This source file includes following definitions.
- statvfs_works
- statvfs_works
- get_fs_usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #include "fsusage.h"
22
23 #include <limits.h>
24 #include <sys/types.h>
25
26 #if STAT_STATVFS || STAT_STATVFS64
27 # include <sys/statvfs.h>
28 #else
29
30
31 # include <fcntl.h>
32 # include <unistd.h>
33 # include <sys/stat.h>
34 #if HAVE_SYS_PARAM_H
35 # include <sys/param.h>
36 #endif
37 #if HAVE_SYS_MOUNT_H
38 # include <sys/mount.h>
39 #endif
40 #if HAVE_SYS_VFS_H
41 # include <sys/vfs.h>
42 #endif
43 # if HAVE_SYS_FS_S5PARAM_H
44 # include <sys/fs/s5param.h>
45 # endif
46 # if HAVE_SYS_STATFS_H
47 # include <sys/statfs.h>
48 # endif
49 #endif
50
51
52
53
54
55 #define PROPAGATE_ALL_ONES(x) \
56 ((sizeof (x) < sizeof (uintmax_t) \
57 && (~ (x) == (sizeof (x) < sizeof (int) \
58 ? - (1 << (sizeof (x) * CHAR_BIT)) \
59 : 0))) \
60 ? UINTMAX_MAX : (uintmax_t) (x))
61
62
63 #define EXTRACT_TOP_BIT(x) ((x) \
64 & ((uintmax_t) 1 << (sizeof (x) * CHAR_BIT - 1)))
65
66
67
68
69
70
71
72
73 #define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1))
74
75 #ifdef STAT_STATVFS
76
77
78
79
80 # if ! (__linux__ && (__GLIBC__ || __UCLIBC__))
81
82 # undef STAT_STATFS2_FRSIZE
83 static int statvfs_works (void) { return 1; }
84 # else
85 # include <string.h>
86 # include <sys/utsname.h>
87 # include <sys/statfs.h>
88 # define STAT_STATFS2_BSIZE 1
89
90 static int
91 statvfs_works (void)
92 {
93 static int statvfs_works_cache = -1;
94 struct utsname name;
95 if (statvfs_works_cache < 0)
96 statvfs_works_cache = (uname (&name) == 0
97 && 0 <= strverscmp (name.release, "2.6.36"));
98 return statvfs_works_cache;
99 }
100 # endif
101 #endif
102
103
104
105
106
107
108
109
110
111 int
112 get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
113 {
114 #ifdef STAT_STATVFS
115
116 if (statvfs_works ())
117 {
118 struct statvfs vfsd;
119
120 if (statvfs (file, &vfsd) < 0)
121 return -1;
122
123
124 fsp->fsu_blocksize = (vfsd.f_frsize
125 ? PROPAGATE_ALL_ONES (vfsd.f_frsize)
126 : PROPAGATE_ALL_ONES (vfsd.f_bsize));
127
128 fsp->fsu_blocks = PROPAGATE_ALL_ONES (vfsd.f_blocks);
129 fsp->fsu_bfree = PROPAGATE_ALL_ONES (vfsd.f_bfree);
130 fsp->fsu_bavail = PROPAGATE_TOP_BIT (vfsd.f_bavail);
131 fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (vfsd.f_bavail) != 0;
132 fsp->fsu_files = PROPAGATE_ALL_ONES (vfsd.f_files);
133 fsp->fsu_ffree = PROPAGATE_ALL_ONES (vfsd.f_ffree);
134 return 0;
135 }
136
137 #endif
138
139 #if defined STAT_STATVFS64
140
141 struct statvfs64 fsd;
142
143 if (statvfs64 (file, &fsd) < 0)
144 return -1;
145
146
147 fsp->fsu_blocksize = (fsd.f_frsize
148 ? PROPAGATE_ALL_ONES (fsd.f_frsize)
149 : PROPAGATE_ALL_ONES (fsd.f_bsize));
150
151 #elif defined STAT_STATFS3_OSF1
152
153 struct statfs fsd;
154
155 if (statfs (file, &fsd, sizeof (struct statfs)) != 0)
156 return -1;
157
158 fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
159
160 #elif defined STAT_STATFS2_FRSIZE
161
162 struct statfs fsd;
163
164 if (statfs (file, &fsd) < 0)
165 return -1;
166
167 fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_frsize);
168
169 #elif defined STAT_STATFS2_BSIZE
170
171
172
173 struct statfs fsd;
174
175 if (statfs (file, &fsd) < 0)
176 return -1;
177
178 fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);
179
180 # ifdef STATFS_TRUNCATES_BLOCK_COUNTS
181
182
183
184
185
186
187 if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0)
188 {
189 fsd.f_blocks = fsd.f_spare[0];
190 fsd.f_bfree = fsd.f_spare[1];
191 fsd.f_bavail = fsd.f_spare[2];
192 }
193 # endif
194
195 #elif defined STAT_STATFS2_FSIZE
196
197 struct statfs fsd;
198
199 if (statfs (file, &fsd) < 0)
200 return -1;
201
202 fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
203
204 #elif defined STAT_STATFS4
205
206 struct statfs fsd;
207
208 if (statfs (file, &fsd, sizeof fsd, 0) < 0)
209 return -1;
210
211
212
213
214 fsp->fsu_blocksize = 512;
215
216 #endif
217
218 #if (defined STAT_STATVFS64 || defined STAT_STATFS3_OSF1 \
219 || defined STAT_STATFS2_FRSIZE || defined STAT_STATFS2_BSIZE \
220 || defined STAT_STATFS2_FSIZE || defined STAT_STATFS4)
221
222 fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
223 fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);
224 fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail);
225 fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0;
226 fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files);
227 fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree);
228
229 #endif
230
231 (void) disk;
232 return 0;
233 }