From a7c9cb7d0dc464eda26958595b728a6c3a4cacbc Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 2 Feb 2008 01:25:03 -0700 Subject: [PATCH] Add support for the DIR_NLINK feature. This patch includes the changes required to e2fsck to understand the nlink count changes made in the kernel. In e2fsck pass 4, when we fetch the actual link count, if it is exceeds 65,000 we set the link count to 1. We silently fix the situation where the nlink count of the directory is 1, and there are fewer than 65,000 subdirectories, since since that can happen naturally. Patch originally from CFS, significantly rewritten by Theodore Ts'o. Signed-off-by: Andreas Dilger Signed-off-by: Kalpak Shah Signed-off-by: "Theodore Ts'o" --- e2fsck/pass4.c | 10 +++++++++- lib/ext2fs/ext2_fs.h | 1 + lib/ext2fs/ext2fs.h | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index e6fe604..ebc19a8 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -155,6 +155,9 @@ void e2fsck_pass4(e2fsck_t ctx) ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); } + if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i) && + (link_counted > EXT2_LINK_MAX)) + link_counted = 1; if (link_counted != link_count) { e2fsck_read_inode(ctx, i, inode, "pass4"); pctx.ino = i; @@ -165,7 +168,12 @@ void e2fsck_pass4(e2fsck_t ctx) PR_4_INCONSISTENT_COUNT, &pctx); } pctx.num = link_counted; - if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) { + /* i_link_count was previously exceeded, but no longer + * is, fix this but don't consider it an error */ + if ((LINUX_S_ISDIR(inode->i_mode) && link_counted > 1 && + (inode->i_flags & EXT2_INDEX_FL) && + link_count == 1 && !(ctx->options & E2F_OPT_NO)) || + (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx))) { inode->i_links_count = link_counted; e2fsck_write_inode(ctx, i, inode, "pass4"); } diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 6016b68..48dd286 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -632,6 +632,7 @@ struct ext2_super_block { #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE) #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) /* diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 15f4352..d52fa34 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -516,7 +516,8 @@ typedef struct ext2_icount *ext2_icount_t; EXT4_FEATURE_INCOMPAT_FLEX_BG) #endif #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE) + EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\ + EXT4_FEATURE_RO_COMPAT_DIR_NLINK) /* * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed @@ -525,7 +526,6 @@ typedef struct ext2_icount *ext2_icount_t; #define EXT2_LIB_SOFTSUPP_INCOMPAT (EXT3_FEATURE_INCOMPAT_EXTENTS) #define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\ EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\ - EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) /* -- 1.8.3.1