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>
This commit is contained in:
parent
fa355112c2
commit
710214e391
@ -2894,11 +2894,23 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
|
|||||||
{
|
{
|
||||||
struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
|
struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
|
||||||
struct rbd_obj_request *stat_request;
|
struct rbd_obj_request *stat_request;
|
||||||
struct page **pages = NULL;
|
struct page **pages;
|
||||||
u32 page_count;
|
u32 page_count;
|
||||||
size_t size;
|
size_t size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
stat_request = rbd_obj_request_create(obj_request->object_name, 0, 0,
|
||||||
|
OBJ_REQUEST_PAGES);
|
||||||
|
if (!stat_request)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
|
||||||
|
stat_request);
|
||||||
|
if (!stat_request->osd_req) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto fail_stat_request;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The response data for a STAT call consists of:
|
* The response data for a STAT call consists of:
|
||||||
* le64 length;
|
* le64 length;
|
||||||
@ -2910,38 +2922,28 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
|
|||||||
size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32);
|
size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32);
|
||||||
page_count = (u32)calc_pages_for(0, size);
|
page_count = (u32)calc_pages_for(0, size);
|
||||||
pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
|
pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
|
||||||
if (IS_ERR(pages))
|
if (IS_ERR(pages)) {
|
||||||
return PTR_ERR(pages);
|
ret = PTR_ERR(pages);
|
||||||
|
goto fail_stat_request;
|
||||||
|
}
|
||||||
|
|
||||||
ret = -ENOMEM;
|
osd_req_op_init(stat_request->osd_req, 0, CEPH_OSD_OP_STAT, 0);
|
||||||
stat_request = rbd_obj_request_create(obj_request->object_name, 0, 0,
|
osd_req_op_raw_data_in_pages(stat_request->osd_req, 0, pages, size, 0,
|
||||||
OBJ_REQUEST_PAGES);
|
false, false);
|
||||||
if (!stat_request)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rbd_obj_request_get(obj_request);
|
rbd_obj_request_get(obj_request);
|
||||||
stat_request->obj_request = obj_request;
|
stat_request->obj_request = obj_request;
|
||||||
stat_request->pages = pages;
|
stat_request->pages = pages;
|
||||||
stat_request->page_count = page_count;
|
stat_request->page_count = page_count;
|
||||||
|
|
||||||
stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
|
|
||||||
stat_request);
|
|
||||||
if (!stat_request->osd_req)
|
|
||||||
goto out;
|
|
||||||
stat_request->callback = rbd_img_obj_exists_callback;
|
stat_request->callback = rbd_img_obj_exists_callback;
|
||||||
|
|
||||||
osd_req_op_init(stat_request->osd_req, 0, CEPH_OSD_OP_STAT, 0);
|
|
||||||
osd_req_op_raw_data_in_pages(stat_request->osd_req, 0, pages, size, 0,
|
|
||||||
false, false);
|
|
||||||
rbd_osd_req_format_read(stat_request);
|
rbd_osd_req_format_read(stat_request);
|
||||||
|
|
||||||
rbd_obj_request_submit(stat_request);
|
rbd_obj_request_submit(stat_request);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out:
|
fail_stat_request:
|
||||||
if (ret)
|
rbd_obj_request_put(stat_request);
|
||||||
rbd_obj_request_put(obj_request);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user