diff options
author | Christoph Hellwig <hch@lst.de> | 2017-10-18 13:22:00 +0200 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2017-10-27 08:03:31 +0200 |
commit | c6424a90da446cff6c67be06767fc0d0be787110 (patch) | |
tree | fe842372c8f6fea4b651d420ee08c8d6c1ac9a60 /drivers/nvme | |
parent | nvme: use kref_get_unless_zero in nvme_find_get_ns (diff) | |
download | linux-c6424a90da446cff6c67be06767fc0d0be787110.tar.xz linux-c6424a90da446cff6c67be06767fc0d0be787110.zip |
nvme: simplify nvme_open
Now that we are protected against lookup vs free races for the namespace
by using kref_get_unless_zero we don't need the hack of NULLing out the
disk private data during removal.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Diffstat (limited to 'drivers/nvme')
-rw-r--r-- | drivers/nvme/host/core.c | 40 |
1 files changed, 10 insertions, 30 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1d931deac83b..9f8ae15c9fe8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -253,12 +253,6 @@ static void nvme_free_ns(struct kref *kref) if (ns->ndev) nvme_nvm_unregister(ns); - if (ns->disk) { - spin_lock(&dev_list_lock); - ns->disk->private_data = NULL; - spin_unlock(&dev_list_lock); - } - put_disk(ns->disk); ida_simple_remove(&ns->ctrl->ns_ida, ns->instance); nvme_put_ctrl(ns->ctrl); @@ -270,29 +264,6 @@ static void nvme_put_ns(struct nvme_ns *ns) kref_put(&ns->kref, nvme_free_ns); } -static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk) -{ - struct nvme_ns *ns; - - spin_lock(&dev_list_lock); - ns = disk->private_data; - if (ns) { - if (!kref_get_unless_zero(&ns->kref)) - goto fail; - if (!try_module_get(ns->ctrl->ops->module)) - goto fail_put_ns; - } - spin_unlock(&dev_list_lock); - - return ns; - -fail_put_ns: - kref_put(&ns->kref, nvme_free_ns); -fail: - spin_unlock(&dev_list_lock); - return NULL; -} - struct request *nvme_alloc_request(struct request_queue *q, struct nvme_command *cmd, unsigned int flags, int qid) { @@ -1056,7 +1027,16 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, static int nvme_open(struct block_device *bdev, fmode_t mode) { - return nvme_get_ns_from_disk(bdev->bd_disk) ? 0 : -ENXIO; + struct nvme_ns *ns = bdev->bd_disk->private_data; + + if (!kref_get_unless_zero(&ns->kref)) + return -ENXIO; + if (!try_module_get(ns->ctrl->ops->module)) { + kref_put(&ns->kref, nvme_free_ns); + return -ENXIO; + } + + return 0; } static void nvme_release(struct gendisk *disk, fmode_t mode) |