aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-06 18:40:33 -0400
committerAlex Elder <elder@inktank.com>2013-05-08 21:16:55 -0400
commit1f3ef78861ac4b510175e177899b9b5ba4bbed91 (patch)
treeedf2c0b20d647f495bf7d596f72b08349115d772 /drivers/block/rbd.c
parent7ce4eef7b5fad73b365b7e4b8892af3af72d4bd3 (diff)
rbd: only set up watch for mapped images
Any changes to parent images are immaterial to any mapped clone. So there is no need to have a watch event registered on header objects except for the header object of an image that is mapped. In fact, a watch request is a write operation, and we may only have read access to a parent image. We can't set up the watch request until we know the name of the header object though. So pass a flag to rbd_dev_image_probe() to indicate whether this probe is for a mapping or for a parent image. Change the second parameter to rbd_dev_header_watch_sync() be Boolean while we're at it. This resolves: http://tracker.ceph.com/issues/4941 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index dbfc44a9defd..e417704de8ca 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -358,7 +358,7 @@ static ssize_t rbd_add(struct bus_type *bus, const char *buf,
358 size_t count); 358 size_t count);
359static ssize_t rbd_remove(struct bus_type *bus, const char *buf, 359static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
360 size_t count); 360 size_t count);
361static int rbd_dev_image_probe(struct rbd_device *rbd_dev); 361static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping);
362 362
363static struct bus_attribute rbd_bus_attrs[] = { 363static struct bus_attribute rbd_bus_attrs[] = {
364 __ATTR(add, S_IWUSR, NULL, rbd_add), 364 __ATTR(add, S_IWUSR, NULL, rbd_add),
@@ -2664,7 +2664,7 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
2664 * Request sync osd watch/unwatch. The value of "start" determines 2664 * Request sync osd watch/unwatch. The value of "start" determines
2665 * whether a watch request is being initiated or torn down. 2665 * whether a watch request is being initiated or torn down.
2666 */ 2666 */
2667static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) 2667static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, bool start)
2668{ 2668{
2669 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; 2669 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
2670 struct rbd_obj_request *obj_request; 2670 struct rbd_obj_request *obj_request;
@@ -2698,7 +2698,7 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start)
2698 rbd_dev->watch_request->osd_req); 2698 rbd_dev->watch_request->osd_req);
2699 2699
2700 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH, 2700 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH,
2701 rbd_dev->watch_event->cookie, 0, start); 2701 rbd_dev->watch_event->cookie, 0, start ? 1 : 0);
2702 rbd_osd_req_format_write(obj_request); 2702 rbd_osd_req_format_write(obj_request);
2703 2703
2704 ret = rbd_obj_request_submit(osdc, obj_request); 2704 ret = rbd_obj_request_submit(osdc, obj_request);
@@ -4549,7 +4549,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
4549 if (!parent) 4549 if (!parent)
4550 goto out_err; 4550 goto out_err;
4551 4551
4552 ret = rbd_dev_image_probe(parent); 4552 ret = rbd_dev_image_probe(parent, false);
4553 if (ret < 0) 4553 if (ret < 0)
4554 goto out_err; 4554 goto out_err;
4555 rbd_dev->parent = parent; 4555 rbd_dev->parent = parent;
@@ -4654,12 +4654,7 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
4654 4654
4655static void rbd_dev_image_release(struct rbd_device *rbd_dev) 4655static void rbd_dev_image_release(struct rbd_device *rbd_dev)
4656{ 4656{
4657 int ret;
4658
4659 rbd_dev_unprobe(rbd_dev); 4657 rbd_dev_unprobe(rbd_dev);
4660 ret = rbd_dev_header_watch_sync(rbd_dev, 0);
4661 if (ret)
4662 rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
4663 kfree(rbd_dev->header_name); 4658 kfree(rbd_dev->header_name);
4664 rbd_dev->header_name = NULL; 4659 rbd_dev->header_name = NULL;
4665 rbd_dev->image_format = 0; 4660 rbd_dev->image_format = 0;
@@ -4671,9 +4666,11 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
4671 4666
4672/* 4667/*
4673 * Probe for the existence of the header object for the given rbd 4668 * Probe for the existence of the header object for the given rbd
4674 * device. 4669 * device. If this image is the one being mapped (i.e., not a
4670 * parent), initiate a watch on its header object before using that
4671 * object to get detailed information about the rbd image.
4675 */ 4672 */
4676static int rbd_dev_image_probe(struct rbd_device *rbd_dev) 4673static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
4677{ 4674{
4678 int ret; 4675 int ret;
4679 int tmp; 4676 int tmp;
@@ -4693,9 +4690,11 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
4693 if (ret) 4690 if (ret)
4694 goto err_out_format; 4691 goto err_out_format;
4695 4692
4696 ret = rbd_dev_header_watch_sync(rbd_dev, 1); 4693 if (mapping) {
4697 if (ret) 4694 ret = rbd_dev_header_watch_sync(rbd_dev, true);
4698 goto out_header_name; 4695 if (ret)
4696 goto out_header_name;
4697 }
4699 4698
4700 if (rbd_dev->image_format == 1) 4699 if (rbd_dev->image_format == 1)
4701 ret = rbd_dev_v1_header_info(rbd_dev); 4700 ret = rbd_dev_v1_header_info(rbd_dev);
@@ -4719,9 +4718,12 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
4719err_out_probe: 4718err_out_probe:
4720 rbd_dev_unprobe(rbd_dev); 4719 rbd_dev_unprobe(rbd_dev);
4721err_out_watch: 4720err_out_watch:
4722 tmp = rbd_dev_header_watch_sync(rbd_dev, 0); 4721 if (mapping) {
4723 if (tmp) 4722 tmp = rbd_dev_header_watch_sync(rbd_dev, false);
4724 rbd_warn(rbd_dev, "unable to tear down watch request\n"); 4723 if (tmp)
4724 rbd_warn(rbd_dev, "unable to tear down "
4725 "watch request (%d)\n", tmp);
4726 }
4725out_header_name: 4727out_header_name:
4726 kfree(rbd_dev->header_name); 4728 kfree(rbd_dev->header_name);
4727 rbd_dev->header_name = NULL; 4729 rbd_dev->header_name = NULL;
@@ -4788,7 +4790,7 @@ static ssize_t rbd_add(struct bus_type *bus,
4788 rbdc = NULL; /* rbd_dev now owns this */ 4790 rbdc = NULL; /* rbd_dev now owns this */
4789 spec = NULL; /* rbd_dev now owns this */ 4791 spec = NULL; /* rbd_dev now owns this */
4790 4792
4791 rc = rbd_dev_image_probe(rbd_dev); 4793 rc = rbd_dev_image_probe(rbd_dev, true);
4792 if (rc < 0) 4794 if (rc < 0)
4793 goto err_out_rbd_dev; 4795 goto err_out_rbd_dev;
4794 4796
@@ -4910,10 +4912,13 @@ static ssize_t rbd_remove(struct bus_type *bus,
4910 spin_unlock_irq(&rbd_dev->lock); 4912 spin_unlock_irq(&rbd_dev->lock);
4911 if (ret < 0) 4913 if (ret < 0)
4912 goto done; 4914 goto done;
4913 ret = count;
4914 rbd_bus_del_dev(rbd_dev); 4915 rbd_bus_del_dev(rbd_dev);
4916 ret = rbd_dev_header_watch_sync(rbd_dev, false);
4917 if (ret)
4918 rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
4915 rbd_dev_image_release(rbd_dev); 4919 rbd_dev_image_release(rbd_dev);
4916 module_put(THIS_MODULE); 4920 module_put(THIS_MODULE);
4921 ret = count;
4917done: 4922done:
4918 mutex_unlock(&ctl_mutex); 4923 mutex_unlock(&ctl_mutex);
4919 4924