block: introduce mp_bvec_last_segment()

BTRFS and guard_bio_eod() need to get the last singlepage segment
from one multipage bvec, so introduce this helper to make them happy.

Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Ming Lei 2019-02-15 19:13:14 +08:00 committed by Jens Axboe
parent 862e5a5e6f
commit 45a3fb9529

View File

@ -131,4 +131,26 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv,
.bi_bvec_done = 0, \
}
/*
* Get the last single-page segment from the multi-page bvec and store it
* in @seg
*/
static inline void mp_bvec_last_segment(const struct bio_vec *bvec,
struct bio_vec *seg)
{
unsigned total = bvec->bv_offset + bvec->bv_len;
unsigned last_page = (total - 1) / PAGE_SIZE;
seg->bv_page = nth_page(bvec->bv_page, last_page);
/* the whole segment is inside the last page */
if (bvec->bv_offset >= last_page * PAGE_SIZE) {
seg->bv_offset = bvec->bv_offset % PAGE_SIZE;
seg->bv_len = bvec->bv_len;
} else {
seg->bv_offset = 0;
seg->bv_len = total - last_page * PAGE_SIZE;
}
}
#endif /* __LINUX_BVEC_ITER_H */