btrfs-progs: fix lowmem check's handling of holes

Lowmem check had the opposite problem of normal check, it caught gaps
that started at 0, but would still fail with my fixes in place.  This is
because lowmem check doesn't take into account the isize of the inode.
Address this by making sure we do not complain about gaps that are after
isize.  This makes lowmem pass with my fixes applied, and still fail
without my fixes.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Josef Bacik 2020-02-04 09:32:41 -05:00 committed by David Sterba
parent 9123fc6142
commit f2832d534b
1 changed files with 10 additions and 4 deletions

View File

@ -2028,7 +2028,8 @@ static int check_file_extent_inline(struct btrfs_root *root,
* Return 0 if no error occurred.
*/
static int check_file_extent(struct btrfs_root *root, struct btrfs_path *path,
unsigned int nodatasum, u64 *size, u64 *end)
unsigned int nodatasum, u64 isize, u64 *size,
u64 *end)
{
struct btrfs_file_extent_item *fi;
struct btrfs_key fkey;
@ -2151,7 +2152,7 @@ static int check_file_extent(struct btrfs_root *root, struct btrfs_path *path,
}
/* Check EXTENT_DATA hole */
if (!no_holes && *end != fkey.offset) {
if (!no_holes && (fkey.offset < isize) && (*end != fkey.offset)) {
if (repair)
ret = punch_extent_hole(root, path, fkey.objectid,
*end, fkey.offset - *end);
@ -2164,7 +2165,12 @@ static int check_file_extent(struct btrfs_root *root, struct btrfs_path *path,
}
}
*end = fkey.offset + extent_num_bytes;
/*
* Don't update extent end beyond rounded up isize. As holes
* after isize is not considered as missing holes.
*/
*end = min(round_up(isize, root->fs_info->sectorsize),
fkey.offset + extent_num_bytes);
if (!is_hole)
*size += extent_num_bytes;
@ -2725,7 +2731,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path)
root->objectid, inode_id, key.objectid,
key.offset);
}
ret = check_file_extent(root, path, nodatasum,
ret = check_file_extent(root, path, nodatasum, isize,
&extent_size, &extent_end);
err |= ret;
break;