aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-09-15 11:53:32 -0400
committerIlya Dryomov <idryomov@gmail.com>2016-10-03 10:13:48 -0400
commit710214e391476f331abed1b774b5f025d054ab7f (patch)
tree3ca0c6e07acc2a7a07cdf86bb4b8325a5a4266d4 /drivers/block/rbd.c
parentfa355112c2763d513f1356119684dc8a6150d08a (diff)
rbd: rework rbd_img_obj_exists_submit() error paths
- don't put obj_request before rbd_obj_request_get() if rbd_obj_request_create() fails - don't leak pages if rbd_obj_request_create() fails - don't leak stat_request if rbd_osd_req_create() fails Reported-by: David Disseldorp <ddiss@suse.de> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Alex Elder <elder@linaro.org> Reviewed-by: David Disseldorp <ddiss@suse.de>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 77675ac8fc4c..3218ac4f2e09 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2894,11 +2894,23 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
2894{ 2894{
2895 struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev; 2895 struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
2896 struct rbd_obj_request *stat_request; 2896 struct rbd_obj_request *stat_request;
2897 struct page **pages = NULL; 2897 struct page **pages;
2898 u32 page_count; 2898 u32 page_count;
2899 size_t size; 2899 size_t size;
2900 int ret; 2900 int ret;
2901 2901
2902 stat_request = rbd_obj_request_create(obj_request->object_name, 0, 0,
2903 OBJ_REQUEST_PAGES);
2904 if (!stat_request)
2905 return -ENOMEM;
2906
2907 stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
2908 stat_request);
2909 if (!stat_request->osd_req) {
2910 ret = -ENOMEM;
2911 goto fail_stat_request;
2912 }
2913
2902 /* 2914 /*
2903 * The response data for a STAT call consists of: 2915 * The response data for a STAT call consists of:
2904 * le64 length; 2916 * le64 length;
@@ -2910,38 +2922,28 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
2910 size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32); 2922 size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32);
2911 page_count = (u32)calc_pages_for(0, size); 2923 page_count = (u32)calc_pages_for(0, size);
2912 pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); 2924 pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
2913 if (IS_ERR(pages)) 2925 if (IS_ERR(pages)) {
2914 return PTR_ERR(pages); 2926 ret = PTR_ERR(pages);
2927 goto fail_stat_request;
2928 }
2915 2929
2916 ret = -ENOMEM; 2930 osd_req_op_init(stat_request->osd_req, 0, CEPH_OSD_OP_STAT, 0);
2917 stat_request = rbd_obj_request_create(obj_request->object_name, 0, 0, 2931 osd_req_op_raw_data_in_pages(stat_request->osd_req, 0, pages, size, 0,
2918 OBJ_REQUEST_PAGES); 2932 false, false);
2919 if (!stat_request)
2920 goto out;
2921 2933
2922 rbd_obj_request_get(obj_request); 2934 rbd_obj_request_get(obj_request);
2923 stat_request->obj_request = obj_request; 2935 stat_request->obj_request = obj_request;
2924 stat_request->pages = pages; 2936 stat_request->pages = pages;
2925 stat_request->page_count = page_count; 2937 stat_request->page_count = page_count;
2926
2927 stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
2928 stat_request);
2929 if (!stat_request->osd_req)
2930 goto out;
2931 stat_request->callback = rbd_img_obj_exists_callback; 2938 stat_request->callback = rbd_img_obj_exists_callback;
2932 2939
2933 osd_req_op_init(stat_request->osd_req, 0, CEPH_OSD_OP_STAT, 0);
2934 osd_req_op_raw_data_in_pages(stat_request->osd_req, 0, pages, size, 0,
2935 false, false);
2936 rbd_osd_req_format_read(stat_request); 2940 rbd_osd_req_format_read(stat_request);
2937 2941
2938 rbd_obj_request_submit(stat_request); 2942 rbd_obj_request_submit(stat_request);
2939 return 0; 2943 return 0;
2940 2944
2941out: 2945fail_stat_request:
2942 if (ret) 2946 rbd_obj_request_put(stat_request);
2943 rbd_obj_request_put(obj_request);
2944
2945 return ret; 2947 return ret;
2946} 2948}
2947 2949