]> git.baikalelectronics.ru Git - kernel.git/commit
btrfs: subpage: allow submit_extent_page() to do bio split
authorQu Wenruo <wqu@suse.com>
Mon, 26 Jul 2021 06:35:00 +0000 (14:35 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Aug 2021 11:19:05 +0000 (13:19 +0200)
commit1b2e0a24b216d3701a84aca5854014c4bf446670
tree3b7d7945f9aecb3e998d8013aa055606d4014d6a
parent773785519ae889beb1332b29537a9dbd1bdb8bae
btrfs: subpage: allow submit_extent_page() to do bio split

Current submit_extent_page() just checks if the current page range can
be fitted into current bio, and if not, submit then re-add.

But this behavior can't handle subpage case at all.

For subpage case, the problem is in the page size, 64K, which is also
the same size as stripe size.

This means, if we can't fit a full 64K into a bio, due to stripe limit,
then it won't fit into next bio without crossing stripe either.

The proper way to handle it is:

- Check how many bytes we can be put into current bio
- Put as many bytes as possible into current bio first
- Submit current bio
- Create a new bio
- Add the remaining bytes into the new bio

Refactor submit_extent_page() so that it does the above iteration.

The main loop inside submit_extent_page() will look like this:

cur = pg_offset;
while (cur < pg_offset + size) {
u32 offset = cur - pg_offset;
int added;
if (!bio_ctrl->bio) {
/* Allocate new bio if needed */
}

/* Add as many bytes into the bio */
added = btrfs_bio_add_page();

if (added < size - offset) {
/* The current bio is full, submit it */
}
cur += added;
}

Also, since we're doing new bio allocation deep inside the main loop,
extract that code into a new helper, alloc_new_bio().

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_io.c