Message ID | c481f192c76a98d5d750aa42f2d268a9bc20be5f.1679538836.git.wqu@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs-progs: convert: handle ext4 orphan file feature properly | expand |
On Thu, Mar 23, 2023 at 10:33:59AM +0800, Qu Wenruo wrote: > [BUG] > Since e2fsprog 1.47, even a newly created empty ext4, btrfs-convert > would result an fs that btrfs-check would complain: > > # mkfs.ext4 -F test.img > # btrfs-convert test.img > # btrfs-check test.img > Opening filesystem to check... > Checking filesystem on test.img > UUID: e45da158-8967-4e4d-9c9f-66b0d127dbce > [1/7] checking root items > [2/7] checking extents > [3/7] checking free space cache > [4/7] checking fs roots > root 5 inode 266 errors 2000, link count wrong > ERROR: errors found in fs roots > found 26333184 bytes used, error(s) found <<< > total csum bytes: 25540 > total tree bytes: 180224 > total fs tree bytes: 49152 > total extent tree bytes: 16384 > btree space waste bytes: 145423 > file data blocks allocated: 33947648 > referenced 26284032 > > [CAUSE] > Ext4 has a new compat feature, COMPAT_ORPHAN_FILE, as a better way to > track all the orphan inodes. > > This new feature would create a new special inode for this purpose, and > such orphan file inode would not be reachable from any other inode, but > only from super block. > > Unfortunately btrfs-convert only skip ext2 known special inodes, not the > newer one. > > [FIX] > According to the kernel document, we can locate the orphan file inode > using ext2 super block s_orphan_file_inum, and skip it for > btrfs-convert. > > And such skip would only happen if we have the definition of > EXT4_FEATURE_COMPAT_ORPHAN_FILE, to be compatible with older e2fsprogs. > > Signed-off-by: Qu Wenruo <wqu@suse.com> Added to devel, thanks. I don't have e2fsprogs 1.47 on any testing host yet, it's stuck in the QA because the change in defaults broke grub2, but I could update the Tumbleweed CI image to pull packages from the devel repos.
diff --git a/convert/source-ext2.c b/convert/source-ext2.c index b0b865b99b7b..c8c8930a79e9 100644 --- a/convert/source-ext2.c +++ b/convert/source-ext2.c @@ -903,10 +903,20 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans, return btrfs_insert_inode(trans, root, objectid, &btrfs_inode); } -static int ext2_is_special_inode(ext2_ino_t ino) +static bool ext2_is_special_inode(ext2_filsys ext2_fs, ext2_ino_t ino) { if (ino < EXT2_GOOD_OLD_FIRST_INO && ino != EXT2_ROOT_INO) return 1; +#ifdef EXT4_FEATURE_COMPAT_ORPHAN_FILE + /* + * If we have COMPAT_ORPHAN_FILE feature, we have a special inode + * recording all the orphan files. + * We need to skip such special inode. + */ + if (ext2_fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_ORPHAN_FILE && + ino == ext2_fs->super->s_orphan_file_inum) + return 1; +#endif return 0; } @@ -940,7 +950,7 @@ static int ext2_copy_inodes(struct btrfs_convert_context *cctx, /* no more inodes */ if (ext2_ino == 0) break; - if (ext2_is_special_inode(ext2_ino)) + if (ext2_is_special_inode(ext2_fs, ext2_ino)) continue; objectid = ext2_ino + INO_OFFSET; ret = ext2_copy_single_inode(trans, root,
[BUG] Since e2fsprog 1.47, even a newly created empty ext4, btrfs-convert would result an fs that btrfs-check would complain: # mkfs.ext4 -F test.img # btrfs-convert test.img # btrfs-check test.img Opening filesystem to check... Checking filesystem on test.img UUID: e45da158-8967-4e4d-9c9f-66b0d127dbce [1/7] checking root items [2/7] checking extents [3/7] checking free space cache [4/7] checking fs roots root 5 inode 266 errors 2000, link count wrong ERROR: errors found in fs roots found 26333184 bytes used, error(s) found <<< total csum bytes: 25540 total tree bytes: 180224 total fs tree bytes: 49152 total extent tree bytes: 16384 btree space waste bytes: 145423 file data blocks allocated: 33947648 referenced 26284032 [CAUSE] Ext4 has a new compat feature, COMPAT_ORPHAN_FILE, as a better way to track all the orphan inodes. This new feature would create a new special inode for this purpose, and such orphan file inode would not be reachable from any other inode, but only from super block. Unfortunately btrfs-convert only skip ext2 known special inodes, not the newer one. [FIX] According to the kernel document, we can locate the orphan file inode using ext2 super block s_orphan_file_inum, and skip it for btrfs-convert. And such skip would only happen if we have the definition of EXT4_FEATURE_COMPAT_ORPHAN_FILE, to be compatible with older e2fsprogs. Signed-off-by: Qu Wenruo <wqu@suse.com> --- convert/source-ext2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)