]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commit
btrfs: refactor btrfs_lookup_bio_sums to handle out-of-order bvecs
authorQu Wenruo <wqu@suse.com>
Wed, 2 Dec 2020 06:48:06 +0000 (14:48 +0800)
committerDavid Sterba <dsterba@suse.com>
Wed, 9 Dec 2020 18:16:11 +0000 (19:16 +0100)
commit6275193ef19033d0cca88df6209556462bbedee2
treef640b545c28bc18becc080f79a5fa781e0e0b41a
parent9e46458a7c0056dad98f0684c71be65a380b067b
btrfs: refactor btrfs_lookup_bio_sums to handle out-of-order bvecs

Refactor btrfs_lookup_bio_sums() by:

- Remove the @file_offset parameter
  There are two factors making the @file_offset parameter useless:

  * For csum lookup in csum tree, file offset makes no sense
    We only need disk_bytenr, which is unrelated to file_offset

  * page_offset (file offset) of each bvec is not contiguous.
    Pages can be added to the same bio as long as their on-disk bytenr
    is contiguous, meaning we could have pages at different file offsets
    in the same bio.

  Thus passing file_offset makes no sense any more.
  The only user of file_offset is for data reloc inode, we will use
  a new function, search_file_offset_in_bio(), to handle it.

- Extract the csum tree lookup into search_csum_tree()
  The new function will handle the csum search in csum tree.
  The return value is the same as btrfs_find_ordered_sum(), returning
  the number of found sectors which have checksum.

- Change how we do the main loop
  The only needed info from bio is:
  * the on-disk bytenr
  * the length

  After extracting the above info, we can do the search without bio
  at all, which makes the main loop much simpler:

for (cur_disk_bytenr = orig_disk_bytenr;
     cur_disk_bytenr < orig_disk_bytenr + orig_len;
     cur_disk_bytenr += count * sectorsize) {

/* Lookup csum tree */
count = search_csum_tree(fs_info, path, cur_disk_bytenr,
 search_len, csum_dst);
if (!count) {
/* Csum hole handling */
}
}

- Use single variable as the source to calculate all other offsets
  Instead of all different type of variables, we use only one main
  variable, cur_disk_bytenr, which represents the current disk bytenr.

  All involved values can be calculated from that variable, and
  all those variable will only be visible in the inner loop.

The above refactoring makes btrfs_lookup_bio_sums() way more robust than
it used to be, especially related to the file offset lookup.  Now
file_offset lookup is only related to data reloc inode, otherwise we
don't need to bother file_offset at all.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/compression.c
fs/btrfs/ctree.h
fs/btrfs/file-item.c
fs/btrfs/inode.c