Browse Source

[SCSI] ipr: Fix a race on multiple configuration changes

In a multiple configuration change scenario a remove notification can be
followed by an immediate add notification for the same device, which
will cause the device to be removed but never added back. This patch
fixes the problem by ensuring that in such situations the device will be
added back.

Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com>
Acked-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Kleber Sacilotto de Souza 14 years ago
parent
commit
5767a1c498
1 changed files with 5 additions and 2 deletions
  1. 5 2
      drivers/scsi/ipr.c

+ 5 - 2
drivers/scsi/ipr.c

@@ -1301,7 +1301,7 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
 			ipr_clear_res_target(res);
 			ipr_clear_res_target(res);
 			list_move_tail(&res->queue, &ioa_cfg->free_res_q);
 			list_move_tail(&res->queue, &ioa_cfg->free_res_q);
 		}
 		}
-	} else if (!res->sdev) {
+	} else if (!res->sdev || res->del_from_ml) {
 		res->add_to_ml = 1;
 		res->add_to_ml = 1;
 		if (ioa_cfg->allow_ml_add_del)
 		if (ioa_cfg->allow_ml_add_del)
 			schedule_work(&ioa_cfg->work_q);
 			schedule_work(&ioa_cfg->work_q);
@@ -3104,7 +3104,10 @@ restart:
 				did_work = 1;
 				did_work = 1;
 				sdev = res->sdev;
 				sdev = res->sdev;
 				if (!scsi_device_get(sdev)) {
 				if (!scsi_device_get(sdev)) {
-					list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+					if (!res->add_to_ml)
+						list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+					else
+						res->del_from_ml = 0;
 					spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 					spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 					scsi_remove_device(sdev);
 					scsi_remove_device(sdev);
 					scsi_device_put(sdev);
 					scsi_device_put(sdev);