diff options
author | Matias Bjørling <m@bjorling.me> | 2016-09-16 08:25:07 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-09-21 09:56:18 -0400 |
commit | b0b4e09c1ae71c4ec33df0616b830ae050006e9b (patch) | |
tree | 67a148740845d77af662b36ec17d88f991c84d72 /drivers/lightnvm | |
parent | b21d5b301794ae332eaa6e177d71fe8b77d3664c (diff) |
lightnvm: control life of nvm_dev in driver
LightNVM compatible device drivers does not have a method to expose
LightNVM specific sysfs entries.
To enable LightNVM sysfs entries to be exposed, lightnvm device
drivers require a struct device to attach it to. To allow both the
actual device driver and lightnvm sysfs entries to coexist, the device
driver tracks the lifetime of the nvm_dev structure.
This patch refactors NVMe and null_blk to handle the lifetime of struct
nvm_dev, which eliminates the need for struct gendisk when a lightnvm
compatible device is provided.
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r-- | drivers/lightnvm/core.c | 35 |
1 files changed, 8 insertions, 27 deletions
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 25c5df920326..a99b59d1eb36 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c | |||
@@ -660,22 +660,15 @@ static void nvm_exit(struct nvm_dev *dev) | |||
660 | pr_info("nvm: successfully unloaded\n"); | 660 | pr_info("nvm: successfully unloaded\n"); |
661 | } | 661 | } |
662 | 662 | ||
663 | int nvm_register(struct request_queue *q, char *disk_name, | 663 | struct nvm_dev *nvm_alloc_dev(int node) |
664 | struct nvm_dev_ops *ops) | ||
665 | { | 664 | { |
666 | struct nvm_dev *dev; | 665 | return kzalloc_node(sizeof(struct nvm_dev), GFP_KERNEL, node); |
667 | int ret; | 666 | } |
668 | 667 | EXPORT_SYMBOL(nvm_alloc_dev); | |
669 | if (!ops->identity) | ||
670 | return -EINVAL; | ||
671 | |||
672 | dev = kzalloc(sizeof(struct nvm_dev), GFP_KERNEL); | ||
673 | if (!dev) | ||
674 | return -ENOMEM; | ||
675 | 668 | ||
676 | dev->q = q; | 669 | int nvm_register(struct nvm_dev *dev) |
677 | dev->ops = ops; | 670 | { |
678 | strncpy(dev->name, disk_name, DISK_NAME_LEN); | 671 | int ret; |
679 | 672 | ||
680 | ret = nvm_init(dev); | 673 | ret = nvm_init(dev); |
681 | if (ret) | 674 | if (ret) |
@@ -714,29 +707,17 @@ int nvm_register(struct request_queue *q, char *disk_name, | |||
714 | return 0; | 707 | return 0; |
715 | err_init: | 708 | err_init: |
716 | kfree(dev->lun_map); | 709 | kfree(dev->lun_map); |
717 | kfree(dev); | ||
718 | return ret; | 710 | return ret; |
719 | } | 711 | } |
720 | EXPORT_SYMBOL(nvm_register); | 712 | EXPORT_SYMBOL(nvm_register); |
721 | 713 | ||
722 | void nvm_unregister(char *disk_name) | 714 | void nvm_unregister(struct nvm_dev *dev) |
723 | { | 715 | { |
724 | struct nvm_dev *dev; | ||
725 | |||
726 | down_write(&nvm_lock); | 716 | down_write(&nvm_lock); |
727 | dev = nvm_find_nvm_dev(disk_name); | ||
728 | if (!dev) { | ||
729 | pr_err("nvm: could not find device %s to unregister\n", | ||
730 | disk_name); | ||
731 | up_write(&nvm_lock); | ||
732 | return; | ||
733 | } | ||
734 | |||
735 | list_del(&dev->devices); | 717 | list_del(&dev->devices); |
736 | up_write(&nvm_lock); | 718 | up_write(&nvm_lock); |
737 | 719 | ||
738 | nvm_exit(dev); | 720 | nvm_exit(dev); |
739 | kfree(dev); | ||
740 | } | 721 | } |
741 | EXPORT_SYMBOL(nvm_unregister); | 722 | EXPORT_SYMBOL(nvm_unregister); |
742 | 723 | ||