]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
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 065bff7611c6a0e4854b865c9eeae2c08c740f07..6f4da1a1234bb60dc48030cdd40b59f7f7127ebe 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 cf03444d8f178fd28b08ed4aef69ce4e0cf5bbdb..18e434bc6ebc945775d53e4ed1f08ef4033dacc5 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 2d359b384c1887acc7ff8e909e5ba11f44809ba3..fc0e5c8b243e46ef28978fce8d21a12da27d939d 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 524577ae93232ead6044300e44386cad4da74b41..41eac0888bf27d8d2e9ade75bfafbae618062da0 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 c45c6b7854e82732e2f60adcccb85ab762236141..4863ea7ab5ac3b518e17a1aa66c391ea7d8e874f 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 2c79169ef33bbd3d8976ca257e069088dd4b2f94..67a9f9527644773d2b7f99b8200b1463e31f1bf3 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 68f4987398624d171e93a82de0797dc9457f96fc..b3ef0f22b866f5a895a6d687a9ca12faa6f7b973 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 407911ca0aa918cb8139f2329c1c9d3ab285e6eb..b448482c06f858bd5e48eb4ca723282bb6f63dd8 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