e2fsprogs/e2fsck-check-and-fix-tails-of-all-bitmaps.patch
OBS User mschnitzer b1cbb812be Set link to e2fsprogs.11742 via maintenance_release request
Rev SUSE:SLE-12:Update/5 Md5 fe895511cbe274cb847ab3dde5f22c5b 2019-07-05 12:10:32 mschnitzer None
2019-07-05 12:10:32 +00:00

356 lines
12 KiB
Diff

From 6d0b48896247dc70b16482a8ff4123d570285a2a Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Sun, 5 May 2019 16:43:33 -0400
Subject: [PATCH] e2fsck: check and fix tails of all bitmap blocks
References: bsc#1128383
Currently, e2fsck effectively checks only tail of the last inode and
block bitmap in the filesystem. Thus if some previous bitmap has unset
bits it goes unnoticed. Mostly these tail bits in the bitmap are
ignored; however, if blocks_per_group are smaller than 8*blocksize,
the multi-block allocator in the kernel can get confused when the tail
bits are unset and return bogus free extent.
Add support to libext2fs to check these bitmap tails when loading
bitmaps (as that's about the only place which has access to the bitmap
tail bits) and make e2fsck use this functionality to detect buggy bitmap
tails and fix them (by rewriting the bitmaps).
Reported-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
e2fsck/pass5.c | 40 ++++++++++++++++---
lib/ext2fs/ext2fs.h | 2 +
lib/ext2fs/rw_bitmaps.c | 26 +++++++++++-
tests/f_bitmaps/expect.1 | 2 +
tests/f_dup/expect.1 | 2 +
tests/f_dup2/expect.1 | 2 +
tests/f_dup3/expect.1 | 2 +
tests/f_end-bitmap/expect.1 | 2 +
tests/f_illbbitmap/expect.1 | 2 +
tests/f_illibitmap/expect.1 | 2 +
tests/f_illitable_flexbg/expect.1 | 2 +
tests/f_lpf/expect.1 | 2 +
tests/f_overfsblks/expect.1 | 2 +
tests/f_super_bad_csum/expect.1 | 4 +-
tests/j_corrupt_ext_jnl_sb_csum/expect | 2 +
tests/j_ext_long_trans/expect | 2 +
tests/j_long_trans/expect | 2 +
tests/j_long_trans_mcsum_32bit/expect | 2 +
tests/j_long_trans_mcsum_64bit/expect | 2 +
tests/j_recover_csum2_32bit/expect.1 | 2 +
tests/j_recover_csum2_64bit/expect.1 | 2 +
tests/j_short_trans/expect | 2 +
tests/j_short_trans_64bit/expect | 2 +
tests/j_short_trans_mcsum_64bit/expect | 2 +
tests/j_short_trans_old_csum/expect | 2 +
tests/j_short_trans_open_recover/expect | 2 +
tests/j_short_trans_recover/expect | 2 +
.../j_short_trans_recover_mcsum_64bit/expect | 2 +
tests/t_replay_and_set/expect | 2 +
29 files changed, 113 insertions(+), 9 deletions(-)
Index: e2fsprogs-1.42.11/e2fsck/pass5.c
===================================================================
--- e2fsprogs-1.42.11.orig/e2fsck/pass5.c
+++ e2fsprogs-1.42.11/e2fsck/pass5.c
@@ -731,6 +731,7 @@ static void check_inode_end(e2fsck_t ctx
ext2_filsys fs = ctx->fs;
ext2_ino_t end, save_inodes_count, i;
struct problem_context pctx;
+ int asked = 0;
clear_problem_context(&pctx);
@@ -744,11 +745,12 @@ static void check_inode_end(e2fsck_t ctx
return;
}
if (save_inodes_count == end)
- return;
+ goto check_intra_bg_tail;
/* protect loop from wrap-around if end is maxed */
for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) {
if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
+ asked = 1;
if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
for (; i <= end; i++)
ext2fs_mark_inode_bitmap(fs->inode_map,
@@ -768,6 +770,20 @@ static void check_inode_end(e2fsck_t ctx
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
return;
}
+ /*
+ * If the number of inodes per block group != blocksize, we
+ * can also have a potential problem with the tail bits in
+ * each individual inode bitmap block. If there is a problem,
+ * it would have been noticed when the bitmap was loaded. And
+ * fixing this is easy; all we need to do force the bitmap to
+ * be written back to disk.
+ */
+check_intra_bg_tail:
+ if (!asked && fs->flags & EXT2_FLAG_IBITMAP_TAIL_PROBLEM)
+ if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx))
+ ext2fs_mark_ib_dirty(fs);
+ else
+ ext2fs_unmark_valid(fs);
}
static void check_block_end(e2fsck_t ctx)
@@ -775,6 +791,7 @@ static void check_block_end(e2fsck_t ctx
ext2_filsys fs = ctx->fs;
blk64_t end, save_blocks_count, i;
struct problem_context pctx;
+ int asked = 0;
clear_problem_context(&pctx);
@@ -789,12 +806,13 @@ static void check_block_end(e2fsck_t ctx
return;
}
if (save_blocks_count == end)
- return;
+ goto check_intra_bg_tail;
/* Protect loop from wrap-around if end is maxed */
for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
if (!ext2fs_test_block_bitmap2(fs->block_map,
EXT2FS_C2B(fs, i))) {
+ asked = 1;
if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
for (; i <= end; i++)
ext2fs_mark_block_bitmap2(fs->block_map,
@@ -814,7 +832,19 @@ static void check_block_end(e2fsck_t ctx
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
return;
}
+ /*
+ * If the number of blocks per block group != blocksize, we
+ * can also have a potential problem with the tail bits in
+ * each individual block bitmap block. If there is a problem,
+ * it would have been noticed when the bitmap was loaded. And
+ * fixing this is easy; all we need to do force the bitmap to
+ * be written back to disk.
+ */
+check_intra_bg_tail:
+ if (!asked && fs->flags & EXT2_FLAG_BBITMAP_TAIL_PROBLEM) {
+ if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx))
+ ext2fs_mark_bb_dirty(fs);
+ else
+ ext2fs_unmark_valid(fs);
+ }
}
-
-
-
Index: e2fsprogs-1.42.11/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs-1.42.11.orig/lib/ext2fs/ext2fs.h
+++ e2fsprogs-1.42.11/lib/ext2fs/ext2fs.h
@@ -192,6 +192,8 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_PRINT_PROGRESS 0x40000
#define EXT2_FLAG_DIRECT_IO 0x80000
#define EXT2_FLAG_SKIP_MMP 0x100000
+#define EXT2_FLAG_BBITMAP_TAIL_PROBLEM 0x1000000
+#define EXT2_FLAG_IBITMAP_TAIL_PROBLEM 0x2000000
/*
* Special flag in the ext2 inode i_flag field that means that this is
Index: e2fsprogs-1.42.11/lib/ext2fs/rw_bitmaps.c
===================================================================
--- e2fsprogs-1.42.11.orig/lib/ext2fs/rw_bitmaps.c
+++ e2fsprogs-1.42.11/lib/ext2fs/rw_bitmaps.c
@@ -182,6 +182,16 @@ static errcode_t mark_uninit_bg_group_bl
return 0;
}
+static int bitmap_tail_verify(unsigned char *bitmap, int first, int last)
+{
+ int i;
+
+ for (i = first; i <= last; i++)
+ if (bitmap[i] != 0xff)
+ return 0;
+ return 1;
+}
+
static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
{
dgrp_t i;
@@ -190,6 +200,7 @@ static errcode_t read_bitmaps(ext2_filsy
errcode_t retval;
int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
+ int tail_flags = 0;
int csum_flag = 0;
unsigned int cnt;
blk64_t blk;
@@ -297,6 +308,9 @@ static errcode_t read_bitmaps(ext2_filsy
retval = EXT2_ET_BLOCK_BITMAP_READ;
goto cleanup;
}
+ if (!bitmap_tail_verify(block_bitmap,
+ block_nbytes, fs->blocksize - 1))
+ tail_flags |= EXT2_FLAG_BBITMAP_TAIL_PROBLEM;
} else
memset(block_bitmap, 0, block_nbytes);
cnt = block_nbytes << 3;
@@ -319,6 +333,9 @@ static errcode_t read_bitmaps(ext2_filsy
retval = EXT2_ET_INODE_BITMAP_READ;
goto cleanup;
}
+ if (!bitmap_tail_verify(inode_bitmap,
+ inode_nbytes, fs->blocksize - 1))
+ tail_flags |= EXT2_FLAG_IBITMAP_TAIL_PROBLEM;
} else
memset(inode_bitmap, 0, inode_nbytes);
cnt = inode_nbytes << 3;
@@ -338,10 +355,15 @@ static errcode_t read_bitmaps(ext2_filsy
}
success_cleanup:
- if (inode_bitmap)
+ if (inode_bitmap) {
ext2fs_free_mem(&inode_bitmap);
- if (block_bitmap)
+ fs->flags &= ~EXT2_FLAG_IBITMAP_TAIL_PROBLEM;
+ }
+ if (block_bitmap) {
ext2fs_free_mem(&block_bitmap);
+ fs->flags &= ~EXT2_FLAG_BBITMAP_TAIL_PROBLEM;
+ }
+ fs->flags |= tail_flags;
return 0;
cleanup:
Index: e2fsprogs-1.42.11/tests/f_bitmaps/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_bitmaps/expect.1
+++ e2fsprogs-1.42.11/tests/f_bitmaps/expect.1
@@ -11,6 +11,8 @@ Fix? yes
Inode bitmap differences: +11 -15
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (9.1% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.42.11/tests/f_dup/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_dup/expect.1
+++ e2fsprogs-1.42.11/tests/f_dup/expect.1
@@ -30,6 +30,8 @@ Fix? yes
Free blocks count wrong (62, counted=60).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Padding at end of block bitmap is not set. Fix? yes
Index: e2fsprogs-1.42.11/tests/f_dup2/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_dup2/expect.1
+++ e2fsprogs-1.42.11/tests/f_dup2/expect.1
@@ -37,6 +37,8 @@ Fix? yes
Free blocks count wrong (26, counted=22).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Padding at end of block bitmap is not set. Fix? yes
Index: e2fsprogs-1.42.11/tests/f_dup3/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_dup3/expect.1
+++ e2fsprogs-1.42.11/tests/f_dup3/expect.1
@@ -39,6 +39,8 @@ Fix? yes
Free blocks count wrong (20, counted=19).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 16/16 files (25.0% non-contiguous), 81/100 blocks
Index: e2fsprogs-1.42.11/tests/f_end-bitmap/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_end-bitmap/expect.1
+++ e2fsprogs-1.42.11/tests/f_end-bitmap/expect.1
@@ -8,6 +8,8 @@ Pass 5: Checking group summary informati
Free blocks count wrong for group #0 (44, counted=63).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Padding at end of block bitmap is not set. Fix? yes
Index: e2fsprogs-1.42.11/tests/f_illbbitmap/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_illbbitmap/expect.1
+++ e2fsprogs-1.42.11/tests/f_illbbitmap/expect.1
@@ -22,6 +22,8 @@ Fix? yes
Inode bitmap differences: -(12--21)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.42.11/tests/f_illibitmap/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_illibitmap/expect.1
+++ e2fsprogs-1.42.11/tests/f_illibitmap/expect.1
@@ -19,6 +19,8 @@ Pass 5: Checking group summary informati
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.42.11/tests/f_illitable_flexbg/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_illitable_flexbg/expect.1
+++ e2fsprogs-1.42.11/tests/f_illitable_flexbg/expect.1
@@ -18,6 +18,8 @@ Pass 5: Checking group summary informati
Inode bitmap differences: -(65--128)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 12/256 files (0.0% non-contiguous), 31163/32768 blocks
Index: e2fsprogs-1.42.11/tests/f_lpf/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_lpf/expect.1
+++ e2fsprogs-1.42.11/tests/f_lpf/expect.1
@@ -42,6 +42,8 @@ Fix? yes
Free inodes count wrong (1, counted=0).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 16/16 files (12.5% non-contiguous), 67/100 blocks
Index: e2fsprogs-1.42.11/tests/f_overfsblks/expect.1
===================================================================
--- e2fsprogs-1.42.11.orig/tests/f_overfsblks/expect.1
+++ e2fsprogs-1.42.11/tests/f_overfsblks/expect.1
@@ -13,6 +13,8 @@ Pass 5: Checking group summary informati
Inode bitmap differences: -(12--21)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks