]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/stat.c
Remove use of LFS64 interfaces
[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);
2e03a36e
ES
69 printf("stat.atime.tv_sec = %ld\n", st->st_atim.tv_sec);
70 printf("stat.atime.tv_nsec = %ld\n", st->st_atim.tv_nsec);
71 printf("stat.ctime.tv_sec = %ld\n", st->st_ctim.tv_sec);
72 printf("stat.ctime.tv_nsec = %ld\n", st->st_ctim.tv_nsec);
73 printf("stat.mtime.tv_sec = %ld\n", st->st_mtim.tv_sec);
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);
ce9adab0 241#ifdef HAVE_STATFS_FLAGS
4130bb62
DW
242 printf(_("statfs.f_flags = 0x%llx\n"),
243 (long long) st.f_flags);
ce9adab0 244#endif
4130bb62 245 }
a8cef9f6 246 }
4130bb62 247
a8cef9f6
ES
248 if (file->flags & IO_FOREIGN)
249 return 0;
4130bb62
DW
250
251 if (flags & REPORT_GEOMETRY) {
252 ret = -xfrog_geometry(file->fd, &fsgeo);
253 if (ret) {
254 xfrog_perror(ret, "XFS_IOC_FSGEOMETRY");
255 exitcode = 1;
256 } else {
257 printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
258 printf(_("geom.agcount = %u\n"), fsgeo.agcount);
259 printf(_("geom.agblocks = %u\n"), fsgeo.agblocks);
260 printf(_("geom.datablocks = %llu\n"),
261 (unsigned long long) fsgeo.datablocks);
262 printf(_("geom.rtblocks = %llu\n"),
263 (unsigned long long) fsgeo.rtblocks);
264 printf(_("geom.rtextents = %llu\n"),
265 (unsigned long long) fsgeo.rtextents);
266 printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize);
267 printf(_("geom.sunit = %u\n"), fsgeo.sunit);
268 printf(_("geom.swidth = %u\n"), fsgeo.swidth);
269 }
a8cef9f6 270 }
4130bb62
DW
271
272 if (flags & REPORT_FSCOUNTS) {
273 ret = ioctl(file->fd, XFS_IOC_FSCOUNTS, &fscounts);
274 if (ret < 0) {
275 perror("XFS_IOC_FSCOUNTS");
276 exitcode = 1;
277 } else {
278 printf(_("counts.freedata = %llu\n"),
279 (unsigned long long) fscounts.freedata);
280 printf(_("counts.freertx = %llu\n"),
281 (unsigned long long) fscounts.freertx);
282 printf(_("counts.freeino = %llu\n"),
283 (unsigned long long) fscounts.freeino);
284 printf(_("counts.allocino = %llu\n"),
285 (unsigned long long) fscounts.allocino);
286 }
a8cef9f6 287 }
4130bb62 288
a8cef9f6
ES
289 return 0;
290}
291
12caa872
ES
292static ssize_t
293_statx(
294 int dfd,
295 const char *filename,
296 unsigned int flags,
297 unsigned int mask,
298 struct statx *buffer)
299{
300#ifdef __NR_statx
301 return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
302#else
303 errno = ENOSYS;
304 return -1;
305#endif
306}
307
308static void
309statx_help(void)
310{
311 printf(_(
312"\n"
313" Display extended file status.\n"
314"\n"
315" Options:\n"
316" -v -- More verbose output\n"
317" -r -- Print raw statx structure fields\n"
318" -m mask -- Specify the field mask for the statx call\n"
319" (can also be 'basic' or 'all'; default STATX_ALL)\n"
320" -D -- Don't sync attributes with the server\n"
321" -F -- Force the attributes to be sync'd with the server\n"
322"\n"));
323}
324
325/* statx helper */
326static int
327dump_raw_statx(struct statx *stx)
328{
329 printf("stat.mask = 0x%x\n", stx->stx_mask);
330 printf("stat.blksize = %u\n", stx->stx_blksize);
51073f86 331 printf("stat.attributes = 0x%llx\n", (unsigned long long)stx->stx_attributes);
12caa872
ES
332 printf("stat.nlink = %u\n", stx->stx_nlink);
333 printf("stat.uid = %u\n", stx->stx_uid);
334 printf("stat.gid = %u\n", stx->stx_gid);
335 printf("stat.mode: 0%o\n", stx->stx_mode);
51073f86
DW
336 printf("stat.ino = %llu\n", (unsigned long long)stx->stx_ino);
337 printf("stat.size = %llu\n", (unsigned long long)stx->stx_size);
338 printf("stat.blocks = %llu\n", (unsigned long long)stx->stx_blocks);
ec5002a8 339 printf("stat.attributes_mask = 0x%llx\n", (unsigned long long)stx->stx_attributes_mask);
51073f86 340 printf("stat.atime.tv_sec = %lld\n", (long long)stx->stx_atime.tv_sec);
12caa872 341 printf("stat.atime.tv_nsec = %d\n", stx->stx_atime.tv_nsec);
51073f86 342 printf("stat.btime.tv_sec = %lld\n", (long long)stx->stx_btime.tv_sec);
12caa872 343 printf("stat.btime.tv_nsec = %d\n", stx->stx_btime.tv_nsec);
51073f86 344 printf("stat.ctime.tv_sec = %lld\n", (long long)stx->stx_ctime.tv_sec);
12caa872 345 printf("stat.ctime.tv_nsec = %d\n", stx->stx_ctime.tv_nsec);
51073f86 346 printf("stat.mtime.tv_sec = %lld\n", (long long)stx->stx_mtime.tv_sec);
12caa872
ES
347 printf("stat.mtime.tv_nsec = %d\n", stx->stx_mtime.tv_nsec);
348 printf("stat.rdev_major = %u\n", stx->stx_rdev_major);
349 printf("stat.rdev_minor = %u\n", stx->stx_rdev_minor);
350 printf("stat.dev_major = %u\n", stx->stx_dev_major);
351 printf("stat.dev_minor = %u\n", stx->stx_dev_minor);
352 return 0;
353}
354
355/*
356 * options:
357 * - input flags - query type
358 * - output style for flags (and all else?) (chars vs. hex?)
359 * - output - mask out incidental flag or not?
360 */
00ff2b10 361static int
12caa872
ES
362statx_f(
363 int argc,
364 char **argv)
365{
366 int c, verbose = 0, raw = 0;
367 char *p;
368 struct statx stx;
369 int atflag = 0;
370 unsigned int mask = STATX_ALL;
371
372 while ((c = getopt(argc, argv, "m:rvFD")) != EOF) {
373 switch (c) {
374 case 'm':
375 if (strcmp(optarg, "basic") == 0)
376 mask = STATX_BASIC_STATS;
377 else if (strcmp(optarg, "all") == 0)
378 mask = STATX_ALL;
379 else {
380 mask = strtoul(optarg, &p, 0);
381 if (!p || p == optarg) {
382 printf(
383 _("non-numeric mask -- %s\n"), optarg);
9e1595e6 384 exitcode = 1;
12caa872
ES
385 return 0;
386 }
387 }
388 break;
389 case 'r':
390 raw = 1;
391 break;
392 case 'v':
393 verbose = 1;
394 break;
395 case 'F':
396 atflag &= ~AT_STATX_SYNC_TYPE;
397 atflag |= AT_STATX_FORCE_SYNC;
398 break;
399 case 'D':
400 atflag &= ~AT_STATX_SYNC_TYPE;
401 atflag |= AT_STATX_DONT_SYNC;
402 break;
403 default:
9e1595e6 404 exitcode = 1;
12caa872
ES
405 return command_usage(&statx_cmd);
406 }
407 }
408
409 if (raw && verbose)
410 return command_usage(&statx_cmd);
411
412 memset(&stx, 0xbf, sizeof(stx));
b61fdaec 413 if (_statx(file->fd, "", atflag | AT_EMPTY_PATH, mask, &stx) < 0) {
12caa872 414 perror("statx");
9e1595e6 415 exitcode = 1;
12caa872
ES
416 return 0;
417 }
9e1595e6 418 exitcode = 0;
12caa872
ES
419
420 if (raw)
421 return dump_raw_statx(&stx);
422
423 print_file_info();
424
425 printf(_("stat.ino = %lld\n"), (long long)stx.stx_ino);
426 printf(_("stat.type = %s\n"), filetype(stx.stx_mode));
427 printf(_("stat.size = %lld\n"), (long long)stx.stx_size);
428 printf(_("stat.blocks = %lld\n"), (long long)stx.stx_blocks);
429 if (verbose) {
430 printf(_("stat.atime = %s"), ctime((time_t *)&stx.stx_atime.tv_sec));
431 printf(_("stat.mtime = %s"), ctime((time_t *)&stx.stx_mtime.tv_sec));
432 printf(_("stat.ctime = %s"), ctime((time_t *)&stx.stx_ctime.tv_sec));
433 if (stx.stx_mask & STATX_BTIME)
434 printf(_("stat.btime = %s"),
435 ctime((time_t *)&stx.stx_btime.tv_sec));
436 }
437
438 if (file->flags & IO_FOREIGN)
439 return 0;
440
441 print_xfs_info(verbose);
442
443 return 0;
444}
445
a8cef9f6
ES
446void
447stat_init(void)
448{
449 stat_cmd.name = "stat";
450 stat_cmd.cfunc = stat_f;
451 stat_cmd.argmin = 0;
452 stat_cmd.argmax = 1;
453 stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
2e03a36e 454 stat_cmd.args = _("[-v|-r]");
a8cef9f6
ES
455 stat_cmd.oneline = _("statistics on the currently open file");
456
12caa872
ES
457 statx_cmd.name = "statx";
458 statx_cmd.cfunc = statx_f;
459 statx_cmd.argmin = 0;
460 statx_cmd.argmax = -1;
461 statx_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
462 statx_cmd.args = _("[-v|-r][-m basic | -m all | -m <mask>][-FD]");
463 statx_cmd.oneline = _("extended statistics on the currently open file");
464 statx_cmd.help = statx_help;
465
a8cef9f6
ES
466 statfs_cmd.name = "statfs";
467 statfs_cmd.cfunc = statfs_f;
4130bb62
DW
468 statfs_cmd.argmin = 0;
469 statfs_cmd.argmax = -1;
470 statfs_cmd.args = _("[-c] [-g] [-s]");
a8cef9f6
ES
471 statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
472 statfs_cmd.oneline =
473 _("statistics on the filesystem of the currently open file");
4130bb62 474 statfs_cmd.help = statfs_help;
a8cef9f6
ES
475
476 add_command(&stat_cmd);
12caa872 477 add_command(&statx_cmd);
a8cef9f6
ES
478 add_command(&statfs_cmd);
479}