From bdf2b26edf817c661f997fdb58bb15d07cec7e12 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Sat, 27 Apr 2013 09:59:30 -0500 Subject: [PATCH] --- yaml --- r: 373519 b: refs/heads/master c: 0d8189e175380c029a309f05f44e82bacf1c0404 h: refs/heads/master i: 373517: c4f41379867ec5fd4d06edbfaf8271729f152753 373515: 86c1088b101e79e5dccbb7bf2f85374a550bd5df 373511: 1af07313a59b2bbc9491fbc54c7bdedbb8d3d61e 373503: 74e2e03db4996e478715cbb55d610786a525ba67 v: v3 --- [refs] | 2 +- trunk/drivers/block/rbd.c | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index a417f7b56e94..c22a9185de60 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 332bb12db9459d52dfcdb278e7607351d2eff6ab +refs/heads/master: 0d8189e175380c029a309f05f44e82bacf1c0404 diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index 44739640d94f..738263f354f6 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -4729,6 +4729,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev) static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) { int ret; + int tmp; ret = rbd_dev_header_watch_sync(rbd_dev, 1); if (ret) @@ -4780,6 +4781,9 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) unregister_blkdev(rbd_dev->major, rbd_dev->name); err_out_id: rbd_dev_id_put(rbd_dev); + tmp = rbd_dev_header_watch_sync(rbd_dev, 0); + if (tmp) + rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret); rbd_dev_mapping_clear(rbd_dev); return ret; @@ -4975,9 +4979,6 @@ static void rbd_dev_release(struct device *dev) { struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); - if (rbd_dev->watch_event) - rbd_dev_header_watch_sync(rbd_dev, 0); - /* clean up and free blkdev */ rbd_free_disk(rbd_dev); unregister_blkdev(rbd_dev->major, rbd_dev->name); @@ -5003,6 +5004,7 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) struct rbd_device *first = rbd_dev; struct rbd_device *second = first->parent; struct rbd_device *third; + int ret; /* * Follow to the parent with no grandparent and @@ -5013,6 +5015,10 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) second = third; } rbd_assert(second); + ret = rbd_dev_header_watch_sync(rbd_dev, 0); + if (ret) + rbd_warn(rbd_dev, + "failed to cancel watch event (%d)\n", ret); rbd_remove_all_snaps(second); rbd_bus_del_dev(second); first->parent = NULL; @@ -5029,13 +5035,13 @@ static ssize_t rbd_remove(struct bus_type *bus, size_t count) { struct rbd_device *rbd_dev = NULL; - int target_id, rc; + int target_id; unsigned long ul; - int ret = count; + int ret; - rc = strict_strtoul(buf, 10, &ul); - if (rc) - return rc; + ret = strict_strtoul(buf, 10, &ul); + if (ret) + return ret; /* convert to int; abort if we lost anything in the conversion */ target_id = (int) ul; @@ -5059,6 +5065,15 @@ static ssize_t rbd_remove(struct bus_type *bus, if (ret < 0) goto done; + ret = rbd_dev_header_watch_sync(rbd_dev, 0); + if (ret) { + rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret); + clear_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags); + smp_mb(); + return ret; + } + ret = count; + rbd_dev_remove_parent(rbd_dev); rbd_remove_all_snaps(rbd_dev);