Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 64 additions & 37 deletions include/linux/bvec.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,51 +104,78 @@ struct bvec_iter_all {
unsigned done;
};

/*
* various member access, note that bio_data should of course not be used
* on highmem page vectors
*/
#define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
static __always_inline const struct bio_vec *
__bvec_iter_bvec(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return bvecs + iter.bi_idx;
}

/* multi-page (mp_bvec) helpers */
#define mp_bvec_iter_page(bvec, iter) \
(__bvec_iter_bvec((bvec), (iter))->bv_page)
static __always_inline struct page *
mp_bvec_iter_page(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return __bvec_iter_bvec(bvecs, iter)->bv_page;
}

#define mp_bvec_iter_len(bvec, iter) \
min((iter).bi_size, \
__bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
static __always_inline unsigned int
mp_bvec_iter_len(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return min(__bvec_iter_bvec(bvecs, iter)->bv_len - iter.bi_bvec_done,
iter.bi_size);
}

#define mp_bvec_iter_offset(bvec, iter) \
(__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
static __always_inline unsigned int
mp_bvec_iter_offset(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return __bvec_iter_bvec(bvecs, iter)->bv_offset + iter.bi_bvec_done;
}

#define mp_bvec_iter_page_idx(bvec, iter) \
(mp_bvec_iter_offset((bvec), (iter)) / PAGE_SIZE)
static __always_inline unsigned int
mp_bvec_iter_page_idx(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return mp_bvec_iter_offset(bvecs, iter) / PAGE_SIZE;
}

#define mp_bvec_iter_bvec(bvec, iter) \
((struct bio_vec) { \
.bv_page = mp_bvec_iter_page((bvec), (iter)), \
.bv_len = mp_bvec_iter_len((bvec), (iter)), \
.bv_offset = mp_bvec_iter_offset((bvec), (iter)), \
})
static __always_inline struct bio_vec
mp_bvec_iter_bvec(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return (struct bio_vec) {
.bv_page = mp_bvec_iter_page(bvecs, iter),
.bv_len = mp_bvec_iter_len(bvecs, iter),
.bv_offset = mp_bvec_iter_offset(bvecs, iter),
};
}

/* For building single-page bvec in flight */
#define bvec_iter_offset(bvec, iter) \
(mp_bvec_iter_offset((bvec), (iter)) % PAGE_SIZE)

#define bvec_iter_len(bvec, iter) \
min_t(unsigned, mp_bvec_iter_len((bvec), (iter)), \
PAGE_SIZE - bvec_iter_offset((bvec), (iter)))

#define bvec_iter_page(bvec, iter) \
(mp_bvec_iter_page((bvec), (iter)) + \
mp_bvec_iter_page_idx((bvec), (iter)))

#define bvec_iter_bvec(bvec, iter) \
((struct bio_vec) { \
.bv_page = bvec_iter_page((bvec), (iter)), \
.bv_len = bvec_iter_len((bvec), (iter)), \
.bv_offset = bvec_iter_offset((bvec), (iter)), \
})
static __always_inline unsigned int
bvec_iter_offset(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return mp_bvec_iter_offset(bvecs, iter) % PAGE_SIZE;
}

static __always_inline unsigned int
bvec_iter_len(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return min(mp_bvec_iter_len(bvecs, iter),
PAGE_SIZE - bvec_iter_offset(bvecs, iter));
}

static __always_inline struct page *
bvec_iter_page(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return mp_bvec_iter_page(bvecs, iter) +
mp_bvec_iter_page_idx(bvecs, iter);
}

static __always_inline struct bio_vec
bvec_iter_bvec(const struct bio_vec *bvecs, const struct bvec_iter iter)
{
return (struct bio_vec) {
.bv_page = bvec_iter_page(bvecs, iter),
.bv_len = bvec_iter_len(bvecs, iter),
.bv_offset = bvec_iter_offset(bvecs, iter),
};
}

static inline bool bvec_iter_advance(const struct bio_vec *bv,
struct bvec_iter *iter, unsigned bytes)
Expand Down