]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Add support for the DIR_NLINK feature.
authorAndreas Dilger <adilger@sun.com>
Sat, 2 Feb 2008 08:25:03 +0000 (01:25 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 15 Mar 2008 05:39:19 +0000 (01:39 -0400)
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 <adilger@clusterfs.com>
Signed-off-by: Kalpak Shah <kalpak@clusterfs.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
e2fsck/pass4.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2fs.h

index e6fe604094785dbd9f80f665f4ae7451a8249840..ebc19a8e280f496b822ba6d1ef5c30747daa326c 100644 (file)
@@ -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");
                        }
index 6016b68b010e5343dca0aee8eaeee3108adbdad5..48dd286649361ecc655599b56463bb7ff399b19b 100644 (file)
@@ -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)
 
 /*
index 15f43526adf44dfa1147f5d93d49ecf9810dbab4..d52fa3455a271225f7971b8258cbfe34a95ad0f9 100644 (file)
@@ -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)
 
 /*