If there are any directories with > 65000 subdirectories, enable the
DIR_NLINK feature in the superblock.  If there are any directories
that formerly had > 65000 subdirs (i_links_count == 1) but no longer
do, don't consider this an error to alert the user about, but silently
fix the link count to the currently counted link count.

The DIR_NLINK feature is not disabled if set but no many-subdir directories
are found, so that the kernel is not required to enable it on-the-fly.  The
admin should set it with tune2fs instead.

Index: e2fsprogs-1.40.5/e2fsck/pass4.c
===================================================================
--- e2fsprogs-1.40.5.orig/e2fsck/pass4.c
+++ e2fsprogs-1.40.5/e2fsck/pass4.c
@@ -101,6 +101,7 @@ void e2fsck_pass4(e2fsck_t ctx)
        struct problem_context  pctx;
        __u16   link_count;
        __u32   link_counted;
+       __u32   many_subdirs = 0;
        char    *buf = 0;
        int     group, maxgroup;
        
@@ -182,7 +183,20 @@ void e2fsck_pass4(e2fsck_t ctx)
                                e2fsck_write_inode(ctx, i, inode, "pass4");
                        }
                }
+               if (link_count == 1 && link_counted > EXT2_LINK_MAX)
+                       many_subdirs++;
        }
+
+       if (many_subdirs) {
+               if (!(fs->super->s_feature_ro_compat &
+                     EXT4_FEATURE_RO_COMPAT_DIR_NLINK) &&
+                   fix_problem(ctx, PR_4_FEATURE_DIR_NLINK, &pctx)) {
+                       fs->super->s_feature_ro_compat |=
+                               EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
+                       ext2fs_mark_super_dirty(fs);
+               }
+       }
+
        ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
        ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
        ext2fs_free_inode_bitmap(ctx->inode_bb_map);
Index: e2fsprogs-1.40.5/e2fsck/problem.c
===================================================================
--- e2fsprogs-1.40.5.orig/e2fsck/problem.c
+++ e2fsprogs-1.40.5/e2fsck/problem.c
@@ -1371,6 +1371,11 @@ static struct e2fsck_problem problem_tab
          "They @s the same!\n"),
          PROMPT_NONE, 0 },
 
+       /* DIR_NLINK flag not set but dirs with > 65000 subdirs found */
+       { PR_4_FEATURE_DIR_NLINK,
+         N_("@f has @d with > 65000 subdirs, but no DIR_NLINK flag in @S.\n"),
+          PROMPT_FIX, 0 },
+
        /* Pass 5 errors */
                  
        /* Pass 5: Checking group summary information */
Index: e2fsprogs-1.40.5/e2fsck/problem.h
===================================================================
--- e2fsprogs-1.40.5.orig/e2fsck/problem.h
+++ e2fsprogs-1.40.5/e2fsck/problem.h
@@ -824,6 +824,10 @@ struct problem_context {
 /* Inconsistent inode count information cached */
 #define PR_4_INCONSISTENT_COUNT        0x040004
 
+/* Directory with > EXT2_LINK_MAX subdirs found but
+ * EXT4_FEATURE_RO_COMPAT_DIR_NLINK flag is not set */
+#define PR_4_FEATURE_DIR_NLINK 0x040005
+
 /*
  * Pass 5 errors
  */
Index: e2fsprogs-1.40.5/misc/tune2fs.8.in
===================================================================
--- e2fsprogs-1.40.5.orig/misc/tune2fs.8.in
+++ e2fsprogs-1.40.5/misc/tune2fs.8.in
@@ -400,6 +400,10 @@ The following filesystem features can be
 .B dir_index
 Use hashed b-trees to speed up lookups in large directories.
 .TP
+.B dir_nlink
+Allow directories to have more than 65000 subdirectories (read-only
+compatible).
+.TP
 .B filetype
 Store file type information in directory entries.
 .TP
Index: e2fsprogs-1.40.5/misc/tune2fs.c
===================================================================
--- e2fsprogs-1.40.5.orig/misc/tune2fs.c
+++ e2fsprogs-1.40.5/misc/tune2fs.c
@@ -100,7 +100,8 @@ static __u32 ok_features[3] = {
        EXT2_FEATURE_INCOMPAT_FILETYPE|         /* Incompat */
                EXT4_FEATURE_INCOMPAT_FLEX_BG,
        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |   /* R/O compat */
-               EXT4_FEATURE_RO_COMPAT_GDT_CSUM
+               EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
+               EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
 };
 
 /*
@@ -286,6 +287,7 @@ static void update_feature_set(ext2_fils
        int sparse, old_sparse, filetype, old_filetype;
        int journal, old_journal, dxdir, old_dxdir;
        int flex_bg, old_flex_bg;
+       int dir_nlink, old_dir_nlink;
        struct ext2_super_block *sb= fs->super;
        __u32   old_compat, old_incompat, old_ro_compat;
 
@@ -295,6 +297,8 @@ static void update_feature_set(ext2_fils
 
        old_sparse = sb->s_feature_ro_compat &
                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
+       old_dir_nlink = sb->s_feature_ro_compat &
+               EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
        old_filetype = sb->s_feature_incompat &
                EXT2_FEATURE_INCOMPAT_FILETYPE;
        old_flex_bg = sb->s_feature_incompat &
@@ -311,6 +315,8 @@ static void update_feature_set(ext2_fils
        }
        sparse = sb->s_feature_ro_compat &
                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
+       dir_nlink = sb->s_feature_ro_compat &
+               EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
        filetype = sb->s_feature_incompat &
                EXT2_FEATURE_INCOMPAT_FILETYPE;
        flex_bg = sb->s_feature_incompat &
@@ -359,6 +365,14 @@ static void update_feature_set(ext2_fils
                if (uuid_is_null((unsigned char *) sb->s_hash_seed))
                        uuid_generate((unsigned char *) sb->s_hash_seed);
        }
+
+       if (old_dir_nlink && !dir_nlink) {
+               fputs(_("The dir_nlink flag was cleared.  "
+                       "Please run e2fsck before using the filesystem\n"
+                       "to verify no many-linked directories exist or "
+                       "data loss may result.\n"), stderr);
+       }
+
        if (!flex_bg && old_flex_bg) {
                if (ext2fs_check_desc(fs)) {
                        fputs(_("Clearing the flex_bg flag would "

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.

-
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to