diff options
-rw-r--r-- | drivers/block/nvme-core.c | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 23728099e36f..cd39390710a0 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
@@ -1716,10 +1716,31 @@ static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode, | |||
1716 | #define nvme_compat_ioctl NULL | 1716 | #define nvme_compat_ioctl NULL |
1717 | #endif | 1717 | #endif |
1718 | 1718 | ||
1719 | static int nvme_open(struct block_device *bdev, fmode_t mode) | ||
1720 | { | ||
1721 | struct nvme_ns *ns = bdev->bd_disk->private_data; | ||
1722 | struct nvme_dev *dev = ns->dev; | ||
1723 | |||
1724 | kref_get(&dev->kref); | ||
1725 | return 0; | ||
1726 | } | ||
1727 | |||
1728 | static void nvme_free_dev(struct kref *kref); | ||
1729 | |||
1730 | static void nvme_release(struct gendisk *disk, fmode_t mode) | ||
1731 | { | ||
1732 | struct nvme_ns *ns = disk->private_data; | ||
1733 | struct nvme_dev *dev = ns->dev; | ||
1734 | |||
1735 | kref_put(&dev->kref, nvme_free_dev); | ||
1736 | } | ||
1737 | |||
1719 | static const struct block_device_operations nvme_fops = { | 1738 | static const struct block_device_operations nvme_fops = { |
1720 | .owner = THIS_MODULE, | 1739 | .owner = THIS_MODULE, |
1721 | .ioctl = nvme_ioctl, | 1740 | .ioctl = nvme_ioctl, |
1722 | .compat_ioctl = nvme_compat_ioctl, | 1741 | .compat_ioctl = nvme_compat_ioctl, |
1742 | .open = nvme_open, | ||
1743 | .release = nvme_release, | ||
1723 | }; | 1744 | }; |
1724 | 1745 | ||
1725 | static void nvme_resubmit_bios(struct nvme_queue *nvmeq) | 1746 | static void nvme_resubmit_bios(struct nvme_queue *nvmeq) |
@@ -1849,13 +1870,6 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1849 | return NULL; | 1870 | return NULL; |
1850 | } | 1871 | } |
1851 | 1872 | ||
1852 | static void nvme_ns_free(struct nvme_ns *ns) | ||
1853 | { | ||
1854 | put_disk(ns->disk); | ||
1855 | blk_cleanup_queue(ns->queue); | ||
1856 | kfree(ns); | ||
1857 | } | ||
1858 | |||
1859 | static int set_queue_count(struct nvme_dev *dev, int count) | 1873 | static int set_queue_count(struct nvme_dev *dev, int count) |
1860 | { | 1874 | { |
1861 | int status; | 1875 | int status; |
@@ -2287,12 +2301,13 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
2287 | 2301 | ||
2288 | static void nvme_dev_remove(struct nvme_dev *dev) | 2302 | static void nvme_dev_remove(struct nvme_dev *dev) |
2289 | { | 2303 | { |
2290 | struct nvme_ns *ns, *next; | 2304 | struct nvme_ns *ns; |
2291 | 2305 | ||
2292 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | 2306 | list_for_each_entry(ns, &dev->namespaces, list) { |
2293 | list_del(&ns->list); | 2307 | if (ns->disk->flags & GENHD_FL_UP) |
2294 | del_gendisk(ns->disk); | 2308 | del_gendisk(ns->disk); |
2295 | nvme_ns_free(ns); | 2309 | if (!blk_queue_dying(ns->queue)) |
2310 | blk_cleanup_queue(ns->queue); | ||
2296 | } | 2311 | } |
2297 | } | 2312 | } |
2298 | 2313 | ||
@@ -2349,9 +2364,22 @@ static void nvme_release_instance(struct nvme_dev *dev) | |||
2349 | spin_unlock(&dev_list_lock); | 2364 | spin_unlock(&dev_list_lock); |
2350 | } | 2365 | } |
2351 | 2366 | ||
2367 | static void nvme_free_namespaces(struct nvme_dev *dev) | ||
2368 | { | ||
2369 | struct nvme_ns *ns, *next; | ||
2370 | |||
2371 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | ||
2372 | list_del(&ns->list); | ||
2373 | put_disk(ns->disk); | ||
2374 | kfree(ns); | ||
2375 | } | ||
2376 | } | ||
2377 | |||
2352 | static void nvme_free_dev(struct kref *kref) | 2378 | static void nvme_free_dev(struct kref *kref) |
2353 | { | 2379 | { |
2354 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); | 2380 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); |
2381 | |||
2382 | nvme_free_namespaces(dev); | ||
2355 | kfree(dev->queues); | 2383 | kfree(dev->queues); |
2356 | kfree(dev->entry); | 2384 | kfree(dev->entry); |
2357 | kfree(dev); | 2385 | kfree(dev); |
@@ -2525,6 +2553,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2525 | goto release_pools; | 2553 | goto release_pools; |
2526 | } | 2554 | } |
2527 | 2555 | ||
2556 | kref_init(&dev->kref); | ||
2528 | result = nvme_dev_add(dev); | 2557 | result = nvme_dev_add(dev); |
2529 | if (result) | 2558 | if (result) |
2530 | goto shutdown; | 2559 | goto shutdown; |
@@ -2540,11 +2569,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2540 | goto remove; | 2569 | goto remove; |
2541 | 2570 | ||
2542 | dev->initialized = 1; | 2571 | dev->initialized = 1; |
2543 | kref_init(&dev->kref); | ||
2544 | return 0; | 2572 | return 0; |
2545 | 2573 | ||
2546 | remove: | 2574 | remove: |
2547 | nvme_dev_remove(dev); | 2575 | nvme_dev_remove(dev); |
2576 | nvme_free_namespaces(dev); | ||
2548 | shutdown: | 2577 | shutdown: |
2549 | nvme_dev_shutdown(dev); | 2578 | nvme_dev_shutdown(dev); |
2550 | release_pools: | 2579 | release_pools: |