block/sed-opal: Introduce free_opal_dev to free the structure and clean up state

Before we free the opal structure we need to clean up any saved
locking ranges that the user had told us to unlock from a suspend.

Signed-off-by: Scott Bauer <scott.bauer@intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Scott Bauer 2017-02-22 10:15:06 -07:00 committed by Jens Axboe
parent 124298bd03
commit 7d6d15789d
2 changed files with 35 additions and 0 deletions

View File

@ -1987,6 +1987,28 @@ static int check_opal_support(struct opal_dev *dev)
return ret; return ret;
} }
static void clean_opal_dev(struct opal_dev *dev)
{
struct opal_suspend_data *suspend, *next;
mutex_lock(&dev->dev_lock);
list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
list_del(&suspend->node);
kfree(suspend);
}
mutex_unlock(&dev->dev_lock);
}
void free_opal_dev(struct opal_dev *dev)
{
if (!dev)
return;
clean_opal_dev(dev);
kfree(dev);
}
EXPORT_SYMBOL(free_opal_dev);
struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv) struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
{ {
struct opal_dev *dev; struct opal_dev *dev;
@ -2141,6 +2163,14 @@ static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
setup_opal_dev(dev, revert_steps); setup_opal_dev(dev, revert_steps);
ret = next(dev); ret = next(dev);
mutex_unlock(&dev->dev_lock); mutex_unlock(&dev->dev_lock);
/*
* If we successfully reverted lets clean
* any saved locking ranges.
*/
if (!ret)
clean_opal_dev(dev);
return ret; return ret;
} }

View File

@ -27,6 +27,7 @@ typedef int (sec_send_recv)(void *data, u16 spsp, u8 secp, void *buffer,
size_t len, bool send); size_t len, bool send);
#ifdef CONFIG_BLK_SED_OPAL #ifdef CONFIG_BLK_SED_OPAL
void free_opal_dev(struct opal_dev *dev);
bool opal_unlock_from_suspend(struct opal_dev *dev); bool opal_unlock_from_suspend(struct opal_dev *dev);
struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv); struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv);
int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *ioctl_ptr); int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *ioctl_ptr);
@ -51,6 +52,10 @@ static inline bool is_sed_ioctl(unsigned int cmd)
return false; return false;
} }
#else #else
static inline void free_opal_dev(struct opal_dev *dev)
{
}
static inline bool is_sed_ioctl(unsigned int cmd) static inline bool is_sed_ioctl(unsigned int cmd)
{ {
return false; return false;