aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <ilya.dryomov@inktank.com>2014-06-19 03:38:14 -0400
committerIlya Dryomov <ilya.dryomov@inktank.com>2014-07-08 07:08:45 -0400
commitbb040aa03ce870b0eff21ee75f7f324cd8cabe03 (patch)
tree36e10430d0b453686a82853745bfe2d27da12b80
parent71c20a066f1a4ee1339db0efb58290fbb62e62f2 (diff)
rbd: add rbd_obj_watch_request_helper() helper
In the past, rbd_dev_header_watch_sync() used to handle both watch and unwatch requests and was entangled and leaky. Commit b30a01f2a307 ("rbd: fix osd_request memory leak in __rbd_dev_header_watch_sync()") split it into two separate functions. This commit cleanly abstracts the common bits, relying on the fixed rbd_obj_request_wait(). Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com> Reviewed-by: Alex Elder <elder@linaro.org>
-rw-r--r--drivers/block/rbd.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 20147aec86f3..02cf7aba7679 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2971,6 +2971,59 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
2971} 2971}
2972 2972
2973/* 2973/*
2974 * Send a (un)watch request and wait for the ack. Return a request
2975 * with a ref held on success or error.
2976 */
2977static struct rbd_obj_request *rbd_obj_watch_request_helper(
2978 struct rbd_device *rbd_dev,
2979 bool watch)
2980{
2981 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
2982 struct rbd_obj_request *obj_request;
2983 int ret;
2984
2985 obj_request = rbd_obj_request_create(rbd_dev->header_name, 0, 0,
2986 OBJ_REQUEST_NODATA);
2987 if (!obj_request)
2988 return ERR_PTR(-ENOMEM);
2989
2990 obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, 1,
2991 obj_request);
2992 if (!obj_request->osd_req) {
2993 ret = -ENOMEM;
2994 goto out;
2995 }
2996
2997 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH,
2998 rbd_dev->watch_event->cookie, 0, watch);
2999 rbd_osd_req_format_write(obj_request);
3000
3001 if (watch)
3002 ceph_osdc_set_request_linger(osdc, obj_request->osd_req);
3003
3004 ret = rbd_obj_request_submit(osdc, obj_request);
3005 if (ret)
3006 goto out;
3007
3008 ret = rbd_obj_request_wait(obj_request);
3009 if (ret)
3010 goto out;
3011
3012 ret = obj_request->result;
3013 if (ret) {
3014 if (watch)
3015 rbd_obj_request_end(obj_request);
3016 goto out;
3017 }
3018
3019 return obj_request;
3020
3021out:
3022 rbd_obj_request_put(obj_request);
3023 return ERR_PTR(ret);
3024}
3025
3026/*
2974 * Initiate a watch request, synchronously. 3027 * Initiate a watch request, synchronously.
2975 */ 3028 */
2976static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev) 3029static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev)