Merge tag 'ceph-for-4.9-rc1' of git://github.com/ceph/ceph-client
[cascardo/linux.git] / drivers / block / rbd.c
index 3218ac4..abb7162 100644 (file)
@@ -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;
        char *snap_names = NULL;
        u64 *snap_sizes = NULL;
        u32 snap_count;
-       size_t size;
        int ret = -ENOMEM;
        u32 i;
 
        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. */
                        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;
 
                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);
 }
 
                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;
 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)
 {
 
 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;
 
        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)
 }
 
 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:
                        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;
                        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;
        }
 
                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;
        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);
 
 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:
        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)
 }
 
 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;
 
        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;
 
        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);
        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);
 
        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);
                                        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);
 
        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,
 
 static struct blk_mq_ops rbd_mq_ops = {
        .queue_rq       = rbd_queue_rq,
-       .map_queue      = blk_mq_map_queue,
        .init_request   = rbd_init_request,
 };
 
        .init_request   = rbd_init_request,
 };