summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2018-01-20 04:30:11 -0500
committerIlya Dryomov <idryomov@gmail.com>2018-04-02 04:12:39 -0400
commitb9e281c2b38804984d619e1d9efc4b9020bcb291 (patch)
treef60492d187e96375c3212679d4ca4a9ad3bcf146 /net
parentf9dcbc44cd317ee3c5e443db7f9a62f52689f08e (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.c75
-rw-r--r--net/ceph/osd_client.c39
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
897static 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
912static 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
924static 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,
3247EXPORT_SYMBOL(ceph_msg_data_add_bio); 3308EXPORT_SYMBOL(ceph_msg_data_add_bio);
3248#endif /* CONFIG_BLOCK */ 3309#endif /* CONFIG_BLOCK */
3249 3310
3311void 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}
3323EXPORT_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
158static 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,
229EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio); 236EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio);
230#endif /* CONFIG_BLOCK */ 237#endif /* CONFIG_BLOCK */
231 238
239void 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}
248EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvec_pos);
249
232static void osd_req_op_cls_request_info_pagelist( 250static 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}
267EXPORT_SYMBOL(osd_req_op_cls_request_data_pages); 285EXPORT_SYMBOL(osd_req_op_cls_request_data_pages);
268 286
287void 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}
302EXPORT_SYMBOL(osd_req_op_cls_request_data_bvecs);
303
269void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req, 304void 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 }