aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/core.c
diff options
context:
space:
mode:
authorMatias Bjørling <m@bjorling.me>2016-01-12 01:49:39 -0500
committerJens Axboe <axboe@fb.com>2016-01-12 10:21:18 -0500
commit8b4970c41f88ad772771f87b1c82c395248a84d8 (patch)
tree4667e602605483b9be057e43ecbd57f4a2f0a047 /drivers/lightnvm/core.c
parentb769207678176d590ea61ce7a64c9100925668b7 (diff)
lightnvm: introduce factory reset
Now that a device can be managed using the system blocks, a method to reset the device is necessary as well. This patch introduces logic to reset the device easily to factory state and exposes it through an ioctl. The ioctl takes the following flags: NVM_FACTORY_ERASE_ONLY_USER By default all blocks, except host-reserved blocks are erased upon factory reset. Instead of this, only erase host-reserved blocks. NVM_FACTORY_RESET_HOST_BLKS Mark host-reserved blocks to be erased and set their type to free. NVM_FACTORY_RESET_GRWN_BBLKS Mark "grown bad blocks" to be erased and set their type to free. Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm/core.c')
-rw-r--r--drivers/lightnvm/core.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 9e5712dda062..33224cb91c5b 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -1088,6 +1088,38 @@ static long nvm_ioctl_dev_init(struct file *file, void __user *arg)
1088 return __nvm_ioctl_dev_init(&init); 1088 return __nvm_ioctl_dev_init(&init);
1089} 1089}
1090 1090
1091static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
1092{
1093 struct nvm_ioctl_dev_factory fact;
1094 struct nvm_dev *dev;
1095
1096 if (!capable(CAP_SYS_ADMIN))
1097 return -EPERM;
1098
1099 if (copy_from_user(&fact, arg, sizeof(struct nvm_ioctl_dev_factory)))
1100 return -EFAULT;
1101
1102 fact.dev[DISK_NAME_LEN - 1] = '\0';
1103
1104 if (fact.flags & ~(NVM_FACTORY_NR_BITS - 1))
1105 return -EINVAL;
1106
1107 down_write(&nvm_lock);
1108 dev = nvm_find_nvm_dev(fact.dev);
1109 up_write(&nvm_lock);
1110 if (!dev) {
1111 pr_err("nvm: device not found\n");
1112 return -EINVAL;
1113 }
1114
1115 if (dev->mt) {
1116 dev->mt->unregister_mgr(dev);
1117 dev->mt = NULL;
1118 }
1119
1120 return nvm_dev_factory(dev, fact.flags);
1121}
1122
1091static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg) 1123static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg)
1092{ 1124{
1093 void __user *argp = (void __user *)arg; 1125 void __user *argp = (void __user *)arg;
@@ -1103,6 +1135,8 @@ static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg)
1103 return nvm_ioctl_dev_remove(file, argp); 1135 return nvm_ioctl_dev_remove(file, argp);
1104 case NVM_DEV_INIT: 1136 case NVM_DEV_INIT:
1105 return nvm_ioctl_dev_init(file, argp); 1137 return nvm_ioctl_dev_init(file, argp);
1138 case NVM_DEV_FACTORY:
1139 return nvm_ioctl_dev_factory(file, argp);
1106 } 1140 }
1107 return 0; 1141 return 0;
1108} 1142}