Merge tag 'ceph-for-4.9-rc1' of git://github.com/ceph/ceph-client
[cascardo/linux.git] / drivers / block / rbd.c
index 02e9a0f..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;
@@ -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:
                        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;
@@ -2368,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;
@@ -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);
 
 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:
        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)
@@ -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,
 
 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,
 };