0001
0002
0003
0004
0005
0006
0007 #ifndef __LINUX_BVEC_H
0008 #define __LINUX_BVEC_H
0009
0010 #include <linux/highmem.h>
0011 #include <linux/bug.h>
0012 #include <linux/errno.h>
0013 #include <linux/limits.h>
0014 #include <linux/minmax.h>
0015 #include <linux/mm.h>
0016 #include <linux/types.h>
0017
0018 struct page;
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 struct bio_vec {
0033 struct page *bv_page;
0034 unsigned int bv_len;
0035 unsigned int bv_offset;
0036 };
0037
0038 struct bvec_iter {
0039 sector_t bi_sector;
0040
0041 unsigned int bi_size;
0042
0043 unsigned int bi_idx;
0044
0045 unsigned int bi_bvec_done;
0046
0047 } __packed;
0048
0049 struct bvec_iter_all {
0050 struct bio_vec bv;
0051 int idx;
0052 unsigned done;
0053 };
0054
0055
0056
0057
0058
0059 #define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
0060
0061
0062 #define mp_bvec_iter_page(bvec, iter) \
0063 (__bvec_iter_bvec((bvec), (iter))->bv_page)
0064
0065 #define mp_bvec_iter_len(bvec, iter) \
0066 min((iter).bi_size, \
0067 __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
0068
0069 #define mp_bvec_iter_offset(bvec, iter) \
0070 (__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
0071
0072 #define mp_bvec_iter_page_idx(bvec, iter) \
0073 (mp_bvec_iter_offset((bvec), (iter)) / PAGE_SIZE)
0074
0075 #define mp_bvec_iter_bvec(bvec, iter) \
0076 ((struct bio_vec) { \
0077 .bv_page = mp_bvec_iter_page((bvec), (iter)), \
0078 .bv_len = mp_bvec_iter_len((bvec), (iter)), \
0079 .bv_offset = mp_bvec_iter_offset((bvec), (iter)), \
0080 })
0081
0082
0083 #define bvec_iter_offset(bvec, iter) \
0084 (mp_bvec_iter_offset((bvec), (iter)) % PAGE_SIZE)
0085
0086 #define bvec_iter_len(bvec, iter) \
0087 min_t(unsigned, mp_bvec_iter_len((bvec), (iter)), \
0088 PAGE_SIZE - bvec_iter_offset((bvec), (iter)))
0089
0090 #define bvec_iter_page(bvec, iter) \
0091 (mp_bvec_iter_page((bvec), (iter)) + \
0092 mp_bvec_iter_page_idx((bvec), (iter)))
0093
0094 #define bvec_iter_bvec(bvec, iter) \
0095 ((struct bio_vec) { \
0096 .bv_page = bvec_iter_page((bvec), (iter)), \
0097 .bv_len = bvec_iter_len((bvec), (iter)), \
0098 .bv_offset = bvec_iter_offset((bvec), (iter)), \
0099 })
0100
0101 static inline bool bvec_iter_advance(const struct bio_vec *bv,
0102 struct bvec_iter *iter, unsigned bytes)
0103 {
0104 unsigned int idx = iter->bi_idx;
0105
0106 if (WARN_ONCE(bytes > iter->bi_size,
0107 "Attempted to advance past end of bvec iter\n")) {
0108 iter->bi_size = 0;
0109 return false;
0110 }
0111
0112 iter->bi_size -= bytes;
0113 bytes += iter->bi_bvec_done;
0114
0115 while (bytes && bytes >= bv[idx].bv_len) {
0116 bytes -= bv[idx].bv_len;
0117 idx++;
0118 }
0119
0120 iter->bi_idx = idx;
0121 iter->bi_bvec_done = bytes;
0122 return true;
0123 }
0124
0125
0126
0127
0128
0129 static inline void bvec_iter_advance_single(const struct bio_vec *bv,
0130 struct bvec_iter *iter, unsigned int bytes)
0131 {
0132 unsigned int done = iter->bi_bvec_done + bytes;
0133
0134 if (done == bv[iter->bi_idx].bv_len) {
0135 done = 0;
0136 iter->bi_idx++;
0137 }
0138 iter->bi_bvec_done = done;
0139 iter->bi_size -= bytes;
0140 }
0141
0142 #define for_each_bvec(bvl, bio_vec, iter, start) \
0143 for (iter = (start); \
0144 (iter).bi_size && \
0145 ((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \
0146 bvec_iter_advance_single((bio_vec), &(iter), (bvl).bv_len))
0147
0148
0149 #define BVEC_ITER_ALL_INIT (struct bvec_iter) \
0150 { \
0151 .bi_sector = 0, \
0152 .bi_size = UINT_MAX, \
0153 .bi_idx = 0, \
0154 .bi_bvec_done = 0, \
0155 }
0156
0157 static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all)
0158 {
0159 iter_all->done = 0;
0160 iter_all->idx = 0;
0161
0162 return &iter_all->bv;
0163 }
0164
0165 static inline void bvec_advance(const struct bio_vec *bvec,
0166 struct bvec_iter_all *iter_all)
0167 {
0168 struct bio_vec *bv = &iter_all->bv;
0169
0170 if (iter_all->done) {
0171 bv->bv_page++;
0172 bv->bv_offset = 0;
0173 } else {
0174 bv->bv_page = bvec->bv_page + (bvec->bv_offset >> PAGE_SHIFT);
0175 bv->bv_offset = bvec->bv_offset & ~PAGE_MASK;
0176 }
0177 bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset,
0178 bvec->bv_len - iter_all->done);
0179 iter_all->done += bv->bv_len;
0180
0181 if (iter_all->done == bvec->bv_len) {
0182 iter_all->idx++;
0183 iter_all->done = 0;
0184 }
0185 }
0186
0187
0188
0189
0190
0191
0192
0193
0194 static inline void *bvec_kmap_local(struct bio_vec *bvec)
0195 {
0196 return kmap_local_page(bvec->bv_page) + bvec->bv_offset;
0197 }
0198
0199
0200
0201
0202
0203
0204
0205 static inline void memcpy_from_bvec(char *to, struct bio_vec *bvec)
0206 {
0207 memcpy_from_page(to, bvec->bv_page, bvec->bv_offset, bvec->bv_len);
0208 }
0209
0210
0211
0212
0213
0214
0215
0216 static inline void memcpy_to_bvec(struct bio_vec *bvec, const char *from)
0217 {
0218 memcpy_to_page(bvec->bv_page, bvec->bv_offset, from, bvec->bv_len);
0219 }
0220
0221
0222
0223
0224
0225
0226
0227 static inline void memzero_bvec(struct bio_vec *bvec)
0228 {
0229 memzero_page(bvec->bv_page, bvec->bv_offset, bvec->bv_len);
0230 }
0231
0232
0233
0234
0235
0236
0237
0238 static inline void *bvec_virt(struct bio_vec *bvec)
0239 {
0240 WARN_ON_ONCE(PageHighMem(bvec->bv_page));
0241 return page_address(bvec->bv_page) + bvec->bv_offset;
0242 }
0243
0244 #endif