btrfs: use dummy extent buffer for super block sys chunk array read
In function btrfs_read_sys_array(), we allocate a real extent buffer using btrfs_find_create_tree_block(). Such extent buffer will be even cached into buffer_radix tree, and using btree inode address space. However we only use such extent buffer to enable the accessors, thus we don't even need to bother using real extent buffer, a dummy one is what we really need. And for dummy extent buffer, we no longer need to do any special handling for the first page, as subpage helper is already doing it properly. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
0320b3538b
commit
e959d3c1df
|
@ -7370,7 +7370,6 @@ static int read_one_dev(struct extent_buffer *leaf,
|
|||
|
||||
int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_root *root = fs_info->tree_root;
|
||||
struct btrfs_super_block *super_copy = fs_info->super_copy;
|
||||
struct extent_buffer *sb;
|
||||
struct btrfs_disk_key *disk_key;
|
||||
|
@ -7386,30 +7385,16 @@ int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
|
|||
struct btrfs_key key;
|
||||
|
||||
ASSERT(BTRFS_SUPER_INFO_SIZE <= fs_info->nodesize);
|
||||
|
||||
/*
|
||||
* This will create extent buffer of nodesize, superblock size is
|
||||
* fixed to BTRFS_SUPER_INFO_SIZE. If nodesize > sb size, this will
|
||||
* overallocate but we can keep it as-is, only the first page is used.
|
||||
* We allocated a dummy extent, just to use extent buffer accessors.
|
||||
* There will be unused space after BTRFS_SUPER_INFO_SIZE, but
|
||||
* that's fine, we will not go beyond system chunk array anyway.
|
||||
*/
|
||||
sb = btrfs_find_create_tree_block(fs_info, BTRFS_SUPER_INFO_OFFSET,
|
||||
root->root_key.objectid, 0);
|
||||
if (IS_ERR(sb))
|
||||
return PTR_ERR(sb);
|
||||
sb = alloc_dummy_extent_buffer(fs_info, BTRFS_SUPER_INFO_OFFSET);
|
||||
if (!sb)
|
||||
return -ENOMEM;
|
||||
set_extent_buffer_uptodate(sb);
|
||||
/*
|
||||
* The sb extent buffer is artificial and just used to read the system array.
|
||||
* set_extent_buffer_uptodate() call does not properly mark all it's
|
||||
* pages up-to-date when the page is larger: extent does not cover the
|
||||
* whole page and consequently check_page_uptodate does not find all
|
||||
* the page's extents up-to-date (the hole beyond sb),
|
||||
* write_extent_buffer then triggers a WARN_ON.
|
||||
*
|
||||
* Regular short extents go through mark_extent_buffer_dirty/writeback cycle,
|
||||
* but sb spans only this function. Add an explicit SetPageUptodate call
|
||||
* to silence the warning eg. on PowerPC 64.
|
||||
*/
|
||||
if (PAGE_SIZE > BTRFS_SUPER_INFO_SIZE)
|
||||
SetPageUptodate(sb->pages[0]);
|
||||
|
||||
write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE);
|
||||
array_size = btrfs_super_sys_array_size(super_copy);
|
||||
|
|
Loading…
Reference in New Issue