summaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2018-02-06 13:26:34 -0500
committerIlya Dryomov <idryomov@gmail.com>2018-04-02 04:12:43 -0400
commit5a237819aa4e0421a17966e9baf91b9caedaf61d (patch)
treeb8d8a199535bdc0ace287c567d98474ea8bd5042 /drivers/block/rbd.c
parent2bb1e56ec6450ce533c644c5bfa548dc34c551a0 (diff)
rbd: switch to common striping framework
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c191
1 files changed, 168 insertions, 23 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index fc94e2c45e28..24f169f33219 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1326,7 +1326,6 @@ static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request,
1326 obj_request->img_request = img_request; 1326 obj_request->img_request = img_request;
1327 img_request->obj_request_count++; 1327 img_request->obj_request_count++;
1328 img_request->pending_count++; 1328 img_request->pending_count++;
1329 list_add_tail(&obj_request->ex.oe_item, &img_request->object_extents);
1330 dout("%s: img %p obj %p\n", __func__, img_request, obj_request); 1329 dout("%s: img %p obj %p\n", __func__, img_request, obj_request);
1331} 1330}
1332 1331
@@ -2055,6 +2054,158 @@ out_unwind:
2055 return -ENOMEM; 2054 return -ENOMEM;
2056} 2055}
2057 2056
2057union rbd_img_fill_iter {
2058 struct ceph_bio_iter bio_iter;
2059 struct ceph_bvec_iter bvec_iter;
2060};
2061
2062struct rbd_img_fill_ctx {
2063 enum obj_request_type pos_type;
2064 union rbd_img_fill_iter *pos;
2065 union rbd_img_fill_iter iter;
2066 ceph_object_extent_fn_t set_pos_fn;
2067};
2068
2069static struct ceph_object_extent *alloc_object_extent(void *arg)
2070{
2071 struct rbd_img_request *img_req = arg;
2072 struct rbd_obj_request *obj_req;
2073
2074 obj_req = rbd_obj_request_create();
2075 if (!obj_req)
2076 return NULL;
2077
2078 rbd_img_obj_request_add(img_req, obj_req);
2079 return &obj_req->ex;
2080}
2081
2082/*
2083 * Map a list of image extents to a list of object extents, create the
2084 * corresponding object requests (normally each to a different object,
2085 * but not always) and add them to @img_req. For each object request,
2086 * set up its data descriptor to point to the corresponding chunk of
2087 * @fctx->pos data buffer.
2088 *
2089 * @fctx->pos data buffer is assumed to be large enough.
2090 */
2091static int rbd_img_fill_request(struct rbd_img_request *img_req,
2092 struct ceph_file_extent *img_extents,
2093 u32 num_img_extents,
2094 struct rbd_img_fill_ctx *fctx)
2095{
2096 u32 i;
2097 int ret;
2098
2099 img_req->data_type = fctx->pos_type;
2100
2101 /*
2102 * Create object requests and set each object request's starting
2103 * position in the provided bio (list) or bio_vec array.
2104 */
2105 fctx->iter = *fctx->pos;
2106 for (i = 0; i < num_img_extents; i++) {
2107 ret = ceph_file_to_extents(&img_req->rbd_dev->layout,
2108 img_extents[i].fe_off,
2109 img_extents[i].fe_len,
2110 &img_req->object_extents,
2111 alloc_object_extent, img_req,
2112 fctx->set_pos_fn, &fctx->iter);
2113 if (ret)
2114 return ret;
2115 }
2116
2117 return __rbd_img_fill_request(img_req);
2118}
2119
2120static int rbd_img_fill_nodata(struct rbd_img_request *img_req,
2121 u64 off, u64 len)
2122{
2123 struct ceph_file_extent ex = { off, len };
2124 union rbd_img_fill_iter dummy;
2125 struct rbd_img_fill_ctx fctx = {
2126 .pos_type = OBJ_REQUEST_NODATA,
2127 .pos = &dummy,
2128 };
2129
2130 return rbd_img_fill_request(img_req, &ex, 1, &fctx);
2131}
2132
2133static void set_bio_pos(struct ceph_object_extent *ex, u32 bytes, void *arg)
2134{
2135 struct rbd_obj_request *obj_req =
2136 container_of(ex, struct rbd_obj_request, ex);
2137 struct ceph_bio_iter *it = arg;
2138
2139 dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes);
2140 obj_req->bio_pos = *it;
2141 ceph_bio_iter_advance(it, bytes);
2142}
2143
2144static int __rbd_img_fill_from_bio(struct rbd_img_request *img_req,
2145 struct ceph_file_extent *img_extents,
2146 u32 num_img_extents,
2147 struct ceph_bio_iter *bio_pos)
2148{
2149 struct rbd_img_fill_ctx fctx = {
2150 .pos_type = OBJ_REQUEST_BIO,
2151 .pos = (union rbd_img_fill_iter *)bio_pos,
2152 .set_pos_fn = set_bio_pos,
2153 };
2154
2155 return rbd_img_fill_request(img_req, img_extents, num_img_extents,
2156 &fctx);
2157}
2158
2159static int rbd_img_fill_from_bio(struct rbd_img_request *img_req,
2160 u64 off, u64 len, struct bio *bio)
2161{
2162 struct ceph_file_extent ex = { off, len };
2163 struct ceph_bio_iter it = { .bio = bio, .iter = bio->bi_iter };
2164
2165 return __rbd_img_fill_from_bio(img_req, &ex, 1, &it);
2166}
2167
2168static void set_bvec_pos(struct ceph_object_extent *ex, u32 bytes, void *arg)
2169{
2170 struct rbd_obj_request *obj_req =
2171 container_of(ex, struct rbd_obj_request, ex);
2172 struct ceph_bvec_iter *it = arg;
2173
2174 obj_req->bvec_pos = *it;
2175 ceph_bvec_iter_shorten(&obj_req->bvec_pos, bytes);
2176 ceph_bvec_iter_advance(it, bytes);
2177}
2178
2179static int __rbd_img_fill_from_bvecs(struct rbd_img_request *img_req,
2180 struct ceph_file_extent *img_extents,
2181 u32 num_img_extents,
2182 struct ceph_bvec_iter *bvec_pos)
2183{
2184 struct rbd_img_fill_ctx fctx = {
2185 .pos_type = OBJ_REQUEST_BVECS,
2186 .pos = (union rbd_img_fill_iter *)bvec_pos,
2187 .set_pos_fn = set_bvec_pos,
2188 };
2189
2190 return rbd_img_fill_request(img_req, img_extents, num_img_extents,
2191 &fctx);
2192}
2193
2194static int rbd_img_fill_from_bvecs(struct rbd_img_request *img_req,
2195 struct ceph_file_extent *img_extents,
2196 u32 num_img_extents,
2197 struct bio_vec *bvecs)
2198{
2199 struct ceph_bvec_iter it = {
2200 .bvecs = bvecs,
2201 .iter = { .bi_size = ceph_file_extents_bytes(img_extents,
2202 num_img_extents) },
2203 };
2204
2205 return __rbd_img_fill_from_bvecs(img_req, img_extents, num_img_extents,
2206 &it);
2207}
2208
2058static void rbd_img_request_submit(struct rbd_img_request *img_request) 2209static void rbd_img_request_submit(struct rbd_img_request *img_request)
2059{ 2210{
2060 struct rbd_obj_request *obj_request; 2211 struct rbd_obj_request *obj_request;
@@ -2083,26 +2234,25 @@ static int rbd_obj_read_from_parent(struct rbd_obj_request *obj_req)
2083 if (!rbd_img_is_write(img_req)) { 2234 if (!rbd_img_is_write(img_req)) {
2084 switch (img_req->data_type) { 2235 switch (img_req->data_type) {
2085 case OBJ_REQUEST_BIO: 2236 case OBJ_REQUEST_BIO:
2086 ret = rbd_img_request_fill(child_img_req, 2237 ret = __rbd_img_fill_from_bio(child_img_req,
2087 OBJ_REQUEST_BIO, 2238 obj_req->img_extents,
2088 &obj_req->bio_pos); 2239 obj_req->num_img_extents,
2240 &obj_req->bio_pos);
2089 break; 2241 break;
2090 case OBJ_REQUEST_BVECS: 2242 case OBJ_REQUEST_BVECS:
2091 ret = rbd_img_request_fill(child_img_req, 2243 ret = __rbd_img_fill_from_bvecs(child_img_req,
2092 OBJ_REQUEST_BVECS, 2244 obj_req->img_extents,
2093 &obj_req->bvec_pos); 2245 obj_req->num_img_extents,
2246 &obj_req->bvec_pos);
2094 break; 2247 break;
2095 default: 2248 default:
2096 rbd_assert(0); 2249 rbd_assert(0);
2097 } 2250 }
2098 } else { 2251 } else {
2099 struct ceph_bvec_iter it = { 2252 ret = rbd_img_fill_from_bvecs(child_img_req,
2100 .bvecs = obj_req->copyup_bvecs, 2253 obj_req->img_extents,
2101 .iter = { .bi_size = obj_req->img_extents[0].fe_len }, 2254 obj_req->num_img_extents,
2102 }; 2255 obj_req->copyup_bvecs);
2103
2104 ret = rbd_img_request_fill(child_img_req, OBJ_REQUEST_BVECS,
2105 &it);
2106 } 2256 }
2107 if (ret) { 2257 if (ret) {
2108 rbd_img_request_put(child_img_req); 2258 rbd_img_request_put(child_img_req);
@@ -3520,15 +3670,10 @@ static void rbd_queue_workfn(struct work_struct *work)
3520 snapc = NULL; /* img_request consumes a ref */ 3670 snapc = NULL; /* img_request consumes a ref */
3521 3671
3522 if (op_type == OBJ_OP_DISCARD) 3672 if (op_type == OBJ_OP_DISCARD)
3523 result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA, 3673 result = rbd_img_fill_nodata(img_request, offset, length);
3524 NULL); 3674 else
3525 else { 3675 result = rbd_img_fill_from_bio(img_request, offset, length,
3526 struct ceph_bio_iter bio_it = { .bio = rq->bio, 3676 rq->bio);
3527 .iter = rq->bio->bi_iter };
3528
3529 result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
3530 &bio_it);
3531 }
3532 if (result) 3677 if (result)
3533 goto err_img_request; 3678 goto err_img_request;
3534 3679