btrfs-progs: check: lowmem, fix path leak when dev extents are invalid

[BUG]
When testing my new RAID56J code, there is a bug causing dev extents
overlapping.

Although both modes can detect the problem, lowmem has leaked some
extent buffers:

  $ btrfs check --mode=lowmem /dev/test/scratch1
  Opening filesystem to check...
  Checking filesystem on /dev/test/scratch1
  UUID: 65775ce9-bb9d-4f61-a210-beea52eef090
  [1/7] checking root items
  [2/7] checking extents
  ERROR: dev extent devid 1 offset 1095761920 len 1073741824 overlap with previous dev extent end 1096810496
  ERROR: dev extent devid 2 offset 1351614464 len 1073741824 overlap with previous dev extent end 1352663040
  ERROR: dev extent devid 3 offset 1351614464 len 1073741824 overlap with previous dev extent end 1352663040
  ERROR: errors found in extent allocation tree or chunk allocation
  [3/7] checking free space tree
  [4/7] checking fs roots
  [5/7] checking only csums items (without verifying data)
  [6/7] checking root refs done with fs roots in lowmem mode, skipping
  [7/7] checking quota groups skipped (not enabled on this FS)
  found 3221372928 bytes used, error(s) found
  total csum bytes: 0
  total tree bytes: 147456
  total fs tree bytes: 32768
  total extent tree bytes: 16384
  btree space waste bytes: 136231
  file data blocks allocated: 3221225472
   referenced 3221225472
  extent buffer leak: start 30752768 len 16384
  extent buffer leak: start 30752768 len 16384
  extent buffer leak: start 30752768 len 16384

[CAUSE]
In the function check_dev_item(), we iterate through all the dev
extents, but when we found overlapping extents, we exit without
releasing the path, causing extent buffer leakage.

[FIX]
Just release the path before we exit the function.

Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2022-05-15 18:55:00 +08:00 committed by David Sterba
parent 1c70e888da
commit 23c6d24668
1 changed files with 2 additions and 0 deletions

View File

@ -4558,6 +4558,7 @@ static int check_dev_item(struct extent_buffer *eb, int slot,
"dev extent devid %llu offset %llu len %llu overlap with previous dev extent end %llu",
devid, physical_offset, physical_len,
prev_dev_ext_end);
btrfs_release_path(&path);
return ACCOUNTING_MISMATCH;
}
if (physical_offset + physical_len > total_bytes) {
@ -4565,6 +4566,7 @@ static int check_dev_item(struct extent_buffer *eb, int slot,
"dev extent devid %llu offset %llu len %llu is beyond device boundary %llu",
devid, physical_offset, physical_len,
total_bytes);
btrfs_release_path(&path);
return ACCOUNTING_MISMATCH;
}
prev_devid = devid;