aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2020-02-13 11:15:56 +0100
committerTheodore Ts'o <tytso@mit.edu>2020-03-07 13:49:43 -0500
commit4ebce13292f54c96f43dcb1bd1d5b8df5dc8749d (patch)
treec39563ec0b60f8299441d619591e92898f47146e
parentb84a5568c7421f494ecd9fe474df6754004df05c (diff)
downloade2fsprogs-4ebce13292f54c96f43dcb1bd1d5b8df5dc8749d.tar.gz
e2fsck: clarify overflow link count error message
When directory link count is set to overflow value (1) but during pass 4 we find out the exact link count would fit, we either silently fix this (which is not great because e2fsck then reports the fs was modified but output doesn't indicate why in any way), or we report that link count is wrong and ask whether we should fix it (in case -n option was specified). The second case is even more misleading because it suggests non-trivial fs corruption which then gets silently fixed on the next run. Similarly to how we fix up other non-problems, just create a new error message for the case directory link count is not overflown anymore and always report it to clarify what is going on. Reviewed-by: Andreas Dilger <adilger@dilger.ca> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--e2fsck/pass4.c20
-rw-r--r--e2fsck/problem.c5
-rw-r--r--e2fsck/problem.h3
-rw-r--r--tests/f_many_subdirs/expect.12
4 files changed, 26 insertions, 4 deletions
diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
index 10be7f871..8c2d2f1fc 100644
--- a/e2fsck/pass4.c
+++ b/e2fsck/pass4.c
@@ -237,6 +237,8 @@ void e2fsck_pass4(e2fsck_t ctx)
link_counted = 1;
}
if (link_counted != link_count) {
+ int fix_nlink = 0;
+
e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
inode_size, "pass4");
pctx.ino = i;
@@ -250,10 +252,20 @@ void e2fsck_pass4(e2fsck_t ctx)
pctx.num = link_counted;
/* i_link_count was previously exceeded, but no longer
* is, fix this but don't consider it an error */
- if ((isdir && 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)) {
+ if (isdir && link_counted > 1 &&
+ (inode->i_flags & EXT2_INDEX_FL) &&
+ link_count == 1) {
+ if ((ctx->options & E2F_OPT_READONLY) == 0) {
+ fix_nlink =
+ fix_problem(ctx,
+ PR_4_DIR_OVERFLOW_REF_COUNT,
+ &pctx);
+ }
+ } else {
+ fix_nlink = fix_problem(ctx, PR_4_BAD_REF_COUNT,
+ &pctx);
+ }
+ if (fix_nlink) {
inode->i_links_count = link_counted;
e2fsck_write_inode_full(ctx, i,
EXT2_INODE(inode),
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index c7c0ba986..e79c853b2 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -2035,6 +2035,11 @@ static struct e2fsck_problem problem_table[] = {
N_("@d exceeds max links, but no DIR_NLINK feature in @S.\n"),
PROMPT_FIX, 0, 0, 0, 0 },
+ /* Directory inode ref count set to overflow but could be exact value */
+ { PR_4_DIR_OVERFLOW_REF_COUNT,
+ N_("@d @i %i ref count set to overflow but could be exact value %N. "),
+ PROMPT_FIX, PR_PREEN_OK, 0, 0, 0 },
+
/* Pass 5 errors */
/* Pass 5: Checking group summary information */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index c7f65f6de..4185e5175 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -1164,6 +1164,9 @@ struct problem_context {
/* directory exceeds max links, but no DIR_NLINK feature in superblock */
#define PR_4_DIR_NLINK_FEATURE 0x040006
+/* Directory ref count set to overflow but it doesn't have to be */
+#define PR_4_DIR_OVERFLOW_REF_COUNT 0x040007
+
/*
* Pass 5 errors
*/
diff --git a/tests/f_many_subdirs/expect.1 b/tests/f_many_subdirs/expect.1
index f2fd78f7c..a8da4807a 100644
--- a/tests/f_many_subdirs/expect.1
+++ b/tests/f_many_subdirs/expect.1
@@ -17,6 +17,8 @@ Fix? yes
Inode 32963 ref count is 65000, should be 2. Fix? yes
+Directory inode 39601 ref count set to overflow but could be exact value 2. Fix? yes
+
Pass 5: Checking group summary information
Block bitmap differences: -73383
Fix? yes