Re: [PATCH][11/28] e2fsprogs-nlinks-flag.patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux