aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ceph
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2018-01-20 04:30:10 -0500
committerIlya Dryomov <idryomov@gmail.com>2018-04-02 04:12:38 -0400
commit5359a17d2706b86da2af83027343d5eb256f7670 (patch)
tree31053fe22a0d91b40911882b2aaa961e77504d4b /include/linux/ceph
parenta1fbb5e7bbb56fccdf54bf4ab5086c6080ee5bfa (diff)
libceph, rbd: new bio handling code (aka don't clone bios)
The reason we clone bios is to be able to give each object request (and consequently each ceph_osd_data/ceph_msg_data item) its own pointer to a (list of) bio(s). The messenger then initializes its cursor with cloned bio's ->bi_iter, so it knows where to start reading from/writing to. That's all the cloned bios are used for: to determine each object request's starting position in the provided data buffer. Introduce ceph_bio_iter to do exactly that -- store position within bio list (i.e. pointer to bio) + position within that bio (i.e. bvec_iter). Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'include/linux/ceph')
-rw-r--r--include/linux/ceph/messenger.h59
-rw-r--r--include/linux/ceph/osd_client.h11
2 files changed, 57 insertions, 13 deletions
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
index ead9d85f1c11..d7b9605fd51d 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -93,14 +93,60 @@ static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type)
93 } 93 }
94} 94}
95 95
96#ifdef CONFIG_BLOCK
97
98struct ceph_bio_iter {
99 struct bio *bio;
100 struct bvec_iter iter;
101};
102
103#define __ceph_bio_iter_advance_step(it, n, STEP) do { \
104 unsigned int __n = (n), __cur_n; \
105 \
106 while (__n) { \
107 BUG_ON(!(it)->iter.bi_size); \
108 __cur_n = min((it)->iter.bi_size, __n); \
109 (void)(STEP); \
110 bio_advance_iter((it)->bio, &(it)->iter, __cur_n); \
111 if (!(it)->iter.bi_size && (it)->bio->bi_next) { \
112 dout("__ceph_bio_iter_advance_step next bio\n"); \
113 (it)->bio = (it)->bio->bi_next; \
114 (it)->iter = (it)->bio->bi_iter; \
115 } \
116 __n -= __cur_n; \
117 } \
118} while (0)
119
120/*
121 * Advance @it by @n bytes.
122 */
123#define ceph_bio_iter_advance(it, n) \
124 __ceph_bio_iter_advance_step(it, n, 0)
125
126/*
127 * Advance @it by @n bytes, executing BVEC_STEP for each bio_vec.
128 */
129#define ceph_bio_iter_advance_step(it, n, BVEC_STEP) \
130 __ceph_bio_iter_advance_step(it, n, ({ \
131 struct bio_vec bv; \
132 struct bvec_iter __cur_iter; \
133 \
134 __cur_iter = (it)->iter; \
135 __cur_iter.bi_size = __cur_n; \
136 __bio_for_each_segment(bv, (it)->bio, __cur_iter, __cur_iter) \
137 (void)(BVEC_STEP); \
138 }))
139
140#endif /* CONFIG_BLOCK */
141
96struct ceph_msg_data { 142struct ceph_msg_data {
97 struct list_head links; /* ceph_msg->data */ 143 struct list_head links; /* ceph_msg->data */
98 enum ceph_msg_data_type type; 144 enum ceph_msg_data_type type;
99 union { 145 union {
100#ifdef CONFIG_BLOCK 146#ifdef CONFIG_BLOCK
101 struct { 147 struct {
102 struct bio *bio; 148 struct ceph_bio_iter bio_pos;
103 size_t bio_length; 149 u32 bio_length;
104 }; 150 };
105#endif /* CONFIG_BLOCK */ 151#endif /* CONFIG_BLOCK */
106 struct { 152 struct {
@@ -122,10 +168,7 @@ struct ceph_msg_data_cursor {
122 bool need_crc; /* crc update needed */ 168 bool need_crc; /* crc update needed */
123 union { 169 union {
124#ifdef CONFIG_BLOCK 170#ifdef CONFIG_BLOCK
125 struct { /* bio */ 171 struct ceph_bio_iter bio_iter;
126 struct bio *bio; /* bio from list */
127 struct bvec_iter bvec_iter;
128 };
129#endif /* CONFIG_BLOCK */ 172#endif /* CONFIG_BLOCK */
130 struct { /* pages */ 173 struct { /* pages */
131 unsigned int page_offset; /* offset in page */ 174 unsigned int page_offset; /* offset in page */
@@ -290,8 +333,8 @@ extern void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
290extern void ceph_msg_data_add_pagelist(struct ceph_msg *msg, 333extern void ceph_msg_data_add_pagelist(struct ceph_msg *msg,
291 struct ceph_pagelist *pagelist); 334 struct ceph_pagelist *pagelist);
292#ifdef CONFIG_BLOCK 335#ifdef CONFIG_BLOCK
293extern void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio, 336void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos,
294 size_t length); 337 u32 length);
295#endif /* CONFIG_BLOCK */ 338#endif /* CONFIG_BLOCK */
296 339
297extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, 340extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 52fb37d1c2a5..315691490cb0 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -72,8 +72,8 @@ struct ceph_osd_data {
72 struct ceph_pagelist *pagelist; 72 struct ceph_pagelist *pagelist;
73#ifdef CONFIG_BLOCK 73#ifdef CONFIG_BLOCK
74 struct { 74 struct {
75 struct bio *bio; /* list of bios */ 75 struct ceph_bio_iter bio_pos;
76 size_t bio_length; /* total in list */ 76 u32 bio_length;
77 }; 77 };
78#endif /* CONFIG_BLOCK */ 78#endif /* CONFIG_BLOCK */
79 }; 79 };
@@ -405,9 +405,10 @@ extern void osd_req_op_extent_osd_data_pagelist(struct ceph_osd_request *,
405 unsigned int which, 405 unsigned int which,
406 struct ceph_pagelist *pagelist); 406 struct ceph_pagelist *pagelist);
407#ifdef CONFIG_BLOCK 407#ifdef CONFIG_BLOCK
408extern void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *, 408void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req,
409 unsigned int which, 409 unsigned int which,
410 struct bio *bio, size_t bio_length); 410 struct ceph_bio_iter *bio_pos,
411 u32 bio_length);
411#endif /* CONFIG_BLOCK */ 412#endif /* CONFIG_BLOCK */
412 413
413extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *, 414extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *,