diff options
| author | Christoph Hellwig <hch@lst.de> | 2019-05-17 05:47:33 -0400 |
|---|---|---|
| committer | Keith Busch <keith.busch@intel.com> | 2019-05-17 13:06:59 -0400 |
| commit | 100c815cbd56480b3e31518475b04719c363614a (patch) | |
| tree | a88268d32b052af56875655effd26ee1b34ba41b | |
| parent | 6fa0321a96043b5a983bbefa785859d664645840 (diff) | |
nvme: fix srcu locking on error return in nvme_get_ns_from_disk
If we can't get a namespace don't leak the SRCU lock. nvme_ioctl was
working around this, but nvme_pr_command wasn't handling this properly.
Just do what callers would usually expect.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <keith.busch@intel.com>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
| -rw-r--r-- | drivers/nvme/host/core.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 308b9ce820cd..421bffd95aee 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -1361,9 +1361,14 @@ static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk, | |||
| 1361 | { | 1361 | { |
| 1362 | #ifdef CONFIG_NVME_MULTIPATH | 1362 | #ifdef CONFIG_NVME_MULTIPATH |
| 1363 | if (disk->fops == &nvme_ns_head_ops) { | 1363 | if (disk->fops == &nvme_ns_head_ops) { |
| 1364 | struct nvme_ns *ns; | ||
| 1365 | |||
| 1364 | *head = disk->private_data; | 1366 | *head = disk->private_data; |
| 1365 | *srcu_idx = srcu_read_lock(&(*head)->srcu); | 1367 | *srcu_idx = srcu_read_lock(&(*head)->srcu); |
| 1366 | return nvme_find_path(*head); | 1368 | ns = nvme_find_path(*head); |
| 1369 | if (!ns) | ||
| 1370 | srcu_read_unlock(&(*head)->srcu, *srcu_idx); | ||
| 1371 | return ns; | ||
| 1367 | } | 1372 | } |
| 1368 | #endif | 1373 | #endif |
| 1369 | *head = NULL; | 1374 | *head = NULL; |
| @@ -1410,9 +1415,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 1410 | 1415 | ||
| 1411 | ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx); | 1416 | ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx); |
| 1412 | if (unlikely(!ns)) | 1417 | if (unlikely(!ns)) |
| 1413 | ret = -EWOULDBLOCK; | 1418 | return -EWOULDBLOCK; |
| 1414 | else | 1419 | |
| 1415 | ret = nvme_ns_ioctl(ns, cmd, arg); | 1420 | ret = nvme_ns_ioctl(ns, cmd, arg); |
| 1416 | nvme_put_ns_from_disk(head, srcu_idx); | 1421 | nvme_put_ns_from_disk(head, srcu_idx); |
| 1417 | return ret; | 1422 | return ret; |
| 1418 | } | 1423 | } |
