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
commit71c20a066f1a4ee1339db0efb58290fbb62e62f2 (patch)
tree5055abe05cb7a383196f2cef2ff68acb5f30bb1f
parentc9f9b93ddfd76498fe36d9f550bd26533a4ee6bf (diff)
rbd: rbd_obj_request_wait() should cancel the request if interrupted
rbd_obj_request_wait() should cancel the underlying OSD request if interrupted. Otherwise libceph will hold onto it indefinitely, causing assert failures or leaking the original object request. This also adds an rbd wrapper around ceph_osdc_cancel_request() to match rbd_obj_request_submit() and 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.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index b2c98c1bc037..20147aec86f3 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1527,11 +1527,37 @@ static bool obj_request_type_valid(enum obj_request_type type)
1527static int rbd_obj_request_submit(struct ceph_osd_client *osdc, 1527static int rbd_obj_request_submit(struct ceph_osd_client *osdc,
1528 struct rbd_obj_request *obj_request) 1528 struct rbd_obj_request *obj_request)
1529{ 1529{
1530 dout("%s: osdc %p obj %p\n", __func__, osdc, obj_request); 1530 dout("%s %p\n", __func__, obj_request);
1531
1532 return ceph_osdc_start_request(osdc, obj_request->osd_req, false); 1531 return ceph_osdc_start_request(osdc, obj_request->osd_req, false);
1533} 1532}
1534 1533
1534static void rbd_obj_request_end(struct rbd_obj_request *obj_request)
1535{
1536 dout("%s %p\n", __func__, obj_request);
1537 ceph_osdc_cancel_request(obj_request->osd_req);
1538}
1539
1540/*
1541 * Wait for an object request to complete. If interrupted, cancel the
1542 * underlying osd request.
1543 */
1544static int rbd_obj_request_wait(struct rbd_obj_request *obj_request)
1545{
1546 int ret;
1547
1548 dout("%s %p\n", __func__, obj_request);
1549
1550 ret = wait_for_completion_interruptible(&obj_request->completion);
1551 if (ret < 0) {
1552 dout("%s %p interrupted\n", __func__, obj_request);
1553 rbd_obj_request_end(obj_request);
1554 return ret;
1555 }
1556
1557 dout("%s %p done\n", __func__, obj_request);
1558 return 0;
1559}
1560
1535static void rbd_img_request_complete(struct rbd_img_request *img_request) 1561static void rbd_img_request_complete(struct rbd_img_request *img_request)
1536{ 1562{
1537 1563
@@ -1558,15 +1584,6 @@ static void rbd_img_request_complete(struct rbd_img_request *img_request)
1558 rbd_img_request_put(img_request); 1584 rbd_img_request_put(img_request);
1559} 1585}
1560 1586
1561/* Caller is responsible for rbd_obj_request_destroy(obj_request) */
1562
1563static int rbd_obj_request_wait(struct rbd_obj_request *obj_request)
1564{
1565 dout("%s: obj %p\n", __func__, obj_request);
1566
1567 return wait_for_completion_interruptible(&obj_request->completion);
1568}
1569
1570/* 1587/*
1571 * The default/initial value for all image request flags is 0. Each 1588 * The default/initial value for all image request flags is 0. Each
1572 * is conditionally set to 1 at image request initialization time 1589 * is conditionally set to 1 at image request initialization time