aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-31 15:17:01 -0500
committerSage Weil <sage@inktank.com>2013-07-03 15:32:42 -0700
commit1ba0f1e7975ad07557f7a931522bdcd813ae35f6 (patch)
tree9203d8f6b37c07e699194e981c5b3828f678252b /drivers/block
parentrbd: protect against concurrent unmaps (diff)
downloadlinux-dev-1ba0f1e7975ad07557f7a931522bdcd813ae35f6.tar.xz
linux-dev-1ba0f1e7975ad07557f7a931522bdcd813ae35f6.zip
rbd: don't hold ctl_mutex to get/put device
When an rbd device is first getting mapped, its device registration is protected the control mutex. There is no need to do that though, because the device has already been assigned an id that's guaranteed to be unique. An unmap of an rbd device won't proceed if the device has a non-zero open count or is already being unmapped. So there's no need to hold the control mutex in that case either. Finally, an rbd device can't be opened if it is being removed, and it won't go away if there is a non-zero open count. So here too there's no need to hold the control mutex while getting or putting a reference to an rbd device's Linux device structure. Drop the mutex calls in these cases. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c17
1 files changed, 2 insertions, 15 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 305c740778c6..d735eb13847d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -489,10 +489,8 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
if (removing)
return -ENOENT;
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
(void) get_device(&rbd_dev->dev);
set_device_ro(bdev, rbd_dev->mapping.read_only);
- mutex_unlock(&ctl_mutex);
return 0;
}
@@ -507,9 +505,7 @@ static void rbd_release(struct gendisk *disk, fmode_t mode)
spin_unlock_irq(&rbd_dev->lock);
rbd_assert(open_count_before > 0);
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
put_device(&rbd_dev->dev);
- mutex_unlock(&ctl_mutex);
}
static const struct block_device_operations rbd_bd_ops = {
@@ -4332,8 +4328,6 @@ static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
struct device *dev;
int ret;
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
dev = &rbd_dev->dev;
dev->bus = &rbd_bus_type;
dev->type = &rbd_device_type;
@@ -4342,8 +4336,6 @@ static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
dev_set_name(dev, "%d", rbd_dev->dev_id);
ret = device_register(dev);
- mutex_unlock(&ctl_mutex);
-
return ret;
}
@@ -5149,8 +5141,6 @@ static ssize_t rbd_remove(struct bus_type *bus,
if (dev_id != ul)
return -EINVAL;
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
ret = -ENOENT;
spin_lock(&rbd_dev_list_lock);
list_for_each(tmp, &rbd_dev_list) {
@@ -5171,7 +5161,7 @@ static ssize_t rbd_remove(struct bus_type *bus,
}
spin_unlock(&rbd_dev_list_lock);
if (ret < 0 || already)
- goto done;
+ return ret;
rbd_bus_del_dev(rbd_dev);
ret = rbd_dev_header_watch_sync(rbd_dev, false);
@@ -5179,11 +5169,8 @@ static ssize_t rbd_remove(struct bus_type *bus,
rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
rbd_dev_image_release(rbd_dev);
module_put(THIS_MODULE);
- ret = count;
-done:
- mutex_unlock(&ctl_mutex);
- return ret;
+ return count;
}
/*