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