e2fsck: don't clobber critical metadata during check_blocks
If we encounter an inode with IND/DIND/TIND blocks or internal extent
tree blocks that point into critical FS metadata such as the
superblock, the group descriptors, the bitmaps, or the inode table,
it's quite possible that the validation code for those blocks is not
going to like what it finds, and it'll ask to try to fix the block.
Unfortunately, this happens before duplicate block processing (pass
1b), which means that we can end up doing stupid things like writing
extent blocks into the inode table, which multiplies e2fsck'
destructive effect and can render a filesystem unfixable.
To solve this, create a bitmap of all the critical FS metadata. If
before pass1b runs (basically check_blocks) we find a metadata block
that points into these critical regions, continue processing that
block, but avoid making any modifications, because we could be
misinterpreting inodes as block maps. Pass 1b will find the
multiply-owned blocks and fix that situation, which means that we can
then restart e2fsck from the beginning and actually fix whatever
problems we find.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-07-23 20:11:23 +04:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
# Run this test with a specific time, because we're crosslinking an extent tree
|
|
|
|
# block with the inode table. When fsck sets dtime to now, we want "now" to be
|
|
|
|
# our preprogrammed value.
|
|
|
|
|
|
|
|
FSCK_OPT=-fy
|
|
|
|
IMAGE=$test_dir/image.gz
|
|
|
|
E2FSCK_TIME=4294967294
|
|
|
|
export E2FSCK_TIME
|
|
|
|
|
|
|
|
gzip -d < $IMAGE > $TMPFILE
|
|
|
|
|
|
|
|
# Run fsck to fix things?
|
|
|
|
EXP1=$test_dir/expect.1
|
|
|
|
OUT1=$test_name.1.log
|
|
|
|
rm -rf $test_name.failed $test_name.ok
|
|
|
|
|
2014-11-08 00:50:49 +03:00
|
|
|
$FSCK $FSCK_OPT -N test_filesys $TMPFILE 2>&1 | tail -n +2 > $OUT1
|
e2fsck: don't clobber critical metadata during check_blocks
If we encounter an inode with IND/DIND/TIND blocks or internal extent
tree blocks that point into critical FS metadata such as the
superblock, the group descriptors, the bitmaps, or the inode table,
it's quite possible that the validation code for those blocks is not
going to like what it finds, and it'll ask to try to fix the block.
Unfortunately, this happens before duplicate block processing (pass
1b), which means that we can end up doing stupid things like writing
extent blocks into the inode table, which multiplies e2fsck'
destructive effect and can render a filesystem unfixable.
To solve this, create a bitmap of all the critical FS metadata. If
before pass1b runs (basically check_blocks) we find a metadata block
that points into these critical regions, continue processing that
block, but avoid making any modifications, because we could be
misinterpreting inodes as block maps. Pass 1b will find the
multiply-owned blocks and fix that situation, which means that we can
then restart e2fsck from the beginning and actually fix whatever
problems we find.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-07-23 20:11:23 +04:00
|
|
|
echo "Exit status is $?" >> $OUT1
|
|
|
|
|
|
|
|
# Run a second time
|
|
|
|
EXP2=$test_dir/expect.2
|
|
|
|
OUT2=$test_name.2.log
|
|
|
|
|
2014-11-08 00:50:49 +03:00
|
|
|
$FSCK $FSCK_OPT -N test_filesys $TMPFILE 2>&1 | tail -n +2 > $OUT2
|
e2fsck: don't clobber critical metadata during check_blocks
If we encounter an inode with IND/DIND/TIND blocks or internal extent
tree blocks that point into critical FS metadata such as the
superblock, the group descriptors, the bitmaps, or the inode table,
it's quite possible that the validation code for those blocks is not
going to like what it finds, and it'll ask to try to fix the block.
Unfortunately, this happens before duplicate block processing (pass
1b), which means that we can end up doing stupid things like writing
extent blocks into the inode table, which multiplies e2fsck'
destructive effect and can render a filesystem unfixable.
To solve this, create a bitmap of all the critical FS metadata. If
before pass1b runs (basically check_blocks) we find a metadata block
that points into these critical regions, continue processing that
block, but avoid making any modifications, because we could be
misinterpreting inodes as block maps. Pass 1b will find the
multiply-owned blocks and fix that situation, which means that we can
then restart e2fsck from the beginning and actually fix whatever
problems we find.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-07-23 20:11:23 +04:00
|
|
|
echo "Exit status is $?" >> $OUT2
|
|
|
|
|
|
|
|
# Figure out what happened
|
|
|
|
if cmp -s $EXP1 $OUT1 && cmp -s $EXP2 $OUT2; then
|
|
|
|
echo "$test_name: $test_description: ok"
|
|
|
|
touch $test_name.ok
|
|
|
|
else
|
|
|
|
echo "$test_name: $test_description: failed"
|
|
|
|
diff -u $EXP1 $OUT1 >> $test_name.failed
|
|
|
|
diff -u $EXP2 $OUT2 >> $test_name.failed
|
|
|
|
fi
|