Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 710214e3 authored by Ilya Dryomov's avatar Ilya Dryomov
Browse files

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: default avatarDavid Disseldorp <ddiss@suse.de>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
Reviewed-by: default avatarAlex Elder <elder@linaro.org>
Reviewed-by: default avatarDavid Disseldorp <ddiss@suse.de>
parent fa355112
Loading
Loading
Loading
Loading
+22 −20
Original line number Diff line number Diff line
@@ -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_obj_request *stat_request;
	struct page **pages = NULL;
	struct page **pages;
	u32 page_count;
	size_t size;
	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:
	 *     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);
	page_count = (u32)calc_pages_for(0, size);
	pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
	if (IS_ERR(pages))
		return PTR_ERR(pages);
	if (IS_ERR(pages)) {
		ret = PTR_ERR(pages);
		goto fail_stat_request;
	}

	ret = -ENOMEM;
	stat_request = rbd_obj_request_create(obj_request->object_name, 0, 0,
							OBJ_REQUEST_PAGES);
	if (!stat_request)
		goto out;
	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_obj_request_get(obj_request);
	stat_request->obj_request = obj_request;
	stat_request->pages = pages;
	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;

	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_obj_request_submit(stat_request);
	return 0;

out:
	if (ret)
		rbd_obj_request_put(obj_request);

fail_stat_request:
	rbd_obj_request_put(stat_request);
	return ret;
}