Blame SOURCES/e2fsprogs-1.42.9-14-e2fsck-set-dir_nlink-feature-if-large-dir-exists.patch

0ef434
From 458939e5d9441448f87d3a6d45c84e041ee14786 Mon Sep 17 00:00:00 2001
0ef434
From: Andreas Dilger <adilger@dilger.ca>
0ef434
Date: Fri, 22 Jun 2018 18:08:54 -0400
0ef434
Subject: [PATCH 2/2] e2fsck: set dir_nlink feature if large dir exists
0ef434
0ef434
commit 1a8015773a9316ee90f713c275fb3a38731735e4
0ef434
0ef434
If there is a directory with more than EXT2_LINK_MAX (65000)
0ef434
subdirectories, but the DIR_NLINK feature is not set in the
0ef434
superblock, the feature should be set before continuing on
0ef434
to change the on-disk directory link count to 1.
0ef434
0ef434
While most filesystems should have DIR_NLINK set (it was set
0ef434
by default for all ext4 filesystems, and all kernels between
0ef434
2.6.23 and 4.12 automatically set it if the directory link
0ef434
count grew too large), it is possible that this flag is lost
0ef434
due to disk corruption or for an upgraded filesystem.  We no
0ef434
longer want kernels to automatically enable features.
0ef434
0ef434
Addresses: https://bugzilla.kernel.org/show_bug.cgi?id=196405
0ef434
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
0ef434
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
0ef434
---
0ef434
 e2fsck/pass4.c   | 14 +++++++++++++-
0ef434
 e2fsck/problem.c |  5 +++++
0ef434
 e2fsck/problem.h |  3 +++
0ef434
 3 files changed, 21 insertions(+), 1 deletion(-)
0ef434
0ef434
diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
0ef434
index 21d93f0c..ad95227c 100644
0ef434
--- a/e2fsck/pass4.c
0ef434
+++ b/e2fsck/pass4.c
0ef434
@@ -98,6 +98,7 @@ void e2fsck_pass4(e2fsck_t ctx)
0ef434
 #endif
0ef434
 	struct problem_context	pctx;
0ef434
 	__u16	link_count, link_counted;
0ef434
+	int dir_nlink_fs;
0ef434
 	char	*buf = 0;
0ef434
 	dgrp_t	group, maxgroup;
0ef434
 
0ef434
@@ -112,6 +113,9 @@ void e2fsck_pass4(e2fsck_t ctx)
0ef434
 	if (!(ctx->options & E2F_OPT_PREEN))
0ef434
 		fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
0ef434
 
0ef434
+	dir_nlink_fs = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
0ef434
+					EXT4_FEATURE_RO_COMPAT_DIR_NLINK);
0ef434
+
0ef434
 	group = 0;
0ef434
 	maxgroup = fs->group_desc_count;
0ef434
 	if (ctx->progress)
0ef434
@@ -158,8 +162,16 @@ void e2fsck_pass4(e2fsck_t ctx)
0ef434
 					    &link_counted);
0ef434
 		}
0ef434
 		isdir = ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i);
0ef434
-		if (isdir && (link_counted > EXT2_LINK_MAX))
0ef434
+		if (isdir && (link_counted > EXT2_LINK_MAX)) {
0ef434
+			if (!dir_nlink_fs &&
0ef434
+			    fix_problem(ctx, PR_4_DIR_NLINK_FEATURE, &pctx)) {
0ef434
+				fs->super->s_feature_ro_compat |=
0ef434
+					EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
0ef434
+				ext2fs_mark_super_dirty(fs);
0ef434
+				dir_nlink_fs = 1;
0ef434
+			}
0ef434
 			link_counted = 1;
0ef434
+		}
0ef434
 		if (link_counted != link_count) {
0ef434
 			e2fsck_read_inode(ctx, i, inode, "pass4");
0ef434
 			pctx.ino = i;
0ef434
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
0ef434
index c3ba631b..0210ff8f 100644
0ef434
--- a/e2fsck/problem.c
0ef434
+++ b/e2fsck/problem.c
0ef434
@@ -1576,6 +1576,11 @@ static struct e2fsck_problem problem_table[] = {
0ef434
 	  "They @s the same!\n"),
0ef434
 	  PROMPT_NONE, 0 },
0ef434
 
0ef434
+	/* directory exceeds max links, but no DIR_NLINK feature in superblock*/
0ef434
+	{ PR_4_DIR_NLINK_FEATURE,
0ef434
+	  N_("@d exceeds max links, but no DIR_NLINK feature in @S.\n"),
0ef434
+	  PROMPT_FIX, 0 },
0ef434
+
0ef434
 	/* Pass 5 errors */
0ef434
 
0ef434
 	/* Pass 5: Checking group summary information */
0ef434
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
0ef434
index cf2df8ce..5712de59 100644
0ef434
--- a/e2fsck/problem.h
0ef434
+++ b/e2fsck/problem.h
0ef434
@@ -1040,6 +1040,9 @@ struct problem_context {
0ef434
 /* Update quota information if it is inconsistent */
0ef434
 #define PR_6_UPDATE_QUOTAS		0x060002
0ef434
 
0ef434
+/* directory exceeds max links, but no DIR_NLINK feature in superblock */
0ef434
+#define PR_4_DIR_NLINK_FEATURE		0x040006
0ef434
+
0ef434
 /*
0ef434
  * Function declarations
0ef434
  */
0ef434
-- 
0ef434
2.20.1
0ef434