aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2011-07-12 19:56:57 -0400
committerSage Weil <sage@newdream.net>2011-07-26 14:29:04 -0400
commit79e3057c4c9d32b88e6745fd220d91b0a8b2030b (patch)
treefb6f4bff64c4e6014af3bdaa5284e921d24111bd /drivers/block/rbd.c
parent2f90b852e3ae73889d7f6de6ecf429b9b6a6b103 (diff)
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/block/rbd.c')
-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:
1253 return ret; 1253 return ret;
1254} 1254}
1255 1255
1256/*
1257 * Request sync osd unwatch
1258 */
1259static int rbd_req_sync_unwatch(struct rbd_device *dev,
1260 const char *obj)
1261{
1262 struct ceph_osd_req_op *ops;
1263
1264 int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_WATCH, 0);
1265 if (ret < 0)
1266 return ret;
1267
1268 ops[0].watch.ver = 0;
1269 ops[0].watch.cookie = cpu_to_le64(dev->watch_event->cookie);
1270 ops[0].watch.flag = 0;
1271
1272 ret = rbd_req_sync_op(dev, NULL,
1273 CEPH_NOSNAP,
1274 0,
1275 CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
1276 ops,
1277 1, obj, 0, 0, NULL, NULL, NULL);
1278
1279 rbd_destroy_ops(ops);
1280 ceph_osdc_cancel_event(dev->watch_event);
1281 dev->watch_event = NULL;
1282 return ret;
1283}
1284
1256struct rbd_notify_info { 1285struct rbd_notify_info {
1257 struct rbd_device *dev; 1286 struct rbd_device *dev;
1258}; 1287};
@@ -2290,7 +2319,7 @@ static void rbd_dev_release(struct device *dev)
2290 ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc, 2319 ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc,
2291 rbd_dev->watch_request); 2320 rbd_dev->watch_request);
2292 if (rbd_dev->watch_event) 2321 if (rbd_dev->watch_event)
2293 ceph_osdc_cancel_event(rbd_dev->watch_event); 2322 rbd_req_sync_unwatch(rbd_dev, rbd_dev->obj_md_name);
2294 2323
2295 rbd_put_client(rbd_dev); 2324 rbd_put_client(rbd_dev);
2296 2325