]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_io: wire up repair ioctl stuff
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 1 Aug 2018 22:06:44 +0000 (17:06 -0500)
committerEric Sandeen <sandeen@redhat.com>
Wed, 1 Aug 2018 22:06:44 +0000 (17:06 -0500)
Wire up the repair ioctl (which is really the scrub ioctl with special
flags) and the force-repair error injection point.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
io/init.c
io/io.h
io/scrub.c
man/man8/xfs_io.8

index 4fe26a73fe2e1863b9d618cb58f0b46698c76b0a..82774c7c569bef650a41022e584ac512cf51ba80 100644 (file)
--- a/io/init.c
+++ b/io/init.c
@@ -73,6 +73,7 @@ init_commands(void)
        quit_init();
        readdir_init();
        reflink_init();
+       repair_init();
        resblks_init();
        scrub_init();
        seek_init();
diff --git a/io/io.h b/io/io.h
index 7e4b3eba022484246392b424e78e1dd1acf89445..e1f3d95be0a522d04a5a7ec386eaa0448886666d 100644 (file)
--- a/io/io.h
+++ b/io/io.h
@@ -186,3 +186,4 @@ extern void         log_writes_init(void);
 #endif
 
 extern void            scrub_init(void);
+extern void            repair_init(void);
index 1666b0b7bbf7ac6eba3c54c6702df280cb4fb556..2ff1a6afb80de683831559fb3f326bb76371e5a9 100644 (file)
@@ -13,6 +13,7 @@
 #include "io.h"
 
 static struct cmdinfo scrub_cmd;
+static struct cmdinfo repair_cmd;
 
 /* Type info and names for the scrub types. */
 enum scrub_type {
@@ -236,3 +237,99 @@ scrub_init(void)
 
        add_command(&scrub_cmd);
 }
+
+static void
+repair_help(void)
+{
+       const struct scrub_descr        *d;
+       int                             i;
+
+       printf(_(
+"\n"
+" Repairs a piece of XFS filesystem metadata.  The first argument is the type\n"
+" of metadata to examine.  Allocation group metadata types take one AG number\n"
+" as the second parameter.  Inode metadata types act on the currently open file\n"
+" or (optionally) take an inode number and generation number to act upon as\n"
+" the second and third parameters.\n"
+"\n"
+" Example:\n"
+" 'repair inobt 3' - repairs the inode btree in AG 3.\n"
+" 'repair bmapbtd 128 13525' - repairs the extent map of inode 128 gen 13525.\n"
+"\n"
+" Known metadata repairs types are:"));
+       for (i = 0, d = scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++)
+               printf(" %s", d->name);
+       printf("\n");
+}
+
+static void
+repair_ioctl(
+       int                             fd,
+       int                             type,
+       uint64_t                        control,
+       uint32_t                        control2)
+{
+       struct xfs_scrub_metadata       meta;
+       const struct scrub_descr        *sc;
+       int                             error;
+
+       sc = &scrubbers[type];
+       memset(&meta, 0, sizeof(meta));
+       meta.sm_type = type;
+       switch (sc->type) {
+       case ST_PERAG:
+               meta.sm_agno = control;
+               break;
+       case ST_INODE:
+               meta.sm_ino = control;
+               meta.sm_gen = control2;
+               break;
+       case ST_NONE:
+       case ST_FS:
+               /* no control parameters */
+               break;
+       }
+       meta.sm_flags = XFS_SCRUB_IFLAG_REPAIR;
+
+       error = ioctl(fd, XFS_IOC_SCRUB_METADATA, &meta);
+       if (error)
+               perror("scrub");
+       if (meta.sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
+               printf(_("Corruption remains.\n"));
+       if (meta.sm_flags & XFS_SCRUB_OFLAG_PREEN)
+               printf(_("Optimization possible.\n"));
+       if (meta.sm_flags & XFS_SCRUB_OFLAG_XFAIL)
+               printf(_("Cross-referencing failed.\n"));
+       if (meta.sm_flags & XFS_SCRUB_OFLAG_XCORRUPT)
+               printf(_("Corruption still detected during cross-referencing.\n"));
+       if (meta.sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
+               printf(_("Repair was not complete.\n"));
+       if (meta.sm_flags & XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED)
+               printf(_("Metadata did not need repair or optimization.\n"));
+}
+
+static int
+repair_f(
+       int                             argc,
+       char                            **argv)
+{
+       return parse_args(argc, argv, &repair_cmd, repair_ioctl);
+}
+
+void
+repair_init(void)
+{
+       if (!expert)
+               return;
+       repair_cmd.name = "repair";
+       repair_cmd.altname = "fix";
+       repair_cmd.cfunc = repair_f;
+       repair_cmd.argmin = 1;
+       repair_cmd.argmax = -1;
+       repair_cmd.flags = CMD_NOMAP_OK;
+       repair_cmd.args = _("type [agno|ino gen]");
+       repair_cmd.oneline = _("repairs filesystem metadata");
+       repair_cmd.help = repair_help;
+
+       add_command(&repair_cmd);
+}
index dd91589bd145862a7e9b62236e2c6faa7d5a56e1..60f7a21c093096af20d2687f180d557450b12118 100644 (file)
@@ -1167,6 +1167,14 @@ inode number and generation number are specified.
 .RE
 .PD
 .TP
+.BI "repair " type " [ " agnumber " | " "ino" " " "gen" " ]"
+Repair internal XFS filesystem metadata.  The
+.BI type
+parameter specifies which type of metadata to repair.
+For AG metadata, one AG number must be specified.
+For file metadata, the repair is applied to the open file unless the
+inode number and generation number are specified.
+.TP
 .BI "log_writes \-d " device " \-m "  mark
 Create a mark named
 .I mark