@@ -12,6 +12,7 @@
#include <linux/blkdev.h>
#include <linux/device.h>
#include <linux/pm_runtime.h>
+#include <linux/task_work.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
@@ -705,13 +706,26 @@ store_rescan_field (struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
+static void sdev_remove_self(struct callback_head *cb)
+{
+ struct scsi_device *sdev =
+ container_of(cb, struct scsi_device, delete_work);
+
+ scsi_remove_device(sdev);
+}
+
static ssize_t
sdev_store_delete(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- if (device_remove_file_self(dev, attr))
- scsi_remove_device(to_scsi_device(dev));
- return count;
+ struct scsi_device *sdev = to_scsi_device(dev);
+ ssize_t err;
+
+ init_task_work(&sdev->delete_work, sdev_remove_self);
+ err = task_work_add(current, &sdev->delete_work, false);
+ if (!err)
+ err = count;
+ return err;
};
static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
@@ -206,6 +206,7 @@ struct scsi_device {
struct scsi_device_handler *handler;
void *handler_data;
+ struct callback_head delete_work;
unsigned char access_state;
enum scsi_device_state sdev_state;
unsigned long sdev_data[0];