diff options
author | Carlos Maiolino <cmaiolino@redhat.com> | 2016-02-29 16:03:40 +1100 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-02-29 16:03:40 +1100 |
commit | ef25c9e4056a93fa408cabcd1ca44aba34737037 (patch) | |
tree | fd8f1726bb8e241c91c36864dbcc622ed4a84149 | |
parent | 2ab8ecbe62cf4d558a0e37f1c8cc283ab5f7b199 (diff) | |
download | xfsprogs-dev-progs-misc-fixes-for-4.6.tar.gz |
xfs_io: implement 'inode' commandprogs-misc-fixes-for-4.6
Implements a new xfs_io command, named 'inode', which is supposed to be
used to query information about inode's existence and its physical size
in the filesystem.
Supported options:
Default: -- Return true(1) or false(0) if any inode greater than
32bits has been found in the filesystem
[num] -- Return inode number or 0 if the inode [num] is in use
-n [num] -- Return the next valid inode after [num]
-v -- verbose mode
Display the inode number and its physical size according to the
argument used
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Bill O'Donnell <billodo@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | io/open.c | 150 |
1 files changed, 150 insertions, 0 deletions
@@ -20,6 +20,7 @@ #include "input.h" #include "init.h" #include "io.h" +#include "libxfs.h" #ifndef __O_TMPFILE #if defined __alpha__ @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; static cmdinfo_t chproj_cmd; static cmdinfo_t lsproj_cmd; static cmdinfo_t extsize_cmd; +static cmdinfo_t inode_cmd; static prid_t prid; static long extsize; @@ -750,6 +752,143 @@ statfs_f( return 0; } +static void +inode_help(void) +{ + printf(_( +"\n" +"Query physical information about the inode" +"\n" +" Default: -- Return true(1) or false(0) if any inode greater than\n" +" 32bits has been found in the filesystem\n" +"[num] -- Return inode number [num] or 0 if the inode [num] is in use\n" +" or not\n" +" -n [num] -- Return the next valid inode after [num]\n" +" -v -- verbose mode\n" +" Display the inode number and its physical size (in bits)\n" +" according to the argument used\n" +"\n")); +} + +static int +inode_f( + int argc, + char **argv) +{ + __s32 count = 0; + __s32 lastgrp = 0; + __u64 last = 0; + __u64 lastino = 0; + __u64 userino = 0; + char *p; + int c; + int verbose = 0; + int ret_next = 0; + int cmd = 0; + struct xfs_inogrp igroup[1024]; + struct xfs_fsop_bulkreq bulkreq; + struct xfs_bstat bstat; + + while ((c = getopt(argc, argv, "nv")) != EOF) { + switch (c) { + case 'v': + verbose = 1; + break; + case 'n': + ret_next = 1; + break; + default: + return command_usage(&inode_cmd); + } + } + + /* + * Inode number can be passed with or without extra arguments, so we + * should handle inode numbers passed by user out of getopt() + */ + if (optind < argc) { + + if (ret_next) { + cmd = XFS_IOC_FSBULKSTAT; + } else { + if ((argc > 2) && !verbose) + return command_usage(&inode_cmd); + else + cmd = XFS_IOC_FSBULKSTAT_SINGLE; + } + + userino = strtoull(argv[optind], &p, 10); + if ((*p != '\0')) { + printf(_("[num] must be a numeric value\n")); + exitcode = 1; + return 0; + } + + bulkreq.lastip = &userino; + bulkreq.icount = 1; + bulkreq.ubuffer = &bstat; + bulkreq.ocount = &count; + + if (xfsctl(file->name, file->fd, cmd, &bulkreq)) { + if (errno == EINVAL) { + if (!ret_next) + printf("0\n"); + } else { + perror("xfsctl"); + } + exitcode = 1; + return 0; + } + + if (ret_next) + userino = bstat.bs_ino; + + if (verbose) + printf("%llu:%d\n", + userino, + userino > XFS_MAXINUMBER_32 ? 64 : 32); + else + /* Inode in use */ + printf("%llu\n", userino); + return 0; + + /* -n option must not be used stand alone */ + } else if (ret_next) { + return command_usage(&inode_cmd); + } + + bulkreq.lastip = &last; + bulkreq.icount = 1024; /* User-defined maybe!? */ + bulkreq.ubuffer = &igroup; + bulkreq.ocount = &count; + + for (;;) { + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, + &bulkreq)) { + perror("XFS_IOC_FSINUMBERS"); + exitcode = 1; + return 0; + } + + if (count == 0) + break; + + lastgrp = count; + } + + lastgrp--; + lastino = igroup[lastgrp].xi_startino + + xfs_highbit64(igroup[lastgrp].xi_allocmask); + + if (verbose) + printf("%llu:%d\n", lastino, + lastino > XFS_MAXINUMBER_32 ? 64 : 32); + else + printf("%d\n", lastino > XFS_MAXINUMBER_32 ? 1 : 0); + + return 0; +} + void open_init(void) { @@ -815,6 +954,16 @@ open_init(void) _("get/set preferred extent size (in bytes) for the open file"); extsize_cmd.help = extsize_help; + inode_cmd.name = "inode"; + inode_cmd.cfunc = inode_f; + inode_cmd.args = _("[-n | -v] [num]"); + inode_cmd.argmin = 0; + inode_cmd.argmax = 2; + inode_cmd.flags = CMD_NOMAP_OK; + inode_cmd.oneline = + _("Query inode number usage in the filesystem"); + inode_cmd.help = inode_help; + add_command(&open_cmd); add_command(&stat_cmd); add_command(&close_cmd); @@ -822,4 +971,5 @@ open_init(void) add_command(&chproj_cmd); add_command(&lsproj_cmd); add_command(&extsize_cmd); + add_command(&inode_cmd); } |