summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2011-07-12 16:56:57 -0700
committerSage Weil <sage@newdream.net>2011-07-26 11:29:04 -0700
commit79e3057c4c9d32b88e6745fd220d91b0a8b2030b (patch)
treefb6f4bff64c4e6014af3bdaa5284e921d24111bd /drivers
parent2f90b852e3ae73889d7f6de6ecf429b9b6a6b103 (diff)
downloadlinux-79e3057c4c9d32b88e6745fd220d91b0a8b2030b.tar.gz
linux-79e3057c4c9d32b88e6745fd220d91b0a8b2030b.tar.bz2
linux-79e3057c4c9d32b88e6745fd220d91b0a8b2030b.zip
rbd: cancel watch request when releasing the device
We were missing this cleanup, so when a device was released the osd didn't clean up its watchers list, so following notifications could be slow as osd needed to timeout on the client. Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/rbd.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 1278098624e6..7392d7af7eab 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1253,6 +1253,35 @@ fail:
return ret;
}
+/*
+ * Request sync osd unwatch
+ */
+static int rbd_req_sync_unwatch(struct rbd_device *dev,
+ const char *obj)
+{
+ struct ceph_osd_req_op *ops;
+
+ int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_WATCH, 0);
+ if (ret < 0)
+ return ret;
+
+ ops[0].watch.ver = 0;
+ ops[0].watch.cookie = cpu_to_le64(dev->watch_event->cookie);
+ ops[0].watch.flag = 0;
+
+ ret = rbd_req_sync_op(dev, NULL,
+ CEPH_NOSNAP,
+ 0,
+ CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
+ ops,
+ 1, obj, 0, 0, NULL, NULL, NULL);
+
+ rbd_destroy_ops(ops);
+ ceph_osdc_cancel_event(dev->watch_event);
+ dev->watch_event = NULL;
+ return ret;
+}
+
struct rbd_notify_info {
struct rbd_device *dev;
};
@@ -2290,7 +2319,7 @@ static void rbd_dev_release(struct device *dev)
ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc,
rbd_dev->watch_request);
if (rbd_dev->watch_event)
- ceph_osdc_cancel_event(rbd_dev->watch_event);
+ rbd_req_sync_unwatch(rbd_dev, rbd_dev->obj_md_name);
rbd_put_client(rbd_dev);