]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - quota/quot.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2005 Silicon Graphics, Inc.
14 #include "libfrog/fsgeom.h"
15 #include "libfrog/bulkstat.h"
28 static uint64_t sizes
[TSIZE
];
29 static uint64_t overflow
;
33 static du_t du
[3][NDU
];
34 static du_t
*duhash
[3][DUHASH
];
35 static int ndu
[3]; /* #usr/grp/prj */
40 static cmdinfo_t quot_cmd
;
47 " display a summary of filesystem ownership\n"
49 " -a -- summarise for all local XFS filesystem mount points\n"
50 " -c -- display three columns giving file size in kilobytes, number of files\n"
51 " of that size, and cumulative total of kilobytes in that size or\n"
52 " smaller file. The last row is used as an overflow bucket and is the\n"
53 " total of all files greater than 500 kilobytes.\n"
54 " -v -- display three columns containing the number of kilobytes not\n"
55 " accessed in the last 30, 60, and 90 days.\n"
56 " -g -- display group summary\n"
57 " -p -- display project summary\n"
58 " -u -- display user summary\n"
59 " -b -- display number of blocks used\n"
60 " -i -- display number of inodes used\n"
61 " -r -- display number of realtime blocks used\n"
62 " -n -- skip identifier-to-name translations, just report IDs\n"
63 " -N -- suppress the initial header\n"
64 " -f -- send output to a file\n"
65 " The (optional) user/group/project can be specified either by name or by\n"
66 " number (i.e. uid/gid/projid).\n"
72 struct xfs_bulkstat
*p
,
80 if ((p
->bs_mode
& S_IFMT
) == 0)
82 size
= howmany((p
->bs_blocks
* p
->bs_blksize
), 0x400ULL
);
84 if (flags
& HISTOGRAM_FLAG
) {
85 if (!(S_ISDIR(p
->bs_mode
) || S_ISREG(p
->bs_mode
)))
94 for (i
= 0; i
< 3; i
++) {
95 id
= (i
== 0) ? p
->bs_uid
: ((i
== 1) ?
96 p
->bs_gid
: p
->bs_projectid
);
97 hp
= &duhash
[i
][id
% DUHASH
];
98 for (dp
= *hp
; dp
; dp
= dp
->next
)
104 dp
= &du
[i
][(ndu
[i
]++)];
116 if (now
- p
->bs_atime
> 30 * (60*60*24))
117 dp
->blocks30
+= size
;
118 if (now
- p
->bs_atime
> 60 * (60*60*24))
119 dp
->blocks60
+= size
;
120 if (now
- p
->bs_atime
> 90 * (60*60*24))
121 dp
->blocks90
+= size
;
131 struct xfs_fd fsxfd
= XFS_FD_INIT_EMPTY
;
132 struct xfs_bulkstat_req
*breq
;
137 * Initialize tables between checks; because of the qsort
138 * in report() the hash tables must be rebuilt each time.
140 for (sts
= 0; sts
< TSIZE
; sts
++)
143 for (i
= 0; i
< 3; i
++)
144 for (dp
= duhash
[i
]; dp
< &duhash
[i
][DUHASH
]; dp
++)
146 ndu
[0] = ndu
[1] = ndu
[2] = 0;
148 ret
= xfd_open(&fsxfd
, fsdir
, O_RDONLY
);
155 breq
= xfrog_bulkstat_alloc_req(NBSTAT
, 0);
162 while ((sts
= xfrog_bulkstat(&fsxfd
, breq
)) == 0) {
163 if (breq
->hdr
.ocount
== 0)
165 for (i
= 0; i
< breq
->hdr
.ocount
; i
++)
166 quot_bulkstat_add(&breq
->bulkstat
[i
], flags
);
170 perror("XFS_IOC_FSBULKSTAT");
181 if (p1
->blocks
> p2
->blocks
)
183 if (p1
->blocks
< p2
->blocks
)
187 else if (p1
->id
< p2
->id
)
192 typedef char *(*idtoname_t
)(uint32_t);
195 quot_report_mount_any_type(
207 fprintf(fp
, _("%s (%s) %s:\n"),
208 mount
->fs_name
, mount
->fs_dir
, type_to_string(type
));
209 qsort(dp
, count
, sizeof(dp
[0]),
210 (int (*)(const void *, const void *))qcompare
);
211 for (; dp
< &dp
[count
]; dp
++) {
214 fprintf(fp
, "%8llu ", (unsigned long long) dp
->blocks
);
215 if (form
& XFS_INODE_QUOTA
)
216 fprintf(fp
, "%8llu ",
217 (unsigned long long) dp
->nfiles
);
218 if (!(flags
& NO_LOOKUP_FLAG
) &&
219 ((cp
= (names
)(dp
->id
)) != NULL
))
220 fprintf(fp
, "%-8.8s", cp
);
222 fprintf(fp
, "#%-7d", dp
->id
);
223 if (flags
& VERBOSE_FLAG
)
224 fprintf(fp
, " %8llu %8llu %8llu",
225 (unsigned long long) dp
->blocks30
,
226 (unsigned long long) dp
->blocks60
,
227 (unsigned long long) dp
->blocks90
);
241 case XFS_GROUP_QUOTA
:
242 quot_report_mount_any_type(fp
, du
[1], ndu
[1], gid_to_name
,
243 form
, type
, mount
, flags
);
246 quot_report_mount_any_type(fp
, du
[2], ndu
[2], prid_to_name
,
247 form
, type
, mount
, flags
);
250 quot_report_mount_any_type(fp
, du
[0], ndu
[0], uid_to_name
,
251 form
, type
, mount
, flags
);
267 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
268 while ((mount
= fs_cursor_next_entry(&cursor
))) {
269 quot_bulkstat_mount(mount
->fs_dir
, flags
);
270 quot_report_mount(fp
, form
, type
, mount
, flags
);
275 quot_histogram_mount(
283 fprintf(fp
, _("%s (%s):\n"), mount
->fs_name
, mount
->fs_dir
);
285 for (i
= 0; i
< TSIZE
- 1; i
++)
288 fprintf(fp
, _("%d\t%llu\t%llu\n"), i
,
289 (unsigned long long) sizes
[i
],
290 (unsigned long long) t
);
292 fprintf(fp
, _("%d\t%llu\t%llu\n"), TSIZE
- 1,
293 (unsigned long long) sizes
[TSIZE
- 1],
294 (unsigned long long) (overflow
+ t
));
306 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
307 while ((mount
= fs_cursor_next_entry(&cursor
))) {
308 quot_bulkstat_mount(mount
->fs_dir
, flags
);
309 quot_histogram_mount(fp
, mount
, flags
);
321 if (flags
& HISTOGRAM_FLAG
)
322 quot_histogram(fp
, dir
, flags
);
324 quot_report(fp
, form
, type
, dir
, flags
);
334 int c
, flags
= 0, type
= 0, form
= 0;
336 while ((c
= getopt(argc
, argv
, "abcf:ghinpruv")) != EOF
) {
342 form
|= XFS_BLOCK_QUOTA
;
345 form
|= XFS_INODE_QUOTA
;
348 form
|= XFS_RTBLOCK_QUOTA
;
351 type
|= XFS_GROUP_QUOTA
;
354 type
|= XFS_PROJ_QUOTA
;
357 type
|= XFS_USER_QUOTA
;
360 flags
|= ALL_MOUNTS_FLAG
;
363 flags
|= HISTOGRAM_FLAG
;
366 flags
|= NO_LOOKUP_FLAG
;
369 flags
|= VERBOSE_FLAG
;
372 return command_usage("_cmd
);
377 form
= XFS_BLOCK_QUOTA
;
380 type
= XFS_USER_QUOTA
;
381 } else if (type
!= XFS_GROUP_QUOTA
&&
382 type
!= XFS_PROJ_QUOTA
&&
383 type
!= XFS_USER_QUOTA
) {
384 return command_usage("_cmd
);
387 if ((fp
= fopen_write_secure(fname
)) == NULL
)
390 if (argc
== optind
) {
391 if (flags
& ALL_MOUNTS_FLAG
)
392 quot_any_type(fp
, form
, type
, NULL
, flags
);
393 else if (fs_path
->fs_flags
& FS_MOUNT_POINT
)
394 quot_any_type(fp
, form
, type
, fs_path
->fs_dir
, flags
);
395 } else while (argc
> optind
) {
396 quot_any_type(fp
, form
, type
, argv
[optind
++], flags
);
407 quot_cmd
.name
= "quot";
408 quot_cmd
.cfunc
= quot_f
;
410 quot_cmd
.argmax
= -1;
411 quot_cmd
.args
= _("[-bir] [-g|-p|-u] [-acv] [-f file]");
412 quot_cmd
.oneline
= _("summarize filesystem ownership");
413 quot_cmd
.help
= quot_help
;
416 add_command("_cmd
);