btrfs-progs: check: detect and warn about tree blocks crossing 64K page boundary

For the incoming subpage support, there is a new requirement for tree
blocks.  Tree blocks should not cross 64K page boundary.

For current btrfs-progs and kernel, there shouldn't be any causes to
create such tree blocks.  But still, we want to detect such tree blocks
in the wild before subpage support fully lands in upstream.

This patch will add such check for both lowmem and original mode.
Currently it's just a warning, since there aren't many users using 64K
page size yet.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2020-11-09 13:39:51 +08:00 committed by David Sterba
parent 08fb534eb7
commit fc38ae7f48
3 changed files with 22 additions and 0 deletions

View File

@ -5400,6 +5400,8 @@ static int process_extent_item(struct btrfs_root *root,
num_bytes, gfs_info->sectorsize);
return -EIO;
}
if (metadata)
btrfs_check_subpage_eb_alignment(key.objectid, num_bytes);
memset(&tmpl, 0, sizeof(tmpl));
tmpl.start = key.objectid;

View File

@ -174,4 +174,22 @@ static inline u32 btrfs_type_to_imode(u8 type)
int get_extent_item_generation(u64 bytenr, u64 *gen_ret);
/*
* Check tree block alignement for future subpage support on 64K page system.
*
* Subpage support on 64K page size require one eb to be completely contained
* by a page. Not allowing a tree block to cross 64K page boudanry.
*
* Since subpage support is still under development, this check only provides
* warning.
*/
static inline void btrfs_check_subpage_eb_alignment(u64 start, u32 len)
{
if (start / BTRFS_MAX_METADATA_BLOCKSIZE !=
(start + len) / BTRFS_MAX_METADATA_BLOCKSIZE)
warning(
"tree block [%llu, %llu) crosses 64K page boudnary, may cause problem for 64K page system",
start, start + len);
}
#endif

View File

@ -4264,6 +4264,8 @@ static int check_extent_item(struct btrfs_path *path)
key.objectid, key.objectid + nodesize);
err |= CROSSING_STRIPE_BOUNDARY;
}
if (metadata)
btrfs_check_subpage_eb_alignment(key.objectid, nodesize);
ptr = (unsigned long)(ei + 1);