diff options
author | Ilya Dryomov <ilya.dryomov@inktank.com> | 2014-06-19 03:38:14 -0400 |
---|---|---|
committer | Ilya Dryomov <ilya.dryomov@inktank.com> | 2014-07-08 07:08:45 -0400 |
commit | bb040aa03ce870b0eff21ee75f7f324cd8cabe03 (patch) | |
tree | 36e10430d0b453686a82853745bfe2d27da12b80 | |
parent | 71c20a066f1a4ee1339db0efb58290fbb62e62f2 (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.c | 53 |
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 | */ | ||
2977 | static 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 | |||
3021 | out: | ||
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 | */ |
2976 | static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev) | 3029 | static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev) |