From: Theodore Ts'o Date: Mon, 5 Aug 2019 16:47:18 +0000 (-0400) Subject: e2fsck: add a developer-only extended option: clear_all_uninit_bits X-Git-Tag: v1.46.0~120 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9e66a187f8ff1df4a35244b1d1e87a35aae46f3;p=thirdparty%2Fe2fsprogs.git e2fsck: add a developer-only extended option: clear_all_uninit_bits 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 --- diff --git a/configure b/configure index 065bff761..6f4da1a12 100755 --- 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 + + diff --git a/configure.ac b/configure.ac index cf03444d8..18e434bc6 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 2d359b384..fc0e5c8b2 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -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 diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 524577ae9..41eac0888 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -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)) { diff --git a/e2fsck/problem.c b/e2fsck/problem.c index c45c6b785..4863ea7ab 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -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 */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 2c79169ef..67a9f9527 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -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 diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 68f498739..b3ef0f22b 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -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); diff --git a/lib/config.h.in b/lib/config.h.in index 407911ca0..b448482c0 100644 --- a/lib/config.h.in +++ b/lib/config.h.in @@ -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