diff options
author | Alex Elder <elder@inktank.com> | 2013-05-06 18:40:33 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2013-05-08 21:16:55 -0400 |
commit | 1f3ef78861ac4b510175e177899b9b5ba4bbed91 (patch) | |
tree | edf2c0b20d647f495bf7d596f72b08349115d772 /drivers/block/rbd.c | |
parent | 7ce4eef7b5fad73b365b7e4b8892af3af72d4bd3 (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.c | 43 |
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); |
359 | static ssize_t rbd_remove(struct bus_type *bus, const char *buf, | 359 | static ssize_t rbd_remove(struct bus_type *bus, const char *buf, |
360 | size_t count); | 360 | size_t count); |
361 | static int rbd_dev_image_probe(struct rbd_device *rbd_dev); | 361 | static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping); |
362 | 362 | ||
363 | static struct bus_attribute rbd_bus_attrs[] = { | 363 | static 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 | */ |
2667 | static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) | 2667 | static 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 | ||
4655 | static void rbd_dev_image_release(struct rbd_device *rbd_dev) | 4655 | static 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 | */ |
4676 | static int rbd_dev_image_probe(struct rbd_device *rbd_dev) | 4673 | static 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) | |||
4719 | err_out_probe: | 4718 | err_out_probe: |
4720 | rbd_dev_unprobe(rbd_dev); | 4719 | rbd_dev_unprobe(rbd_dev); |
4721 | err_out_watch: | 4720 | err_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 | } | ||
4725 | out_header_name: | 4727 | out_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; | ||
4917 | done: | 4922 | done: |
4918 | mutex_unlock(&ctl_mutex); | 4923 | mutex_unlock(&ctl_mutex); |
4919 | 4924 | ||