diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 3fd1253d..31131ab5 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -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 */ diff --git a/tests/f_rebuild_csum_rootdir/expect.1 b/tests/f_rebuild_csum_rootdir/expect.1 new file mode 100644 index 00000000..4df58f91 --- /dev/null +++ b/tests/f_rebuild_csum_rootdir/expect.1 @@ -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 (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 diff --git a/tests/f_rebuild_csum_rootdir/expect.2 b/tests/f_rebuild_csum_rootdir/expect.2 new file mode 100644 index 00000000..033f1bf7 --- /dev/null +++ b/tests/f_rebuild_csum_rootdir/expect.2 @@ -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 diff --git a/tests/f_rebuild_csum_rootdir/image.gz b/tests/f_rebuild_csum_rootdir/image.gz new file mode 100644 index 00000000..a32fd443 Binary files /dev/null and b/tests/f_rebuild_csum_rootdir/image.gz differ diff --git a/tests/f_rebuild_csum_rootdir/name b/tests/f_rebuild_csum_rootdir/name new file mode 100644 index 00000000..b246f480 --- /dev/null +++ b/tests/f_rebuild_csum_rootdir/name @@ -0,0 +1 @@ +force fsck to rebuild a corrupted rootdir w/ metadata_csum