X-Git-Url: http://git.cascardo.info/?p=cascardo%2Flinux.git;a=blobdiff_plain;f=drivers%2Fblock%2Frbd.c;h=abb71628ab614628d62acd3d16a91ee9eae8c9b4;hp=02e9a0f0bf7b04293e86da0758bf49759ec21736;hb=8dfb790b15e779232d5d4e3f0102af2bea21ca55;hpb=7c84883adf6dc614fc9e01304aa1813a55c43ad2 diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 02e9a0f0bf7b..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; @@ -2147,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; @@ -2368,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; @@ -2727,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); } /* @@ -2882,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) @@ -4442,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, };