X-Git-Url: http://git.cascardo.info/?p=cascardo%2Flinux.git;a=blobdiff_plain;f=drivers%2Fblock%2Frbd.c;h=abb71628ab614628d62acd3d16a91ee9eae8c9b4;hp=3218ac4f2e09189197df9726afbd06bc6ced36e9;hb=8dfb790b15e779232d5d4e3f0102af2bea21ca55;hpb=710214e391476f331abed1b774b5f025d054ab7f diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 3218ac4f2e09..abb71628ab61 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -986,7 +986,6 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, char *snap_names = NULL; u64 *snap_sizes = NULL; u32 snap_count; - size_t size; int ret = -ENOMEM; u32 i; @@ -1024,9 +1023,9 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, goto out_err; /* ...as well as the array of their sizes. */ - - size = snap_count * sizeof (*header->snap_sizes); - snap_sizes = kmalloc(size, GFP_KERNEL); + snap_sizes = kmalloc_array(snap_count, + sizeof(*header->snap_sizes), + GFP_KERNEL); if (!snap_sizes) goto out_err; @@ -1819,6 +1818,22 @@ static void rbd_obj_request_complete(struct rbd_obj_request *obj_request) complete_all(&obj_request->completion); } +static void rbd_obj_request_error(struct rbd_obj_request *obj_request, int err) +{ + obj_request->result = err; + obj_request->xferred = 0; + /* + * kludge - mirror rbd_obj_request_submit() to match a put in + * rbd_img_obj_callback() + */ + if (obj_request_img_data_test(obj_request)) { + WARN_ON(obj_request->callback != rbd_img_obj_callback); + rbd_img_request_get(obj_request->img_request); + } + obj_request_done_set(obj_request); + rbd_obj_request_complete(obj_request); +} + static void rbd_osd_read_callback(struct rbd_obj_request *obj_request) { struct rbd_img_request *img_request = NULL; @@ -1951,11 +1966,10 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req) static void rbd_osd_req_format_read(struct rbd_obj_request *obj_request) { - struct rbd_img_request *img_request = obj_request->img_request; struct ceph_osd_request *osd_req = obj_request->osd_req; - if (img_request) - osd_req->r_snapid = img_request->snap_id; + rbd_assert(obj_request_img_data_test(obj_request)); + osd_req->r_snapid = obj_request->img_request->snap_id; } static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request) @@ -2148,7 +2162,9 @@ static void rbd_obj_request_destroy(struct kref *kref) bio_chain_put(obj_request->bio_list); break; case OBJ_REQUEST_PAGES: - if (obj_request->pages) + /* img_data requests don't own their page array */ + if (obj_request->pages && + !obj_request_img_data_test(obj_request)) ceph_release_page_vector(obj_request->pages, obj_request->page_count); break; @@ -2369,13 +2385,6 @@ static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request) xferred = obj_request->length; } - /* Image object requests don't own their page array */ - - if (obj_request->type == OBJ_REQUEST_PAGES) { - obj_request->pages = NULL; - obj_request->page_count = 0; - } - if (img_request_child_test(img_request)) { rbd_assert(img_request->obj_request != NULL); more = obj_request->which < img_request->obj_request_count - 1; @@ -2728,11 +2737,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) out_err: ceph_release_page_vector(pages, page_count); - orig_request->result = img_result; - orig_request->xferred = 0; - rbd_img_request_get(orig_request->img_request); - obj_request_done_set(orig_request); - rbd_obj_request_complete(orig_request); + rbd_obj_request_error(orig_request, img_result); } /* @@ -2883,11 +2888,7 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request) return; fail_orig_request: - orig_request->result = result; - orig_request->xferred = 0; - rbd_img_request_get(orig_request->img_request); - obj_request_done_set(orig_request); - rbd_obj_request_complete(orig_request); + rbd_obj_request_error(orig_request, result); } static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request) @@ -2937,8 +2938,6 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request) stat_request->page_count = page_count; stat_request->callback = rbd_img_obj_exists_callback; - rbd_osd_req_format_read(stat_request); - rbd_obj_request_submit(stat_request); return 0; @@ -4034,7 +4033,6 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, osd_req_op_cls_response_data_pages(obj_request->osd_req, 0, obj_request->pages, inbound_size, 0, false, false); - rbd_osd_req_format_read(obj_request); rbd_obj_request_submit(obj_request); ret = rbd_obj_request_wait(obj_request); @@ -4276,7 +4274,6 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, obj_request->length, obj_request->offset & ~PAGE_MASK, false, false); - rbd_osd_req_format_read(obj_request); rbd_obj_request_submit(obj_request); ret = rbd_obj_request_wait(obj_request); @@ -4447,7 +4444,6 @@ static int rbd_init_request(void *data, struct request *rq, static struct blk_mq_ops rbd_mq_ops = { .queue_rq = rbd_queue_rq, - .map_queue = blk_mq_map_queue, .init_request = rbd_init_request, };