summaryrefslogtreecommitdiff
path: root/include/linux/bvec.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/bvec.h')
-rw-r--r--include/linux/bvec.h56
1 files changed, 33 insertions, 23 deletions
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index ba8f52d48b94..d36dd476feda 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -22,11 +22,8 @@ struct page;
* @bv_len: Number of bytes in the address range.
* @bv_offset: Start of the address range relative to the start of @bv_page.
*
- * The following holds for a bvec if n * PAGE_SIZE < bv_offset + bv_len:
- *
- * nth_page(@bv_page, n) == @bv_page + n
- *
- * This holds because page_is_mergeable() checks the above property.
+ * All pages within a bio_vec starting from @bv_page are contiguous and
+ * can simply be iterated (see bvec_advance()).
*/
struct bio_vec {
struct page *bv_page;
@@ -57,9 +54,12 @@ static inline void bvec_set_page(struct bio_vec *bv, struct page *page,
* @offset: offset into the folio
*/
static inline void bvec_set_folio(struct bio_vec *bv, struct folio *folio,
- unsigned int len, unsigned int offset)
+ size_t len, size_t offset)
{
- bvec_set_page(bv, &folio->page, len, offset);
+ unsigned long nr = offset / PAGE_SIZE;
+
+ WARN_ON_ONCE(len > UINT_MAX);
+ bvec_set_page(bv, folio_page(folio, nr), len, offset % PAGE_SIZE);
}
/**
@@ -75,14 +75,27 @@ static inline void bvec_set_virt(struct bio_vec *bv, void *vaddr,
}
struct bvec_iter {
- sector_t bi_sector; /* device address in 512 byte
- sectors */
- unsigned int bi_size; /* residual I/O count */
-
- unsigned int bi_idx; /* current index into bvl_vec */
-
- unsigned int bi_bvec_done; /* number of bytes completed in
- current bvec */
+ /*
+ * Current device address in 512 byte sectors. Only updated by the bio
+ * iter wrappers and not the bvec iterator helpers themselves.
+ */
+ sector_t bi_sector;
+
+ /*
+ * Remaining size in bytes.
+ */
+ unsigned int bi_size;
+
+ /*
+ * Current index into the bvec array. This indexes into `bi_io_vec` when
+ * iterating a bvec array that is part of a `bio`.
+ */
+ unsigned int bi_idx;
+
+ /*
+ * Current offset in the bvec entry pointed to by `bi_idx`.
+ */
+ unsigned int bi_bvec_done;
} __packed __aligned(4);
struct bvec_iter_all {
@@ -184,14 +197,11 @@ static inline void bvec_iter_advance_single(const struct bio_vec *bv,
((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \
bvec_iter_advance_single((bio_vec), &(iter), (bvl).bv_len))
-/* for iterating one bio from start to end */
-#define BVEC_ITER_ALL_INIT (struct bvec_iter) \
-{ \
- .bi_sector = 0, \
- .bi_size = UINT_MAX, \
- .bi_idx = 0, \
- .bi_bvec_done = 0, \
-}
+#define for_each_mp_bvec(bvl, bio_vec, iter, start) \
+ for (iter = (start); \
+ (iter).bi_size && \
+ ((bvl = mp_bvec_iter_bvec((bio_vec), (iter))), 1); \
+ bvec_iter_advance_single((bio_vec), &(iter), (bvl).bv_len))
static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all)
{