[PATCH] xfs_io: implement 'inode' command V7
Carlos Maiolino
cmaiolino at redhat.com
Mon Feb 22 04:32:29 CST 2016
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 at redhat.com>
---
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
More information about the xfs
mailing list