mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-16 14:08:45 +00:00
btrfs: fix offset when reading compressed extents
btrfs_read_extent_reg correctly computed the extent offset in the BTRFS_COMPRESS_NONE case, but did not account for the 'offset - key.offset' part correctly in the compressed case, making the function read incorrect data. In the case I examined, the last 4k of a file was corrupted and contained data from a few blocks prior, e.g. reading a 10k file with a single extent: btrfs_file_read() -> btrfs_read_extent_reg (aligned part loop, until 8k) -> read_and_truncate_page -> btrfs_read_extent_reg (re-reads the last extent from 8k to the end, incorrectly reading the first 2k of data) This can be reproduced as follow: $ truncate -s 200M btr $ mount btr -o compress /mnt $ pat() { dd if=/dev/zero bs=1M count=$1 iflag=count_bytes status=none | tr '\0' "\\$2"; } $ { pat 4K 1; pat 4K 2; pat 2K 3; } > /mnt/file $ sync $ filefrag -v /mnt/file File size of /mnt/file is 10240 (3 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 2: 3328.. 3330: 3: last,encoded,eof $ umount /mnt Then in u-boot: => load scsi 0 2000000 file 10240 bytes read in 3 ms (3.3 MiB/s) => md 2001ff0 02001ff0: 02020202 02020202 02020202 02020202 ................ 02002000: 01010101 01010101 01010101 01010101 ................ 02002010: 01010101 01010101 01010101 01010101 ................ (02002000 onwards should contain '03' pattern but went back to 01, start of the extent) After patch, data is read properly: => md 2001ff0 02001ff0: 02020202 02020202 02020202 02020202 ................ 02002000: 03030303 03030303 03030303 03030303 ................ 02002010: 03030303 03030303 03030303 03030303 ................ Note that the code previously (before commite3427184f3
("fs: btrfs: Implement btrfs_file_read()")) did not split that read in two, so this is a regression even if the previous code might not have been handling offsets correctly either (something that booted now fails to boot) Fixes:a26a6bedaf
("fs: btrfs: Introduce btrfs_read_extent_inline() and btrfs_read_extent_reg()") Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com> Reviewed-by: Qu Wenruo <wqu@suse.com>
This commit is contained in:
parent
fbfe7fb5ae
commit
b1d3013d02
1 changed files with 3 additions and 1 deletions
|
@ -511,7 +511,9 @@ int btrfs_read_extent_reg(struct btrfs_path *path,
|
||||||
if (ret < dsize)
|
if (ret < dsize)
|
||||||
memset(dbuf + ret, 0, dsize - ret);
|
memset(dbuf + ret, 0, dsize - ret);
|
||||||
/* Then copy the needed part */
|
/* Then copy the needed part */
|
||||||
memcpy(dest, dbuf + btrfs_file_extent_offset(leaf, fi), len);
|
memcpy(dest,
|
||||||
|
dbuf + btrfs_file_extent_offset(leaf, fi) + offset - key.offset,
|
||||||
|
len);
|
||||||
ret = len;
|
ret = len;
|
||||||
out:
|
out:
|
||||||
free(cbuf);
|
free(cbuf);
|
||||||
|
|
Loading…
Add table
Reference in a new issue