btrfs: simplify splitting logic in btrfs_extract_ordered_extent
authorChristoph Hellwig <hch@lst.de>
Tue, 28 Mar 2023 05:19:51 +0000 (14:19 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 17 Apr 2023 16:01:21 +0000 (18:01 +0200)
btrfs_extract_ordered_extent is always used to split an ordered_extent
and extent_map into two parts, so it doesn't need to deal with a three
way split.

Simplify it by only allowing for a single split point, and always split
out the beginning of the extent, as that is what we'll later need to
be able to hold on to a reference to the original ordered_extent that
the first part is split off for submission.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Tested-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index bd6749e..757706d 100644 (file)
@@ -2632,39 +2632,36 @@ blk_status_t btrfs_extract_ordered_extent(struct btrfs_bio *bbio)
        u64 len = bbio->bio.bi_iter.bi_size;
        struct btrfs_inode *inode = bbio->inode;
        struct btrfs_ordered_extent *ordered;
-       u64 file_len;
-       u64 end = start + len;
-       u64 ordered_end;
-       u64 pre, post;
+       u64 ordered_len;
        int ret = 0;
 
        ordered = btrfs_lookup_ordered_extent(inode, bbio->file_offset);
        if (WARN_ON_ONCE(!ordered))
                return BLK_STS_IOERR;
+       ordered_len = ordered->num_bytes;
 
-       /* No need to split */
-       if (ordered->disk_num_bytes == len)
+       /* Must always be called for the beginning of an ordered extent. */
+       if (WARN_ON_ONCE(start != ordered->disk_bytenr)) {
+               ret = -EINVAL;
                goto out;
+       }
 
-       ordered_end = ordered->disk_bytenr + ordered->disk_num_bytes;
-       /* bio must be in one ordered extent */
-       if (WARN_ON_ONCE(start < ordered->disk_bytenr || end > ordered_end)) {
+       /* The bio must be entirely covered by the ordered extent. */
+       if (WARN_ON_ONCE(len > ordered_len)) {
                ret = -EINVAL;
                goto out;
        }
 
-       file_len = ordered->num_bytes;
-       pre = start - ordered->disk_bytenr;
-       post = ordered_end - end;
+       /* No need to split if the ordered extent covers the entire bio. */
+       if (ordered->disk_num_bytes == len)
+               goto out;
 
-       ret = btrfs_split_ordered_extent(ordered, pre, post);
+       ret = btrfs_split_ordered_extent(ordered, len, 0);
        if (ret)
                goto out;
-       ret = split_zoned_em(inode, bbio->file_offset, file_len, pre, post);
-
+       ret = split_zoned_em(inode, bbio->file_offset, ordered_len, len, 0);
 out:
        btrfs_put_ordered_extent(ordered);
-
        return errno_to_blk_status(ret);
 }