diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2018-01-20 04:30:10 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-04-02 04:12:38 -0400 |
commit | 5359a17d2706b86da2af83027343d5eb256f7670 (patch) | |
tree | 31053fe22a0d91b40911882b2aaa961e77504d4b /include/linux/ceph | |
parent | a1fbb5e7bbb56fccdf54bf4ab5086c6080ee5bfa (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.h | 59 | ||||
-rw-r--r-- | include/linux/ceph/osd_client.h | 11 |
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 | |||
98 | struct 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 | |||
96 | struct ceph_msg_data { | 142 | struct 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, | |||
290 | extern void ceph_msg_data_add_pagelist(struct ceph_msg *msg, | 333 | extern 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 |
293 | extern void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio, | 336 | void 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 | ||
297 | extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, | 340 | extern 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 |
408 | extern void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *, | 408 | void 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 | ||
413 | extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *, | 414 | extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *, |