]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - quota/free.c
df42954bc056bef1b3e3c8cbf16c7dd93cb41934
2 * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33 #include <xfs/command.h>
37 static cmdinfo_t free_cmd
;
44 " reports the number of free disk blocks and inodes\n"
46 " This command reports the number of total, used, and available disk blocks.\n"
47 " It can optionally report the same set of numbers for inodes and realtime\n"
48 " disk blocks, and will report on all known XFS filesystem mount points and\n"
49 " project quota paths by default (see 'print' command for a list).\n"
50 " -b -- report the block count values\n"
51 " -i -- report the inode count values\n"
52 " -r -- report the realtime block count values\n"
53 " -h -- report in a human-readable format\n"
54 " -n -- suppress the header from the output\n"
59 mount_free_space_data(
60 struct fs_path
*mount
,
71 struct xfs_fsop_counts fscounts
;
72 struct xfs_fsop_geom fsgeo
;
74 __uint64_t logsize
, count
, free
;
77 if ((fd
= open(mount
->fs_dir
, O_RDONLY
)) < 0) {
78 fprintf(stderr
, "%s: cannot open %s: %s\n",
79 progname
, mount
->fs_dir
, strerror(errno
));
83 if (platform_fstatfs(fd
, &st
) < 0) {
88 if ((xfsctl(mount
->fs_dir
, fd
, XFS_IOC_FSGEOMETRY_V1
, &fsgeo
)) < 0) {
89 perror("XFS_IOC_FSGEOMETRY_V1");
93 if ((xfsctl(mount
->fs_dir
, fd
, XFS_IOC_FSCOUNTS
, &fscounts
)) < 0) {
94 perror("XFS_IOC_FSCOUNTS");
99 logsize
= fsgeo
.logstart
? fsgeo
.logblocks
: 0;
100 count
= (fsgeo
.datablocks
- logsize
) * fsgeo
.blocksize
;
101 free
= fscounts
.freedata
* fsgeo
.blocksize
;
102 *bcount
= BTOBB(count
);
103 *bfree
= BTOBB(free
);
104 *bused
= BTOBB(count
- free
);
106 *icount
= st
.f_files
;
108 *iused
= st
.f_files
- st
.f_ffree
;
110 count
= fsgeo
.rtextents
* fsgeo
.rtextsize
;
111 free
= fscounts
.freertx
* fsgeo
.rtextsize
;
112 *rcount
= BTOBB(count
);
113 *rfree
= BTOBB(free
);
114 *rused
= BTOBB(count
- free
);
121 projects_free_space_data(
122 struct fs_path
*path
,
136 uint type
= XFS_PROJ_QUOTA
;
137 char *dev
= path
->fs_name
;
140 if ((fd
= open(path
->fs_dir
, O_RDONLY
)) < 0) {
141 fprintf(stderr
, "%s: cannot open %s: %s\n",
142 progname
, path
->fs_dir
, strerror(errno
));
146 if ((xfsctl(path
->fs_dir
, fd
, XFS_IOC_FSGETXATTR
, &fsx
)) < 0) {
147 perror("XFS_IOC_FSGETXATTR");
151 if (!(fsx
.fsx_xflags
& XFS_XFLAG_PROJINHERIT
)) {
152 fprintf(stderr
, _("%s: project quota flag not set on %s\n"),
153 progname
, path
->fs_dir
);
158 if ((xfsctl(path
->fs_dir
, fd
, XFS_IOC_GETPROJID
, &projid
)) < 0) {
159 perror("XFS_IOC_GETPROJID");
163 if (path
->fs_prid
!= projid
) {
165 _("%s: project ID %u (%s) doesn't match ID %u (%s)\n"),
166 progname
, path
->fs_prid
, projects_file
,
167 projid
, path
->fs_dir
);
172 if (xfsquotactl(XFS_GETQUOTA
, dev
, type
, projid
, (void *)&d
) < 0) {
173 perror("XFS_GETQUOTA");
178 /* If no softlimit is set for any of blk/ino/rt, get actual usage */
179 if (!d
.d_blk_softlimit
|| !d
.d_ino_softlimit
|| !d
.d_rtb_softlimit
) {
180 mount_free_space_data(path
, bcount
, bused
, bfree
,
181 icount
, iused
, ifree
, rcount
, rused
, rfree
);
184 if (d
.d_blk_softlimit
) {
185 *bcount
= d
.d_blk_softlimit
<< 1;
186 *bfree
= (d
.d_blk_softlimit
- d
.d_bcount
) << 1;
188 *bused
= d
.d_bcount
<< 1;
189 if (d
.d_ino_softlimit
) {
190 *icount
= d
.d_ino_softlimit
;
191 *ifree
= (d
.d_ino_softlimit
- d
.d_icount
);
194 if (d
.d_rtb_softlimit
) {
195 *rcount
= d
.d_rtb_softlimit
<< 1;
196 *rfree
= (d
.d_rtb_softlimit
- d
.d_rtbcount
) << 1;
198 *rcount
= d
.d_rtbcount
<< 1;
211 __uint64_t bcount
, bused
, bfree
;
212 __uint64_t icount
, iused
, ifree
;
213 __uint64_t rcount
, rused
, rfree
;
214 char a
[8], s
[8], u
[8], p
[8];
217 count
= (path
->fs_flags
& FS_PROJECT_PATH
) ?
218 projects_free_space_data(path
, &bcount
, &bused
, &bfree
,
219 &icount
, &iused
, &ifree
,
220 &rcount
, &rused
, &rfree
) :
221 mount_free_space_data(path
, &bcount
, &bused
, &bfree
,
222 &icount
, &iused
, &ifree
,
223 &rcount
, &rused
, &rfree
);
227 if (!(flags
& NO_HEADER_FLAG
)) {
228 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
229 _("Filesystem ") : _("Filesystem "));
230 if (form
& (XFS_BLOCK_QUOTA
|XFS_RTBLOCK_QUOTA
))
231 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
232 _(" Size Used Avail Use%%") :
233 _(" 1K-blocks Used Available Use%%"));
234 else if (form
& XFS_INODE_QUOTA
)
235 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
236 _(" Inodes Used Free Use%%") :
237 _(" Inodes IUsed IFree IUse%%"));
238 fprintf(fp
, _(" Pathname\n"));
241 if (flags
& HUMAN_FLAG
) {
242 count
= fprintf(fp
, "%-12s", path
->fs_name
);
244 fprintf(fp
, "\n%12s", " ");
246 count
= fprintf(fp
, "%-19s", path
->fs_name
);
248 fprintf(fp
, "\n%19s", " ");
251 if (form
& XFS_BLOCK_QUOTA
) {
252 if (flags
& HUMAN_FLAG
)
253 fprintf(fp
, " %6s %6s %6s %3s%%",
254 bbs_to_string(bcount
, s
, sizeof(s
)),
255 bbs_to_string(bused
, u
, sizeof(u
)),
256 bbs_to_string(bfree
, a
, sizeof(a
)),
257 pct_to_string(bused
, bcount
, p
, sizeof(p
)));
259 fprintf(fp
, " %10llu %10llu %10llu %3s%%",
260 (unsigned long long)bcount
>> 1,
261 (unsigned long long)bused
>> 1,
262 (unsigned long long)bfree
>> 1,
263 pct_to_string(bused
, bcount
, p
, sizeof(p
)));
264 } else if (form
& XFS_INODE_QUOTA
) {
265 if (flags
& HUMAN_FLAG
)
266 fprintf(fp
, " %6s %6s %6s %3s%%",
267 num_to_string(icount
, s
, sizeof(s
)),
268 num_to_string(iused
, u
, sizeof(u
)),
269 num_to_string(ifree
, a
, sizeof(a
)),
270 pct_to_string(iused
, icount
, p
, sizeof(p
)));
272 fprintf(fp
, " %10llu %10llu %10llu %3s%%",
273 (unsigned long long)icount
,
274 (unsigned long long)iused
,
275 (unsigned long long)ifree
,
276 pct_to_string(iused
, icount
, p
, sizeof(p
)));
277 } else if (form
& XFS_RTBLOCK_QUOTA
) {
278 if (flags
& HUMAN_FLAG
)
279 fprintf(fp
, " %6s %6s %6s %3s%%",
280 bbs_to_string(rcount
, s
, sizeof(s
)),
281 bbs_to_string(rused
, u
, sizeof(u
)),
282 bbs_to_string(rfree
, a
, sizeof(a
)),
283 pct_to_string(rused
, rcount
, p
, sizeof(p
)));
285 fprintf(fp
, " %10llu %10llu %10llu %3s%%",
286 (unsigned long long)rcount
>> 1,
287 (unsigned long long)rused
>> 1,
288 (unsigned long long)rfree
>> 1,
289 pct_to_string(rused
, rcount
, p
, sizeof(p
)));
291 fprintf(fp
, " %s\n", path
->fs_dir
);
306 fs_cursor_initialise(dir
, type
, &cursor
);
307 while ((path
= fs_cursor_next_entry(&cursor
))) {
308 if (free_space(fp
, form
, path
, flags
))
309 flags
|= NO_HEADER_FLAG
;
320 int c
, flags
= 0, form
= 0, type
= 0;
322 while ((c
= getopt(argc
, argv
, "bf:hnir")) != EOF
) {
328 form
|= XFS_BLOCK_QUOTA
;
331 form
|= XFS_INODE_QUOTA
;
334 form
|= XFS_RTBLOCK_QUOTA
;
340 flags
|= NO_HEADER_FLAG
;
343 return command_usage(&free_cmd
);
348 form
= XFS_BLOCK_QUOTA
;
351 type
= FS_MOUNT_POINT
|FS_PROJECT_PATH
;
353 if ((fp
= fopen_write_secure(fname
)) == NULL
)
357 free_space_list(fp
, form
, type
, NULL
, flags
);
358 else while (argc
> optind
)
359 free_space_list(fp
, form
, type
, argv
[optind
++], flags
);
369 free_cmd
.name
= _("df");
370 free_cmd
.altname
= _("free");
371 free_cmd
.cfunc
= free_f
;
373 free_cmd
.argmax
= -1;
374 free_cmd
.args
= _("[-bir] [-hn] [-f file]");
375 free_cmd
.oneline
= _("show free and used counts for blocks and inodes");
376 free_cmd
.help
= free_help
;
378 add_command(&free_cmd
);