[PATCH U-BOOT 1/3] btrfs: fix offset within btrfs_read_extent_reg()
Qu Wenruo
quwenruo.btrfs at gmx.com
Tue Apr 18 04:20:45 CEST 2023
On 2023/4/18 10:05, Dominique Martinet wrote:
> Qu Wenruo wrote on Tue, Apr 18, 2023 at 09:58:37AM +0800:
>> The subject can be changed to "btrfs: fix offset when reading compressed
>> extents".
>> The original one is a little too generic.
>
> Ok.
>
>>> btrfs_file_read()
>>> -> btrfs_read_extent_reg
>>> (aligned part loop from 0x40480000 to 0x40ba0000, 128KB at a time)
>>> last read had 0x4000 bytes in extent, but aligned_end - cur limited
>>> the read to 0x3000 (offset 0x720000)
>>> -> read_and_truncate_page
>>> -> btrfs_read_extent_reg
>>> reading the last 0x1000 bytes from offset 0x73000 (end of the
>>> previous 0x4000) into 0x40ba3000
>>> here key.offset = 0x70000 so we need to use it to recover the
>>> 0x3000 offset.
>>
>> You can use "btrfs ins dump-tree" to provide a much easier to read on-disk
>> data layout.
>
> key.offset is the offset within the read call, not the offset on disk.
> The file on disk looks perfectly normal, the condition to trigger the
> bug is to have a file which size is not sector-aligned and where the
> last extent is bigger than a sector.
Forgot to mention, this bug does not only affect the mentioned case, it
affects all partial read of an extent.
Even if it's sector aligned.
>
> I had a look at dump-tree early on and couldn't actually find my file in
> there, now the problem is understood it should be easy to make a
> reproducer so I'll add this info and commands needed to reproduce (+ a
> link to a fs image just in case) in v2
>
>>> /* Preallocated or hole , fill @dest with zero */
>>> if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_PREALLOC ||
>>> @@ -454,9 +456,7 @@ int btrfs_read_extent_reg(struct btrfs_path *path,
>>> if (btrfs_file_extent_compression(leaf, fi) == BTRFS_COMPRESS_NONE) {
>>> u64 logical;
>>> - logical = btrfs_file_extent_disk_bytenr(leaf, fi) +
>>> - btrfs_file_extent_offset(leaf, fi) +
>>> - offset - key.offset;
>>> + logical = btrfs_file_extent_disk_bytenr(leaf, fi) + offset;
>>
>> This is touching non-compressed path, which is very weird as your commit
>> message said this part is correct.
>
> my rationale is that since this was considered once but forgotten the
> other time it'll be easy to add yet another code path that forgets it
> later, but I guess it won't change much anyway -- I'll fix the patch
> making it explicit again.
>
>
> Thanks,
More information about the U-Boot
mailing list