On Mon, Feb 22, 2016 at 11:32:29AM +0100, Carlos Maiolino wrote: > 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 > > No manpage sent because there were changes in the supported options and its > descriptions. > I'll send the manpage after the options and descriptions are reviewed. > > - Changelog > > V3: > - Merge all 3 patches from the V2 together in a single patch > - Rework of '-n [num]' and 'num' only arguments algorithm > - Argument -n now relies on bulkreq.count to check for next inodes, not > on bstat.bs_ino anymore. > - for loop in ret_lsize or ret_largest case, now relies on count being 0 > to break the loop > > V4: > - Refactor inode_f function to reduce its size and easier logic > - Implement error handlers for invalid command combination (hopefully > all invalid combinations). > - use a single xfs_inogrp array for keep track of inodes > - Fix missing newline in inode_help() > - Rewrite help message in inode_help() > - Fix indentation > > V5: > - Reduce the amount of options > - remove igrp_rec variable, and use igroup[lastgrp] directly to get > information from the last inode groups returned by ioctl > > V6: > - Re-use userino variable to reduce code duplication for command output > - Use verbose option as an extension to another commands > - report usage message when -n option is passed stand-alone > - Refactor command outputs > - Add a few comments to the code > > V7: > - Fix verbose mode usage with an inode number > > Signed-off-by: Carlos Maiolino <cmaiolino@xxxxxxxxxx> > --- looks good to me. Thanks! Reviewed-by: Bill O'Donnell <billodo@xxxxxxxxxx> > io/open.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 150 insertions(+) > > diff --git a/io/open.c b/io/open.c > index 037843d..2303527 100644 > --- a/io/open.c > +++ b/io/open.c > @@ -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); > } > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@xxxxxxxxxxx > http://oss.sgi.com/mailman/listinfo/xfs _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs