[SCSI] fix scsi process problems and clean up the target reap issues
In order to use the new execute_in_process_context() API, you have to provide it with the work storage, which I do in SCSI in scsi_device and scsi_target, but which also means that we can no longer queue up the target reaps, so instead I moved the target to a state model which allows target_alloc to detect if we've received a dying target and wait for it to be gone. Hopefully, this should also solve the target namespace race. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:

committed by
James Bottomley

parent
1fa44ecad2
commit
ffedb45225
@@ -2257,61 +2257,3 @@ scsi_target_unblock(struct device *dev)
|
||||
device_for_each_child(dev, NULL, target_unblock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scsi_target_unblock);
|
||||
|
||||
|
||||
struct work_queue_work {
|
||||
struct work_struct work;
|
||||
void (*fn)(void *);
|
||||
void *data;
|
||||
};
|
||||
|
||||
static void execute_in_process_context_work(void *data)
|
||||
{
|
||||
void (*fn)(void *data);
|
||||
struct work_queue_work *wqw = data;
|
||||
|
||||
fn = wqw->fn;
|
||||
data = wqw->data;
|
||||
|
||||
kfree(wqw);
|
||||
|
||||
fn(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* scsi_execute_in_process_context - reliably execute the routine with user context
|
||||
* @fn: the function to execute
|
||||
* @data: data to pass to the function
|
||||
*
|
||||
* Executes the function immediately if process context is available,
|
||||
* otherwise schedules the function for delayed execution.
|
||||
*
|
||||
* Returns: 0 - function was executed
|
||||
* 1 - function was scheduled for execution
|
||||
* <0 - error
|
||||
*/
|
||||
int scsi_execute_in_process_context(void (*fn)(void *data), void *data)
|
||||
{
|
||||
struct work_queue_work *wqw;
|
||||
|
||||
if (!in_interrupt()) {
|
||||
fn(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC);
|
||||
|
||||
if (unlikely(!wqw)) {
|
||||
printk(KERN_ERR "Failed to allocate memory\n");
|
||||
WARN_ON(1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_WORK(&wqw->work, execute_in_process_context_work, wqw);
|
||||
wqw->fn = fn;
|
||||
wqw->data = data;
|
||||
schedule_work(&wqw->work);
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scsi_execute_in_process_context);
|
||||
|
Reference in New Issue
Block a user