Whamcloud - gitweb
e2fsck: add a developer-only extended option: clear_all_uninit_bits
authorTheodore Ts'o <tytso@mit.edu>
Mon, 5 Aug 2019 16:47:18 +0000 (12:47 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 15 Aug 2019 18:41:13 +0000 (14:41 -0400)
This option clears the uninitialized bit on all extents of all inodes.
Note that this can end up exposing uninitialized data to userspace.
It should only used in very specialized situations.

This option is only enabled via a new configure flag,
--enable-developer-features.  It should *not* be enabled by
distributions, as it enables features thare only designed for use by
ext4 developers.  These features have no documentation in the man
page, or regression tests, and if it breaks, you get to keep both
pieces.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
configure
configure.ac
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/problem.c
e2fsck/problem.h
e2fsck/unix.c
lib/config.h.in

index 065bff7..6f4da1a 100755 (executable)
--- a/configure
+++ b/configure
@@ -785,6 +785,7 @@ LIBUUID
 PKG_CONFIG_LIBDIR
 PKG_CONFIG_PATH
 PKG_CONFIG
+DEV_FEATURES_CMT
 TEST_IO_CMT
 PRIVATE_LIBS_CMT
 LDFLAG_DYNAMIC
@@ -894,6 +895,7 @@ enable_hardening
 enable_jbd_debug
 enable_blkid_debug
 enable_testio_debug
+enable_developer_features
 enable_libuuid
 enable_libblkid
 enable_subset
@@ -1580,6 +1582,7 @@ Optional Features:
   --enable-jbd-debug     enable journal debugging
   --enable-blkid-debug    enable blkid debugging
   --disable-testio-debug  disable the use of the test I/O manager for debugging
+  --enable-developer-features  enable features for use by ext4 developers
   --enable-libuuid       build and use private uuid library
   --enable-libblkid      build and use private blkid library
   --enable-subset        enable subset-only build
@@ -5168,6 +5171,30 @@ TEST_IO_CMT=
 fi
 
 
+# Check whether --enable-developer-features was given.
+if test "${enable_developer_features+set}" = set; then :
+  enableval=$enable_developer_features;
+if test "$enableval" = "yes"
+then
+       DEV_FEATURES_CMT=
+       $as_echo "#define CONFIG_DEVELOPER_FEATURES 1" >>confdefs.h
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Enabling ext4 developer features" >&5
+$as_echo "Enabling ext4 developer features" >&6; }
+else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Disabling ext4 developer features" >&5
+$as_echo "Disabling ext4 developer features" >&6; }
+       DEV_FEATURES_CMT="#"
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Disabling ext4 developer features by default" >&5
+$as_echo "Disabling ext4 developer features by default" >&6; }
+DEV_FEATURES_CMT=
+
+fi
+
+
 
 
 
index cf03444..18e434b 100644 (file)
@@ -439,6 +439,27 @@ TEST_IO_CMT=
 )
 AC_SUBST(TEST_IO_CMT)
 dnl
+dnl handle --enable-developer-features
+dnl
+AC_ARG_ENABLE([developer-features],
+[  --enable-developer-features  enable features for use by ext4 developers],
+AH_TEMPLATE([CONFIG_DEVELOPER_FEATURES],
+       [Define to 1 for features for use by ext4 developers])
+if test "$enableval" = "yes"
+then
+       DEV_FEATURES_CMT=
+       AC_DEFINE(CONFIG_DEVELOPER_FEATURES, 1)
+       AC_MSG_RESULT([Enabling ext4 developer features])
+else
+       AC_MSG_RESULT([Disabling ext4 developer features])
+       DEV_FEATURES_CMT="#"
+fi
+,
+AC_MSG_RESULT([Disabling ext4 developer features by default])
+DEV_FEATURES_CMT=
+)
+AC_SUBST(DEV_FEATURES_CMT)
+dnl
 dnl handle --disable-libuuid
 dnl
 PKG_PROG_PKG_CONFIG
index 2d359b3..fc0e5c8 100644 (file)
@@ -174,6 +174,7 @@ struct resource_track {
 #define E2F_OPT_NOOPT_EXTENTS  0x10000 /* don't optimize extents */
 #define E2F_OPT_ICOUNT_FULLMAP 0x20000 /* use an array for inode counts */
 #define E2F_OPT_UNSHARE_BLOCKS  0x40000
+#define E2F_OPT_CLEAR_UNINIT   0x80000 /* Hack to clear the uninit bit */
 
 /*
  * E2fsck flags
index 524577a..41eac08 100644 (file)
@@ -2855,7 +2855,20 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
                                return;
                        failed_csum = 0;
                }
-
+#ifdef CONFIG_DEVELOPER_FEATURES
+               if (try_repairs && !is_dir && problem == 0 &&
+                   (ctx->options & E2F_OPT_CLEAR_UNINIT) &&
+                   (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) &&
+                   fix_problem(ctx, PR_1_CLEAR_UNINIT_EXTENT, pctx)) {
+                       extent.e_flags &= ~EXT2_EXTENT_FLAGS_UNINIT;
+                       pb->inode_modified = 1;
+                       pctx->errcode = ext2fs_extent_replace(ehandle, 0,
+                                                             &extent);
+                       if (pctx->errcode)
+                               return;
+                       failed_csum = 0;
+               }
+#endif
                if (try_repairs && problem) {
 report_problem:
                        if (fix_problem(ctx, problem, pctx)) {
index c45c6b7..4863ea7 100644 (file)
@@ -1240,6 +1240,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("EA @i %N for parent @i %i missing EA_INODE flag.\n "),
          PROMPT_FIX, PR_PREEN_OK, 0, 0, 0 },
 
+       /* Offer to clear uninitialized flag on an extent */
+       { PR_1_CLEAR_UNINIT_EXTENT,
+         /* xgettext:no-c-format */
+         N_("@i %i has @x marked uninitialized at @b %c (len %N).  "),
+         PROMPT_CLEAR, PR_PREEN_OK, 0, 0, 0 },
 
        /* Pass 1b errors */
 
index 2c79169..67a9f95 100644 (file)
@@ -693,6 +693,9 @@ struct problem_context {
 /* EA inode for parent inode does not have EXT4_EA_INODE_FL flag */
 #define PR_1_ATTR_SET_EA_INODE_FL              0x010086
 
+/* Offer to clear uninitialized flag on an extent */
+#define PR_1_CLEAR_UNINIT_EXTENT               0x010087
+
 
 /*
  * Pass 1b errors
index 68f4987..b3ef0f2 100644 (file)
@@ -753,6 +753,11 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
                        ctx->options |= E2F_OPT_UNSHARE_BLOCKS;
                        ctx->options |= E2F_OPT_FORCE;
                        continue;
+#ifdef CONFIG_DEVELOPER_FEATURES
+               } else if (strcmp(token, "clear_all_uninit_bits") == 0) {
+                       ctx->options |= E2F_OPT_CLEAR_UNINIT;
+                       continue;
+#endif
                } else {
                        fprintf(stderr, _("Unknown extended option: %s\n"),
                                token);
index 407911c..b448482 100644 (file)
@@ -9,6 +9,9 @@
 /* Define to 1 to compile findfs */
 #undef CONFIG_BUILD_FINDFS
 
+/* Define to 1 for features for use by ext4 developers */
+#undef CONFIG_DEVELOPER_FEATURES
+
 /* Define to 1 if debugging ext3/4 journal code */
 #undef CONFIG_JBD_DEBUG