Message ID | 20210923152911.359451-1-naohiro.aota@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs-progs: properly format btrfs_header in btrfs_create_root() | expand |
On Fri, Sep 24, 2021 at 12:29:11AM +0900, Naohiro Aota wrote: > Enabling quota on zoned btrfs hits the following ASSERT(). > > $ mkfs.btrfs -f -d single -m single -R quota /dev/nullb0 > btrfs-progs v5.11 > See http://btrfs.wiki.kernel.org for more information. > > Zoned: /dev/nullb0: host-managed device detected, setting zoned feature > Resetting device zones /dev/nullb0 (1600 zones) ... > bad tree block 25395200, bytenr mismatch, want=25395200, have=0 > kernel-shared/disk-io.c:549: write_tree_block: BUG_ON `1` triggered, value 1 > ./mkfs.btrfs(+0x26aaa)[0x564d1a7ccaaa] > ./mkfs.btrfs(write_tree_block+0xb8)[0x564d1a7cee29] > ./mkfs.btrfs(__commit_transaction+0x91)[0x564d1a7e3740] > ./mkfs.btrfs(btrfs_commit_transaction+0x135)[0x564d1a7e39aa] > ./mkfs.btrfs(main+0x1fe9)[0x564d1a7b442a] > /lib64/libc.so.6(__libc_start_main+0xcd)[0x7f36377d37fd] > ./mkfs.btrfs(_start+0x2a)[0x564d1a7b1fda] > zsh: IOT instruction sudo ./mkfs.btrfs -f -d single -m single -R quota /dev/nullb0 > > The issue occur because btrfs_create_root() is not formatting the root node > properly. This is fine on regular btrfs, because it's fortunately reusing > an once freed buffer. As the previous tree node allocation kindly formatted > the header, it will see the proper bytenr and pass the checks. > > However, we never reuse an once freed buffer on zoned btrfs. As a result, > we have zero-filled bytenr, FSID, and chunk-tree UUID, hitting the ASSERTs > in check_tree_block(). > > Reported-by: Johannes Thumshirn <Johannes.Thumshirn@wdc.com> > Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Added to devel, thanks.
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 6e9358cbac55..21e5414965e7 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -237,11 +237,16 @@ int btrfs_create_root(struct btrfs_trans_handle *trans, } new_root->node = node; + memset_extent_buffer(node, 0, 0, sizeof(struct btrfs_header)); + btrfs_set_header_bytenr(node, node->start); btrfs_set_header_generation(node, trans->transid); btrfs_set_header_backref_rev(node, BTRFS_MIXED_BACKREF_REV); - btrfs_clear_header_flag(node, - BTRFS_HEADER_FLAG_RELOC | BTRFS_HEADER_FLAG_WRITTEN); btrfs_set_header_owner(node, objectid); + write_extent_buffer(node, fs_info->fs_devices->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + write_extent_buffer(node, fs_info->chunk_tree_uuid, + btrfs_header_chunk_tree_uuid(node), + BTRFS_UUID_SIZE); btrfs_set_header_nritems(node, 0); btrfs_set_header_level(node, 0); ret = btrfs_inc_ref(trans, new_root, node, 0);
Enabling quota on zoned btrfs hits the following ASSERT(). $ mkfs.btrfs -f -d single -m single -R quota /dev/nullb0 btrfs-progs v5.11 See http://btrfs.wiki.kernel.org for more information. Zoned: /dev/nullb0: host-managed device detected, setting zoned feature Resetting device zones /dev/nullb0 (1600 zones) ... bad tree block 25395200, bytenr mismatch, want=25395200, have=0 kernel-shared/disk-io.c:549: write_tree_block: BUG_ON `1` triggered, value 1 ./mkfs.btrfs(+0x26aaa)[0x564d1a7ccaaa] ./mkfs.btrfs(write_tree_block+0xb8)[0x564d1a7cee29] ./mkfs.btrfs(__commit_transaction+0x91)[0x564d1a7e3740] ./mkfs.btrfs(btrfs_commit_transaction+0x135)[0x564d1a7e39aa] ./mkfs.btrfs(main+0x1fe9)[0x564d1a7b442a] /lib64/libc.so.6(__libc_start_main+0xcd)[0x7f36377d37fd] ./mkfs.btrfs(_start+0x2a)[0x564d1a7b1fda] zsh: IOT instruction sudo ./mkfs.btrfs -f -d single -m single -R quota /dev/nullb0 The issue occur because btrfs_create_root() is not formatting the root node properly. This is fine on regular btrfs, because it's fortunately reusing an once freed buffer. As the previous tree node allocation kindly formatted the header, it will see the proper bytenr and pass the checks. However, we never reuse an once freed buffer on zoned btrfs. As a result, we have zero-filled bytenr, FSID, and chunk-tree UUID, hitting the ASSERTs in check_tree_block(). Reported-by: Johannes Thumshirn <Johannes.Thumshirn@wdc.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> --- kernel-shared/ctree.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)