mirror of https://github.com/vitalif/e2fsprogs
e2fsck: write dir blocks after new inode when reconstructing root/lost+found
If we trash the root directory block, e2fsck will find inode 11 (the old lost+found) and try to attach it to l+f. The lost+found checker also fails to find l+f and tries to add one to the root dir. The root dir is not found but is recreated with incorrect checksums, so linking in the l+f dir fails and the l+f '..' entry isn't set. Since both dirs now fail checksum verification, they're both referred to rehash to have that fixed, but because l+f doesn't have a '..' entry, rehash crashes because l+f has < 2 entries. On a checksumming filesystem, the routines in e2fsck that recreate /lost+found and / must write the new directory block *after* the inode has been written to disk because the checksum depends on i_generation. Add a regression test while we're at it. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>crypto
parent
17641bf208
commit
eb89a6287d
|
@ -204,28 +204,6 @@ skip_new_block:
|
|||
ext2fs_mark_block_bitmap2(fs->block_map, blk);
|
||||
ext2fs_mark_bb_dirty(fs);
|
||||
|
||||
/*
|
||||
* Now let's create the actual data block for the inode
|
||||
*/
|
||||
pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
|
||||
&block);
|
||||
if (pctx.errcode) {
|
||||
pctx.str = "ext2fs_new_dir_block";
|
||||
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
||||
ctx->flags |= E2F_FLAG_ABORT;
|
||||
return;
|
||||
}
|
||||
|
||||
pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
|
||||
EXT2_ROOT_INO);
|
||||
if (pctx.errcode) {
|
||||
pctx.str = "ext2fs_write_dir_block4";
|
||||
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
||||
ctx->flags |= E2F_FLAG_ABORT;
|
||||
return;
|
||||
}
|
||||
ext2fs_free_mem(&block);
|
||||
|
||||
/*
|
||||
* Set up the inode structure
|
||||
*/
|
||||
|
@ -248,6 +226,30 @@ skip_new_block:
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now let's create the actual data block for the inode.
|
||||
* Due to metadata_csum, we must write the dir blocks AFTER
|
||||
* the inode has been written to disk!
|
||||
*/
|
||||
pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
|
||||
&block);
|
||||
if (pctx.errcode) {
|
||||
pctx.str = "ext2fs_new_dir_block";
|
||||
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
||||
ctx->flags |= E2F_FLAG_ABORT;
|
||||
return;
|
||||
}
|
||||
|
||||
pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
|
||||
EXT2_ROOT_INO);
|
||||
ext2fs_free_mem(&block);
|
||||
if (pctx.errcode) {
|
||||
pctx.str = "ext2fs_write_dir_block4";
|
||||
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
||||
ctx->flags |= E2F_FLAG_ABORT;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Miscellaneous bookkeeping...
|
||||
*/
|
||||
|
@ -471,24 +473,6 @@ skip_new_block:
|
|||
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
|
||||
ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
|
||||
|
||||
/*
|
||||
* Now let's create the actual data block for the inode
|
||||
*/
|
||||
retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
|
||||
if (retval) {
|
||||
pctx.errcode = retval;
|
||||
fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
|
||||
ext2fs_free_mem(&block);
|
||||
if (retval) {
|
||||
pctx.errcode = retval;
|
||||
fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the inode structure
|
||||
*/
|
||||
|
@ -509,6 +493,27 @@ skip_new_block:
|
|||
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now let's create the actual data block for the inode.
|
||||
* Due to metadata_csum, the directory block MUST be written
|
||||
* after the inode is written to disk!
|
||||
*/
|
||||
retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
|
||||
if (retval) {
|
||||
pctx.errcode = retval;
|
||||
fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
|
||||
ext2fs_free_mem(&block);
|
||||
if (retval) {
|
||||
pctx.errcode = retval;
|
||||
fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, create the directory link
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Pass 2: Checking directory structure
|
||||
Directory inode 2, block #0, offset 0: directory has no checksum.
|
||||
Fix? yes
|
||||
|
||||
Directory inode 2, block #0, offset 0: directory corrupted
|
||||
Salvage? yes
|
||||
|
||||
Missing '.' in directory inode 2.
|
||||
Fix? yes
|
||||
|
||||
Setting filetype for entry '.' in ??? (2) to 2.
|
||||
Missing '..' in directory inode 2.
|
||||
Fix? yes
|
||||
|
||||
Setting filetype for entry '..' in ??? (2) to 2.
|
||||
Pass 3: Checking directory connectivity
|
||||
'..' in / (2) is <The NULL inode> (0), should be / (2).
|
||||
Fix? yes
|
||||
|
||||
Unconnected directory inode 11 (/???)
|
||||
Connect to /lost+found? yes
|
||||
|
||||
/lost+found not found. Create? yes
|
||||
|
||||
Pass 3A: Optimizing directories
|
||||
Pass 4: Checking reference counts
|
||||
Inode 11 ref count is 3, should be 2. Fix? yes
|
||||
|
||||
Unattached inode 12
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 12 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 13
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 13 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 14
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 14 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 15
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 15 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 16
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 16 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 17
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 17 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 18
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 18 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 19
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 19 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 20
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 20 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 21
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 21 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 22
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 22 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 23
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 23 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 24
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 24 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 25
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 25 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 26
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 26 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 27
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 27 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 28
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 28 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 29
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 29 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 30
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 30 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 31
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 31 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 32
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 32 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 33
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 33 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 34
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 34 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 35
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 35 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 36
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 36 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 37
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 37 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 38
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 38 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 39
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 39 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 40
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 40 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 41
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 41 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 42
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 42 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 43
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 43 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 44
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 44 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 45
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 45 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 46
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 46 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 47
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 47 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 48
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 48 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 49
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 49 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 50
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 50 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 51
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 51 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 52
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 52 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 53
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 53 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 54
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 54 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 55
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 55 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 56
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 56 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 57
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 57 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 58
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 58 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 59
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 59 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 60
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 60 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 61
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 61 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 62
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 62 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 63
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 63 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 64
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 64 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached zero-length inode 65. Clear? yes
|
||||
|
||||
Unattached inode 66
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 66 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Unattached inode 67
|
||||
Connect to /lost+found? yes
|
||||
|
||||
Inode 67 ref count is 2, should be 1. Fix? yes
|
||||
|
||||
Pass 5: Checking group summary information
|
||||
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
test_filesys: 67/512 files (1.5% non-contiguous), 1127/2048 blocks
|
||||
Exit status is 1
|
|
@ -0,0 +1,7 @@
|
|||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
test_filesys: 67/512 files (1.5% non-contiguous), 1127/2048 blocks
|
||||
Exit status is 0
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
force fsck to rebuild a corrupted rootdir w/ metadata_csum
|
Loading…
Reference in New Issue