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>
link_counted = 1;
}
if (link_counted != link_count) {
link_counted = 1;
}
if (link_counted != link_count) {
e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
inode_size, "pass4");
pctx.ino = i;
e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
inode_size, "pass4");
pctx.ino = i;
pctx.num = link_counted;
/* i_link_count was previously exceeded, but no longer
* is, fix this but don't consider it an error */
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),
inode->i_links_count = link_counted;
e2fsck_write_inode_full(ctx, i,
EXT2_INODE(inode),
N_("@d exceeds max links, but no DIR_NLINK feature in @S.\n"),
PROMPT_FIX, 0, 0, 0, 0 },
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 */
/* Pass 5 errors */
/* Pass 5: Checking group summary information */
/* directory exceeds max links, but no DIR_NLINK feature in superblock */
#define PR_4_DIR_NLINK_FEATURE 0x040006
/* 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
+
Inode 32963 ref count is 65000, should be 2. 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
Pass 5: Checking group summary information
Block bitmap differences: -73383
Fix? yes