diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2018-01-20 04:30:11 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-04-02 04:12:39 -0400 |
commit | b9e281c2b38804984d619e1d9efc4b9020bcb291 (patch) | |
tree | f60492d187e96375c3212679d4ca4a9ad3bcf146 /net | |
parent | f9dcbc44cd317ee3c5e443db7f9a62f52689f08e (diff) |
libceph: introduce BVECS data type
In preparation for rbd "fancy" striping, introduce ceph_bvec_iter for
working with bio_vec array data buffers. The wrappers are trivial, but
make it look similar to ceph_bio_iter.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/messenger.c | 75 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 39 |
2 files changed, 114 insertions, 0 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index b9fa8b869c08..91a57857cf11 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -894,6 +894,58 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, | |||
894 | } | 894 | } |
895 | #endif /* CONFIG_BLOCK */ | 895 | #endif /* CONFIG_BLOCK */ |
896 | 896 | ||
897 | static void ceph_msg_data_bvecs_cursor_init(struct ceph_msg_data_cursor *cursor, | ||
898 | size_t length) | ||
899 | { | ||
900 | struct ceph_msg_data *data = cursor->data; | ||
901 | struct bio_vec *bvecs = data->bvec_pos.bvecs; | ||
902 | |||
903 | cursor->resid = min_t(size_t, length, data->bvec_pos.iter.bi_size); | ||
904 | cursor->bvec_iter = data->bvec_pos.iter; | ||
905 | cursor->bvec_iter.bi_size = cursor->resid; | ||
906 | |||
907 | BUG_ON(cursor->resid < bvec_iter_len(bvecs, cursor->bvec_iter)); | ||
908 | cursor->last_piece = | ||
909 | cursor->resid == bvec_iter_len(bvecs, cursor->bvec_iter); | ||
910 | } | ||
911 | |||
912 | static struct page *ceph_msg_data_bvecs_next(struct ceph_msg_data_cursor *cursor, | ||
913 | size_t *page_offset, | ||
914 | size_t *length) | ||
915 | { | ||
916 | struct bio_vec bv = bvec_iter_bvec(cursor->data->bvec_pos.bvecs, | ||
917 | cursor->bvec_iter); | ||
918 | |||
919 | *page_offset = bv.bv_offset; | ||
920 | *length = bv.bv_len; | ||
921 | return bv.bv_page; | ||
922 | } | ||
923 | |||
924 | static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, | ||
925 | size_t bytes) | ||
926 | { | ||
927 | struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs; | ||
928 | |||
929 | BUG_ON(bytes > cursor->resid); | ||
930 | BUG_ON(bytes > bvec_iter_len(bvecs, cursor->bvec_iter)); | ||
931 | cursor->resid -= bytes; | ||
932 | bvec_iter_advance(bvecs, &cursor->bvec_iter, bytes); | ||
933 | |||
934 | if (!cursor->resid) { | ||
935 | BUG_ON(!cursor->last_piece); | ||
936 | return false; /* no more data */ | ||
937 | } | ||
938 | |||
939 | if (!bytes || cursor->bvec_iter.bi_bvec_done) | ||
940 | return false; /* more bytes to process in this segment */ | ||
941 | |||
942 | BUG_ON(cursor->last_piece); | ||
943 | BUG_ON(cursor->resid < bvec_iter_len(bvecs, cursor->bvec_iter)); | ||
944 | cursor->last_piece = | ||
945 | cursor->resid == bvec_iter_len(bvecs, cursor->bvec_iter); | ||
946 | return true; | ||
947 | } | ||
948 | |||
897 | /* | 949 | /* |
898 | * For a page array, a piece comes from the first page in the array | 950 | * For a page array, a piece comes from the first page in the array |
899 | * that has not already been fully consumed. | 951 | * that has not already been fully consumed. |
@@ -1077,6 +1129,9 @@ static void __ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor) | |||
1077 | ceph_msg_data_bio_cursor_init(cursor, length); | 1129 | ceph_msg_data_bio_cursor_init(cursor, length); |
1078 | break; | 1130 | break; |
1079 | #endif /* CONFIG_BLOCK */ | 1131 | #endif /* CONFIG_BLOCK */ |
1132 | case CEPH_MSG_DATA_BVECS: | ||
1133 | ceph_msg_data_bvecs_cursor_init(cursor, length); | ||
1134 | break; | ||
1080 | case CEPH_MSG_DATA_NONE: | 1135 | case CEPH_MSG_DATA_NONE: |
1081 | default: | 1136 | default: |
1082 | /* BUG(); */ | 1137 | /* BUG(); */ |
@@ -1125,6 +1180,9 @@ static struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor, | |||
1125 | page = ceph_msg_data_bio_next(cursor, page_offset, length); | 1180 | page = ceph_msg_data_bio_next(cursor, page_offset, length); |
1126 | break; | 1181 | break; |
1127 | #endif /* CONFIG_BLOCK */ | 1182 | #endif /* CONFIG_BLOCK */ |
1183 | case CEPH_MSG_DATA_BVECS: | ||
1184 | page = ceph_msg_data_bvecs_next(cursor, page_offset, length); | ||
1185 | break; | ||
1128 | case CEPH_MSG_DATA_NONE: | 1186 | case CEPH_MSG_DATA_NONE: |
1129 | default: | 1187 | default: |
1130 | page = NULL; | 1188 | page = NULL; |
@@ -1163,6 +1221,9 @@ static void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor, | |||
1163 | new_piece = ceph_msg_data_bio_advance(cursor, bytes); | 1221 | new_piece = ceph_msg_data_bio_advance(cursor, bytes); |
1164 | break; | 1222 | break; |
1165 | #endif /* CONFIG_BLOCK */ | 1223 | #endif /* CONFIG_BLOCK */ |
1224 | case CEPH_MSG_DATA_BVECS: | ||
1225 | new_piece = ceph_msg_data_bvecs_advance(cursor, bytes); | ||
1226 | break; | ||
1166 | case CEPH_MSG_DATA_NONE: | 1227 | case CEPH_MSG_DATA_NONE: |
1167 | default: | 1228 | default: |
1168 | BUG(); | 1229 | BUG(); |
@@ -3247,6 +3308,20 @@ void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos, | |||
3247 | EXPORT_SYMBOL(ceph_msg_data_add_bio); | 3308 | EXPORT_SYMBOL(ceph_msg_data_add_bio); |
3248 | #endif /* CONFIG_BLOCK */ | 3309 | #endif /* CONFIG_BLOCK */ |
3249 | 3310 | ||
3311 | void ceph_msg_data_add_bvecs(struct ceph_msg *msg, | ||
3312 | struct ceph_bvec_iter *bvec_pos) | ||
3313 | { | ||
3314 | struct ceph_msg_data *data; | ||
3315 | |||
3316 | data = ceph_msg_data_create(CEPH_MSG_DATA_BVECS); | ||
3317 | BUG_ON(!data); | ||
3318 | data->bvec_pos = *bvec_pos; | ||
3319 | |||
3320 | list_add_tail(&data->links, &msg->data); | ||
3321 | msg->data_length += bvec_pos->iter.bi_size; | ||
3322 | } | ||
3323 | EXPORT_SYMBOL(ceph_msg_data_add_bvecs); | ||
3324 | |||
3250 | /* | 3325 | /* |
3251 | * construct a new message with given type, size | 3326 | * construct a new message with given type, size |
3252 | * the new msg has a ref count of 1. | 3327 | * the new msg has a ref count of 1. |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 339d8773ebe8..407be0533c18 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -155,6 +155,13 @@ static void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data, | |||
155 | } | 155 | } |
156 | #endif /* CONFIG_BLOCK */ | 156 | #endif /* CONFIG_BLOCK */ |
157 | 157 | ||
158 | static void ceph_osd_data_bvecs_init(struct ceph_osd_data *osd_data, | ||
159 | struct ceph_bvec_iter *bvec_pos) | ||
160 | { | ||
161 | osd_data->type = CEPH_OSD_DATA_TYPE_BVECS; | ||
162 | osd_data->bvec_pos = *bvec_pos; | ||
163 | } | ||
164 | |||
158 | #define osd_req_op_data(oreq, whch, typ, fld) \ | 165 | #define osd_req_op_data(oreq, whch, typ, fld) \ |
159 | ({ \ | 166 | ({ \ |
160 | struct ceph_osd_request *__oreq = (oreq); \ | 167 | struct ceph_osd_request *__oreq = (oreq); \ |
@@ -229,6 +236,17 @@ void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req, | |||
229 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio); | 236 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio); |
230 | #endif /* CONFIG_BLOCK */ | 237 | #endif /* CONFIG_BLOCK */ |
231 | 238 | ||
239 | void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req, | ||
240 | unsigned int which, | ||
241 | struct ceph_bvec_iter *bvec_pos) | ||
242 | { | ||
243 | struct ceph_osd_data *osd_data; | ||
244 | |||
245 | osd_data = osd_req_op_data(osd_req, which, extent, osd_data); | ||
246 | ceph_osd_data_bvecs_init(osd_data, bvec_pos); | ||
247 | } | ||
248 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvec_pos); | ||
249 | |||
232 | static void osd_req_op_cls_request_info_pagelist( | 250 | static void osd_req_op_cls_request_info_pagelist( |
233 | struct ceph_osd_request *osd_req, | 251 | struct ceph_osd_request *osd_req, |
234 | unsigned int which, struct ceph_pagelist *pagelist) | 252 | unsigned int which, struct ceph_pagelist *pagelist) |
@@ -266,6 +284,23 @@ void osd_req_op_cls_request_data_pages(struct ceph_osd_request *osd_req, | |||
266 | } | 284 | } |
267 | EXPORT_SYMBOL(osd_req_op_cls_request_data_pages); | 285 | EXPORT_SYMBOL(osd_req_op_cls_request_data_pages); |
268 | 286 | ||
287 | void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req, | ||
288 | unsigned int which, | ||
289 | struct bio_vec *bvecs, u32 bytes) | ||
290 | { | ||
291 | struct ceph_osd_data *osd_data; | ||
292 | struct ceph_bvec_iter it = { | ||
293 | .bvecs = bvecs, | ||
294 | .iter = { .bi_size = bytes }, | ||
295 | }; | ||
296 | |||
297 | osd_data = osd_req_op_data(osd_req, which, cls, request_data); | ||
298 | ceph_osd_data_bvecs_init(osd_data, &it); | ||
299 | osd_req->r_ops[which].cls.indata_len += bytes; | ||
300 | osd_req->r_ops[which].indata_len += bytes; | ||
301 | } | ||
302 | EXPORT_SYMBOL(osd_req_op_cls_request_data_bvecs); | ||
303 | |||
269 | void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req, | 304 | void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req, |
270 | unsigned int which, struct page **pages, u64 length, | 305 | unsigned int which, struct page **pages, u64 length, |
271 | u32 alignment, bool pages_from_pool, bool own_pages) | 306 | u32 alignment, bool pages_from_pool, bool own_pages) |
@@ -291,6 +326,8 @@ static u64 ceph_osd_data_length(struct ceph_osd_data *osd_data) | |||
291 | case CEPH_OSD_DATA_TYPE_BIO: | 326 | case CEPH_OSD_DATA_TYPE_BIO: |
292 | return (u64)osd_data->bio_length; | 327 | return (u64)osd_data->bio_length; |
293 | #endif /* CONFIG_BLOCK */ | 328 | #endif /* CONFIG_BLOCK */ |
329 | case CEPH_OSD_DATA_TYPE_BVECS: | ||
330 | return osd_data->bvec_pos.iter.bi_size; | ||
294 | default: | 331 | default: |
295 | WARN(true, "unrecognized data type %d\n", (int)osd_data->type); | 332 | WARN(true, "unrecognized data type %d\n", (int)osd_data->type); |
296 | return 0; | 333 | return 0; |
@@ -831,6 +868,8 @@ static void ceph_osdc_msg_data_add(struct ceph_msg *msg, | |||
831 | } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) { | 868 | } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) { |
832 | ceph_msg_data_add_bio(msg, &osd_data->bio_pos, length); | 869 | ceph_msg_data_add_bio(msg, &osd_data->bio_pos, length); |
833 | #endif | 870 | #endif |
871 | } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BVECS) { | ||
872 | ceph_msg_data_add_bvecs(msg, &osd_data->bvec_pos); | ||
834 | } else { | 873 | } else { |
835 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_NONE); | 874 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_NONE); |
836 | } | 875 | } |