]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/stat.c
configure: don't check for the f_flags field in statfs
[thirdparty/xfsprogs-dev.git] / io / stat.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
a8cef9f6
ES
2/*
3 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
12caa872
ES
5 * Copyright (C) 2015, 2017 Red Hat, Inc.
6 * Portions of statx support written by David Howells (dhowells@redhat.com)
a8cef9f6
ES
7 */
8
9#include "command.h"
10#include "input.h"
11#include "init.h"
12#include "io.h"
12caa872 13#include "statx.h"
a8cef9f6 14#include "libxfs.h"
9fc3ef62 15#include "libfrog/logging.h"
fee68490 16#include "libfrog/fsgeom.h"
a8cef9f6 17
12caa872
ES
18#include <fcntl.h>
19
a8cef9f6
ES
20static cmdinfo_t stat_cmd;
21static cmdinfo_t statfs_cmd;
12caa872 22static cmdinfo_t statx_cmd;
a8cef9f6 23
9e726740 24off_t
a8cef9f6
ES
25filesize(void)
26{
27 struct stat st;
28
29 if (fstat(file->fd, &st) < 0) {
30 perror("fstat");
31 return -1;
32 }
33 return st.st_size;
34}
35
36static char *
37filetype(mode_t mode)
38{
39 switch (mode & S_IFMT) {
40 case S_IFSOCK:
41 return _("socket");
42 case S_IFDIR:
43 return _("directory");
44 case S_IFCHR:
45 return _("char device");
46 case S_IFBLK:
47 return _("block device");
48 case S_IFREG:
49 return _("regular file");
50 case S_IFLNK:
51 return _("symbolic link");
52 case S_IFIFO:
53 return _("fifo");
54 }
55 return NULL;
56}
57
2e03a36e
ES
58static int
59dump_raw_stat(struct stat *st)
a8cef9f6 60{
51073f86
DW
61 printf("stat.blksize = %lu\n", (unsigned long)st->st_blksize);
62 printf("stat.nlink = %lu\n", (unsigned long)st->st_nlink);
2e03a36e
ES
63 printf("stat.uid = %u\n", st->st_uid);
64 printf("stat.gid = %u\n", st->st_gid);
65 printf("stat.mode: 0%o\n", st->st_mode);
51073f86
DW
66 printf("stat.ino = %llu\n", (unsigned long long)st->st_ino);
67 printf("stat.size = %lld\n", (long long)st->st_size);
68 printf("stat.blocks = %lld\n", (long long)st->st_blocks);
ebe85b80 69 printf("stat.atime.tv_sec = %jd\n", (intmax_t)st->st_atim.tv_sec);
2e03a36e 70 printf("stat.atime.tv_nsec = %ld\n", st->st_atim.tv_nsec);
ebe85b80 71 printf("stat.ctime.tv_sec = %jd\n", (intmax_t)st->st_ctim.tv_sec);
2e03a36e 72 printf("stat.ctime.tv_nsec = %ld\n", st->st_ctim.tv_nsec);
ebe85b80 73 printf("stat.mtime.tv_sec = %jd\n", (intmax_t)st->st_mtim.tv_sec);
2e03a36e
ES
74 printf("stat.mtime.tv_nsec = %ld\n", st->st_mtim.tv_nsec);
75 printf("stat.rdev_major = %u\n", major(st->st_rdev));
76 printf("stat.rdev_minor = %u\n", minor(st->st_rdev));
77 printf("stat.dev_major = %u\n", major(st->st_dev));
78 printf("stat.dev_minor = %u\n", minor(st->st_dev));
79 return 0;
80}
a8cef9f6 81
00ff2b10
ES
82static void
83print_file_info(void)
2e03a36e 84{
a8cef9f6
ES
85 printf(_("fd.path = \"%s\"\n"), file->name);
86 printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"),
87 file->flags & IO_OSYNC ? _("sync") : _("non-sync"),
88 file->flags & IO_DIRECT ? _("direct") : _("non-direct"),
89 file->flags & IO_READONLY ? _("read-only") : _("read-write"),
90 file->flags & IO_REALTIME ? _(",real-time") : "",
91 file->flags & IO_APPEND ? _(",append-only") : "",
92 file->flags & IO_NONBLOCK ? _(",non-block") : "",
93 file->flags & IO_TMPFILE ? _(",tmpfile") : "");
2e03a36e
ES
94}
95
00ff2b10
ES
96static void
97print_xfs_info(int verbose)
2e03a36e
ES
98{
99 struct dioattr dio;
100 struct fsxattr fsx, fsxa;
101
a8cef9f6
ES
102 if ((xfsctl(file->name, file->fd, FS_IOC_FSGETXATTR, &fsx)) < 0 ||
103 (xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTRA, &fsxa)) < 0) {
104 perror("FS_IOC_FSGETXATTR");
105 } else {
106 printf(_("fsxattr.xflags = 0x%x "), fsx.fsx_xflags);
107 printxattr(fsx.fsx_xflags, verbose, 0, file->name, 1, 1);
108 printf(_("fsxattr.projid = %u\n"), fsx.fsx_projid);
109 printf(_("fsxattr.extsize = %u\n"), fsx.fsx_extsize);
110 printf(_("fsxattr.cowextsize = %u\n"), fsx.fsx_cowextsize);
111 printf(_("fsxattr.nextents = %u\n"), fsx.fsx_nextents);
112 printf(_("fsxattr.naextents = %u\n"), fsxa.fsx_nextents);
113 }
114 if ((xfsctl(file->name, file->fd, XFS_IOC_DIOINFO, &dio)) < 0) {
115 perror("XFS_IOC_DIOINFO");
116 } else {
117 printf(_("dioattr.mem = 0x%x\n"), dio.d_mem);
118 printf(_("dioattr.miniosz = %u\n"), dio.d_miniosz);
119 printf(_("dioattr.maxiosz = %u\n"), dio.d_maxiosz);
120 }
2e03a36e
ES
121}
122
123int
124stat_f(
125 int argc,
126 char **argv)
127{
128 struct stat st;
129 int c, verbose = 0, raw = 0;
130
131 while ((c = getopt(argc, argv, "rv")) != EOF) {
132 switch (c) {
133 case 'r':
134 raw = 1;
135 break;
136 case 'v':
137 verbose = 1;
138 break;
139 default:
9e1595e6 140 exitcode = 1;
2e03a36e
ES
141 return command_usage(&stat_cmd);
142 }
143 }
144
2e03a36e
ES
145 if (fstat(file->fd, &st) < 0) {
146 perror("fstat");
9e1595e6 147 exitcode = 1;
2e03a36e
ES
148 return 0;
149 }
150
151 if (raw)
152 return dump_raw_stat(&st);
153
154 print_file_info();
155
156 printf(_("stat.ino = %lld\n"), (long long)st.st_ino);
157 printf(_("stat.type = %s\n"), filetype(st.st_mode));
158 printf(_("stat.size = %lld\n"), (long long)st.st_size);
159 printf(_("stat.blocks = %lld\n"), (long long)st.st_blocks);
160 if (verbose) {
161 printf(_("stat.atime = %s"), ctime(&st.st_atime));
162 printf(_("stat.mtime = %s"), ctime(&st.st_mtime));
163 printf(_("stat.ctime = %s"), ctime(&st.st_ctime));
164 }
165
166 if (file->flags & IO_FOREIGN)
167 return 0;
168
169 print_xfs_info(verbose);
170
a8cef9f6
ES
171 return 0;
172}
173
4130bb62
DW
174static void
175statfs_help(void)
176{
177 printf(_(
178"\n"
179" Display file system status.\n"
180"\n"
181" Options:\n"
182" -c -- Print fs summary count data.\n"
183" -g -- Print fs geometry data.\n"
184" -s -- Print statfs data.\n"
185"\n"));
186}
187
188#define REPORT_STATFS (1 << 0)
189#define REPORT_GEOMETRY (1 << 1)
190#define REPORT_FSCOUNTS (1 << 2)
191
a8cef9f6
ES
192static int
193statfs_f(
194 int argc,
195 char **argv)
196{
197 struct xfs_fsop_counts fscounts;
198 struct xfs_fsop_geom fsgeo;
199 struct statfs st;
4130bb62
DW
200 unsigned int flags = 0;
201 int c;
9612817d 202 int ret;
a8cef9f6 203
4130bb62
DW
204 while ((c = getopt(argc, argv, "cgs")) != EOF) {
205 switch (c) {
206 case 'c':
207 flags |= REPORT_FSCOUNTS;
208 break;
209 case 'g':
210 flags |= REPORT_GEOMETRY;
211 break;
212 case 's':
213 flags |= REPORT_STATFS;
214 break;
215 default:
216 exitcode = 1;
217 return command_usage(&statfs_cmd);
218 }
219 }
220
221 if (!flags)
222 flags = REPORT_STATFS | REPORT_GEOMETRY | REPORT_FSCOUNTS;
223
a8cef9f6 224 printf(_("fd.path = \"%s\"\n"), file->name);
4130bb62
DW
225 if (flags & REPORT_STATFS) {
226 ret = platform_fstatfs(file->fd, &st);
227 if (ret < 0) {
228 perror("fstatfs");
229 exitcode = 1;
230 } else {
231 printf(_("statfs.f_bsize = %lld\n"),
232 (long long) st.f_bsize);
233 printf(_("statfs.f_blocks = %lld\n"),
234 (long long) st.f_blocks);
235 printf(_("statfs.f_bavail = %lld\n"),
236 (long long) st.f_bavail);
237 printf(_("statfs.f_files = %lld\n"),
238 (long long) st.f_files);
239 printf(_("statfs.f_ffree = %lld\n"),
240 (long long) st.f_ffree);
4130bb62
DW
241 printf(_("statfs.f_flags = 0x%llx\n"),
242 (long long) st.f_flags);
4130bb62 243 }
a8cef9f6 244 }
4130bb62 245
a8cef9f6
ES
246 if (file->flags & IO_FOREIGN)
247 return 0;
4130bb62
DW
248
249 if (flags & REPORT_GEOMETRY) {
250 ret = -xfrog_geometry(file->fd, &fsgeo);
251 if (ret) {
252 xfrog_perror(ret, "XFS_IOC_FSGEOMETRY");
253 exitcode = 1;
254 } else {
255 printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
256 printf(_("geom.agcount = %u\n"), fsgeo.agcount);
257 printf(_("geom.agblocks = %u\n"), fsgeo.agblocks);
258 printf(_("geom.datablocks = %llu\n"),
259 (unsigned long long) fsgeo.datablocks);
260 printf(_("geom.rtblocks = %llu\n"),
261 (unsigned long long) fsgeo.rtblocks);
262 printf(_("geom.rtextents = %llu\n"),
263 (unsigned long long) fsgeo.rtextents);
264 printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize);
265 printf(_("geom.sunit = %u\n"), fsgeo.sunit);
266 printf(_("geom.swidth = %u\n"), fsgeo.swidth);
267 }
a8cef9f6 268 }
4130bb62
DW
269
270 if (flags & REPORT_FSCOUNTS) {
271 ret = ioctl(file->fd, XFS_IOC_FSCOUNTS, &fscounts);
272 if (ret < 0) {
273 perror("XFS_IOC_FSCOUNTS");
274 exitcode = 1;
275 } else {
276 printf(_("counts.freedata = %llu\n"),
277 (unsigned long long) fscounts.freedata);
278 printf(_("counts.freertx = %llu\n"),
279 (unsigned long long) fscounts.freertx);
280 printf(_("counts.freeino = %llu\n"),
281 (unsigned long long) fscounts.freeino);
282 printf(_("counts.allocino = %llu\n"),
283 (unsigned long long) fscounts.allocino);
284 }
a8cef9f6 285 }
4130bb62 286
a8cef9f6
ES
287 return 0;
288}
289
12caa872
ES
290static ssize_t
291_statx(
292 int dfd,
293 const char *filename,
294 unsigned int flags,
295 unsigned int mask,
296 struct statx *buffer)
297{
298#ifdef __NR_statx
299 return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
300#else
301 errno = ENOSYS;
302 return -1;
303#endif
304}
305
306static void
307statx_help(void)
308{
309 printf(_(
310"\n"
311" Display extended file status.\n"
312"\n"
313" Options:\n"
314" -v -- More verbose output\n"
315" -r -- Print raw statx structure fields\n"
316" -m mask -- Specify the field mask for the statx call\n"
317" (can also be 'basic' or 'all'; default STATX_ALL)\n"
318" -D -- Don't sync attributes with the server\n"
319" -F -- Force the attributes to be sync'd with the server\n"
320"\n"));
321}
322
323/* statx helper */
324static int
325dump_raw_statx(struct statx *stx)
326{
327 printf("stat.mask = 0x%x\n", stx->stx_mask);
328 printf("stat.blksize = %u\n", stx->stx_blksize);
51073f86 329 printf("stat.attributes = 0x%llx\n", (unsigned long long)stx->stx_attributes);
12caa872
ES
330 printf("stat.nlink = %u\n", stx->stx_nlink);
331 printf("stat.uid = %u\n", stx->stx_uid);
332 printf("stat.gid = %u\n", stx->stx_gid);
333 printf("stat.mode: 0%o\n", stx->stx_mode);
51073f86
DW
334 printf("stat.ino = %llu\n", (unsigned long long)stx->stx_ino);
335 printf("stat.size = %llu\n", (unsigned long long)stx->stx_size);
336 printf("stat.blocks = %llu\n", (unsigned long long)stx->stx_blocks);
ec5002a8 337 printf("stat.attributes_mask = 0x%llx\n", (unsigned long long)stx->stx_attributes_mask);
51073f86 338 printf("stat.atime.tv_sec = %lld\n", (long long)stx->stx_atime.tv_sec);
12caa872 339 printf("stat.atime.tv_nsec = %d\n", stx->stx_atime.tv_nsec);
51073f86 340 printf("stat.btime.tv_sec = %lld\n", (long long)stx->stx_btime.tv_sec);
12caa872 341 printf("stat.btime.tv_nsec = %d\n", stx->stx_btime.tv_nsec);
51073f86 342 printf("stat.ctime.tv_sec = %lld\n", (long long)stx->stx_ctime.tv_sec);
12caa872 343 printf("stat.ctime.tv_nsec = %d\n", stx->stx_ctime.tv_nsec);
51073f86 344 printf("stat.mtime.tv_sec = %lld\n", (long long)stx->stx_mtime.tv_sec);
12caa872
ES
345 printf("stat.mtime.tv_nsec = %d\n", stx->stx_mtime.tv_nsec);
346 printf("stat.rdev_major = %u\n", stx->stx_rdev_major);
347 printf("stat.rdev_minor = %u\n", stx->stx_rdev_minor);
348 printf("stat.dev_major = %u\n", stx->stx_dev_major);
349 printf("stat.dev_minor = %u\n", stx->stx_dev_minor);
350 return 0;
351}
352
353/*
354 * options:
355 * - input flags - query type
356 * - output style for flags (and all else?) (chars vs. hex?)
357 * - output - mask out incidental flag or not?
358 */
00ff2b10 359static int
12caa872
ES
360statx_f(
361 int argc,
362 char **argv)
363{
364 int c, verbose = 0, raw = 0;
365 char *p;
366 struct statx stx;
367 int atflag = 0;
368 unsigned int mask = STATX_ALL;
369
370 while ((c = getopt(argc, argv, "m:rvFD")) != EOF) {
371 switch (c) {
372 case 'm':
373 if (strcmp(optarg, "basic") == 0)
374 mask = STATX_BASIC_STATS;
375 else if (strcmp(optarg, "all") == 0)
376 mask = STATX_ALL;
377 else {
378 mask = strtoul(optarg, &p, 0);
379 if (!p || p == optarg) {
380 printf(
381 _("non-numeric mask -- %s\n"), optarg);
9e1595e6 382 exitcode = 1;
12caa872
ES
383 return 0;
384 }
385 }
386 break;
387 case 'r':
388 raw = 1;
389 break;
390 case 'v':
391 verbose = 1;
392 break;
393 case 'F':
394 atflag &= ~AT_STATX_SYNC_TYPE;
395 atflag |= AT_STATX_FORCE_SYNC;
396 break;
397 case 'D':
398 atflag &= ~AT_STATX_SYNC_TYPE;
399 atflag |= AT_STATX_DONT_SYNC;
400 break;
401 default:
9e1595e6 402 exitcode = 1;
12caa872
ES
403 return command_usage(&statx_cmd);
404 }
405 }
406
407 if (raw && verbose)
408 return command_usage(&statx_cmd);
409
410 memset(&stx, 0xbf, sizeof(stx));
b61fdaec 411 if (_statx(file->fd, "", atflag | AT_EMPTY_PATH, mask, &stx) < 0) {
12caa872 412 perror("statx");
9e1595e6 413 exitcode = 1;
12caa872
ES
414 return 0;
415 }
9e1595e6 416 exitcode = 0;
12caa872
ES
417
418 if (raw)
419 return dump_raw_statx(&stx);
420
421 print_file_info();
422
423 printf(_("stat.ino = %lld\n"), (long long)stx.stx_ino);
424 printf(_("stat.type = %s\n"), filetype(stx.stx_mode));
425 printf(_("stat.size = %lld\n"), (long long)stx.stx_size);
426 printf(_("stat.blocks = %lld\n"), (long long)stx.stx_blocks);
427 if (verbose) {
428 printf(_("stat.atime = %s"), ctime((time_t *)&stx.stx_atime.tv_sec));
429 printf(_("stat.mtime = %s"), ctime((time_t *)&stx.stx_mtime.tv_sec));
430 printf(_("stat.ctime = %s"), ctime((time_t *)&stx.stx_ctime.tv_sec));
431 if (stx.stx_mask & STATX_BTIME)
432 printf(_("stat.btime = %s"),
433 ctime((time_t *)&stx.stx_btime.tv_sec));
434 }
435
436 if (file->flags & IO_FOREIGN)
437 return 0;
438
439 print_xfs_info(verbose);
440
441 return 0;
442}
443
a8cef9f6
ES
444void
445stat_init(void)
446{
447 stat_cmd.name = "stat";
448 stat_cmd.cfunc = stat_f;
449 stat_cmd.argmin = 0;
450 stat_cmd.argmax = 1;
451 stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
2e03a36e 452 stat_cmd.args = _("[-v|-r]");
a8cef9f6
ES
453 stat_cmd.oneline = _("statistics on the currently open file");
454
12caa872
ES
455 statx_cmd.name = "statx";
456 statx_cmd.cfunc = statx_f;
457 statx_cmd.argmin = 0;
458 statx_cmd.argmax = -1;
459 statx_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
460 statx_cmd.args = _("[-v|-r][-m basic | -m all | -m <mask>][-FD]");
461 statx_cmd.oneline = _("extended statistics on the currently open file");
462 statx_cmd.help = statx_help;
463
a8cef9f6
ES
464 statfs_cmd.name = "statfs";
465 statfs_cmd.cfunc = statfs_f;
4130bb62
DW
466 statfs_cmd.argmin = 0;
467 statfs_cmd.argmax = -1;
468 statfs_cmd.args = _("[-c] [-g] [-s]");
a8cef9f6
ES
469 statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
470 statfs_cmd.oneline =
471 _("statistics on the filesystem of the currently open file");
4130bb62 472 statfs_cmd.help = statfs_help;
a8cef9f6
ES
473
474 add_command(&stat_cmd);
12caa872 475 add_command(&statx_cmd);
a8cef9f6
ES
476 add_command(&statfs_cmd);
477}