summaryrefslogtreecommitdiff
path: root/libbcache/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'libbcache/util.h')
-rw-r--r--libbcache/util.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/libbcache/util.h b/libbcache/util.h
index 2b171a1..88cbe30 100644
--- a/libbcache/util.h
+++ b/libbcache/util.h
@@ -1,6 +1,7 @@
#ifndef _BCACHE_UTIL_H
#define _BCACHE_UTIL_H
+#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/blkdev.h>
@@ -722,4 +723,33 @@ static inline void memmove_u64s(void *dst, const void *src,
__memmove_u64s_up(dst, src, u64s);
}
+static inline struct bio_vec next_contig_bvec(struct bio *bio,
+ struct bvec_iter *iter)
+{
+ struct bio_vec bv = bio_iter_iovec(bio, *iter);
+
+ bio_advance_iter(bio, iter, bv.bv_len);
+#ifndef CONFIG_HIGHMEM
+ while (iter->bi_size) {
+ struct bio_vec next = bio_iter_iovec(bio, *iter);
+
+ if (page_address(bv.bv_page) + bv.bv_offset + bv.bv_len !=
+ page_address(next.bv_page) + next.bv_offset)
+ break;
+
+ bv.bv_len += next.bv_len;
+ bio_advance_iter(bio, iter, next.bv_len);
+ }
+#endif
+ return bv;
+}
+
+#define __bio_for_each_contig_segment(bv, bio, iter, start) \
+ for (iter = (start); \
+ (iter).bi_size && \
+ ((bv = next_contig_bvec((bio), &(iter))), 1);)
+
+#define bio_for_each_contig_segment(bv, bio, iter) \
+ __bio_for_each_contig_segment(bv, bio, iter, (bio)->bi_iter)
+
#endif /* _BCACHE_UTIL_H */