|
@@ -1253,6 +1253,35 @@ fail:
|
|
return ret;
|
|
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_notify_info {
|
|
struct rbd_device *dev;
|
|
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,
|
|
ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc,
|
|
rbd_dev->watch_request);
|
|
rbd_dev->watch_request);
|
|
if (rbd_dev->watch_event)
|
|
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);
|
|
rbd_put_client(rbd_dev);
|
|
|
|
|