On 12/28/22 21:51, Sam Winchenbach wrote:
Hello,

Hello, I have hit the following situation when trying to load files from a 
BTRFS partition with duplication enabled.

In the first example I read a 16KiB file - __btrfs_map_block() changes the 
length to something larger than the file being read. This works fine, as length 
is later clamped to the file size.

In the second example, __btrfs_map_block() changes the length parameter to 
something smaller than the file (the size of a stripe).  This seems to break 
this check here:

     read = len;
     num_copies = btrfs_num_copies(fs_info, logical, len);
     for (i = 1; i <= num_copies; i++) {
         ret = read_extent_data(fs_info, dest, logical, &read, i);
         if (ret < 0 || read != len) {
             continue;
         }
         finished = true;
         break;
     }

The problem being that read is always less than len.

I am not sure if __btrfs_map_block is changing "len" to the incorrect value, or if there 
is some logic in "read_extent_data" that isn't correct. Any pointers on how this code is 
supposed to work would be greatly appreciated.
Thanks.

Thanks for reporting the issue

$ scripts/get_maintainer.pl -f fs/btrfs/volumes.c

suggests to include

"Marek BehĂșn" <ka...@kernel.org> (maintainer:BTRFS)
Qu Wenruo <w...@suse.com> (reviewer:BTRFS)
linux-bt...@vger.kernel.org

to the communication.

Best regards

Heinrich


=== EXAMPLE 2 ===
Zynq> load mmc 1:0 0 16K
[btrfs_file_read,fs/btrfs/inode.c:710] === read the aligned part ===
[btrfs_read_extent_reg,fs/btrfs/inode.c:458] before read_extent_data (ret = 0, 
read = 16384, len = 16384)
[read_extent_data,fs/btrfs/disk-io.c:547] before __btrfs_map_block (len = 16384)
[read_extent_data,fs/btrfs/disk-io.c:550] after __btrfs_map_block (len = 28672)
[read_extent_data,fs/btrfs/disk-io.c:565] before __btrfs_devread (len = 16384)
[read_extent_data,fs/btrfs/disk-io.c:568] after __btrfs_devread (len = 16384)
[btrfs_read_extent_reg,fs/btrfs/inode.c:460] after read_extent_data (ret = 0, 
read = 16384, len = 16384)
cur: 0, extent_num_bytes: 16384, aligned_end: 16384
16384 bytes read in 100 ms (159.2 KiB/s)

=== EXAMPLE 2 ===
Zynq> load mmc 1:0 0 32K
[btrfs_file_read,fs/btrfs/inode.c:710] === read the aligned part ===
[btrfs_read_extent_reg,fs/btrfs/inode.c:458] before read_extent_data (ret = 0, 
read = 32768, len = 32768)
[read_extent_data,fs/btrfs/disk-io.c:547] before __btrfs_map_block (len = 32768)
[read_extent_data,fs/btrfs/disk-io.c:550] after __btrfs_map_block (len = 12288)
[read_extent_data,fs/btrfs/disk-io.c:565] before __btrfs_devread (len = 12288)
[read_extent_data,fs/btrfs/disk-io.c:568] after __btrfs_devread (len = 12288)
[btrfs_read_extent_reg,fs/btrfs/inode.c:460] after read_extent_data (ret = 0, 
read = 12288, len = 32768)
[btrfs_read_extent_reg,fs/btrfs/inode.c:458] before read_extent_data (ret = 0, 
read = 12288, len = 32768)
[read_extent_data,fs/btrfs/disk-io.c:547] before __btrfs_map_block (len = 12288)
[read_extent_data,fs/btrfs/disk-io.c:550] after __btrfs_map_block (len = 12288)
[read_extent_data,fs/btrfs/disk-io.c:565] before __btrfs_devread (len = 12288)
[read_extent_data,fs/btrfs/disk-io.c:568] after __btrfs_devread (len = 12288)
[btrfs_read_extent_reg,fs/btrfs/inode.c:460] after read_extent_data (ret = 0, 
read = 12288, len = 32768)
file: fs/btrfs/inode.c, line: 468
cur: 0, extent_num_bytes: 32768, aligned_end: 32768
-----> btrfs_read_extent_reg: -5, line: 758
BTRFS: An error occurred while reading file 32K
Failed to load '32K'





Sam Winchenbach
Embedded Software Engineer III
Tethers Unlimited, Inc. | Connect Your Universe | www.tethers.com
swinchenb...@tethers.com | C: 207-974-6934
11711 North Creek Pkwy # D113, Bothell, WA 98011-8808, USA

Reply via email to