diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2018-02-06 13:26:34 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-04-02 04:12:43 -0400 |
commit | 5a237819aa4e0421a17966e9baf91b9caedaf61d (patch) | |
tree | b8d8a199535bdc0ace287c567d98474ea8bd5042 /drivers/block/rbd.c | |
parent | 2bb1e56ec6450ce533c644c5bfa548dc34c551a0 (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.c | 191 |
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 | ||
2057 | union rbd_img_fill_iter { | ||
2058 | struct ceph_bio_iter bio_iter; | ||
2059 | struct ceph_bvec_iter bvec_iter; | ||
2060 | }; | ||
2061 | |||
2062 | struct 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 | |||
2069 | static 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 | */ | ||
2091 | static 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 | |||
2120 | static 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 | |||
2133 | static 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 | |||
2144 | static 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 | |||
2159 | static 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 | |||
2168 | static 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 | |||
2179 | static 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 | |||
2194 | static 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 | |||
2058 | static void rbd_img_request_submit(struct rbd_img_request *img_request) | 2209 | static 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 | ||