btrfs: factor out helper adding a page to bio
Factor out adding a page to a bio from submit_extent_page(). The page is added only when bio_flags are the same, contiguous and the added page fits in the same stripe as pages in the bio. Condition checks are reordered to allow early return to avoid possibly heavy btrfs_bio_fits_in_stripe() calling. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
dcba6e48b5
Коммит
953651eb30
|
@ -3084,6 +3084,48 @@ struct bio *btrfs_bio_clone_partial(struct bio *orig, int offset, int size)
|
|||
return bio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to add a page to bio
|
||||
*
|
||||
* @bio: destination bio
|
||||
* @page: page to add to the bio
|
||||
* @disk_bytenr: offset of the new bio or to check whether we are adding
|
||||
* a contiguous page to the previous one
|
||||
* @pg_offset: starting offset in the page
|
||||
* @size: portion of page that we want to write
|
||||
* @prev_bio_flags: flags of previous bio to see if we can merge the current one
|
||||
* @bio_flags: flags of the current bio to see if we can merge them
|
||||
* @return: true if page was added, false otherwise
|
||||
*
|
||||
* Attempt to add a page to bio considering stripe alignment etc.
|
||||
*
|
||||
* Return true if successfully page added. Otherwise, return false.
|
||||
*/
|
||||
static bool btrfs_bio_add_page(struct bio *bio, struct page *page,
|
||||
u64 disk_bytenr, unsigned int size,
|
||||
unsigned int pg_offset,
|
||||
unsigned long prev_bio_flags,
|
||||
unsigned long bio_flags)
|
||||
{
|
||||
const sector_t sector = disk_bytenr >> SECTOR_SHIFT;
|
||||
bool contig;
|
||||
|
||||
if (prev_bio_flags != bio_flags)
|
||||
return false;
|
||||
|
||||
if (prev_bio_flags & EXTENT_BIO_COMPRESSED)
|
||||
contig = bio->bi_iter.bi_sector == sector;
|
||||
else
|
||||
contig = bio_end_sector(bio) == sector;
|
||||
if (!contig)
|
||||
return false;
|
||||
|
||||
if (btrfs_bio_fits_in_stripe(page, size, bio, bio_flags))
|
||||
return false;
|
||||
|
||||
return bio_add_page(bio, page, size, pg_offset) == size;
|
||||
}
|
||||
|
||||
/*
|
||||
* @opf: bio REQ_OP_* and REQ_* flags as one value
|
||||
* @wbc: optional writeback control for io accounting
|
||||
|
@ -3112,27 +3154,15 @@ static int submit_extent_page(unsigned int opf,
|
|||
int ret = 0;
|
||||
struct bio *bio;
|
||||
size_t io_size = min_t(size_t, size, PAGE_SIZE);
|
||||
sector_t sector = disk_bytenr >> 9;
|
||||
struct extent_io_tree *tree = &BTRFS_I(page->mapping->host)->io_tree;
|
||||
|
||||
ASSERT(bio_ret);
|
||||
|
||||
if (*bio_ret) {
|
||||
bool contig;
|
||||
bool can_merge = true;
|
||||
|
||||
bio = *bio_ret;
|
||||
if (prev_bio_flags & EXTENT_BIO_COMPRESSED)
|
||||
contig = bio->bi_iter.bi_sector == sector;
|
||||
else
|
||||
contig = bio_end_sector(bio) == sector;
|
||||
|
||||
if (btrfs_bio_fits_in_stripe(page, io_size, bio, bio_flags))
|
||||
can_merge = false;
|
||||
|
||||
if (prev_bio_flags != bio_flags || !contig || !can_merge ||
|
||||
force_bio_submit ||
|
||||
bio_add_page(bio, page, io_size, pg_offset) < io_size) {
|
||||
if (force_bio_submit ||
|
||||
!btrfs_bio_add_page(bio, page, disk_bytenr, io_size,
|
||||
pg_offset, prev_bio_flags, bio_flags)) {
|
||||
ret = submit_one_bio(bio, mirror_num, prev_bio_flags);
|
||||
if (ret < 0) {
|
||||
*bio_ret = NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче