[dm-devel] [PATCH] scsi-dh-emc: fix activate vs set_params race
Mikulas Patocka
mpatocka at redhat.com
Wed Apr 3 00:09:26 UTC 2013
Hi
This fixes a possible race in scsi_dh_emc. It is untested because I don't
have the hardware. It could happen when we reload a multipath device and
path failure happens at the same time.
This is a theoretical race condition (there are no reports of it
hapenning), but a different bug was already triggered under the same
conditions in QA testing.
Mikulas
---
scsi-dh-emc: fix activate vs set_params race
The activate routine may be called concurrently with the set_params
routine. This can happen when dm-multipath device is reloaded. When we
reload a device mapper device, the new target instance is being created
(that could call the set_params method) while the old target instance is
still active (that could call the activate method).
The activate and set_params routine share the same data and sense buffer,
so it could result in incorrect behaviour if they are called concurrently.
This patch adds a mutex to fix the race.
Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
---
drivers/scsi/device_handler/scsi_dh_emc.c | 11 +++++++++++
1 file changed, 11 insertions(+)
Index: linux-3.9-rc5-fast/drivers/scsi/device_handler/scsi_dh_emc.c
===================================================================
--- linux-3.9-rc5-fast.orig/drivers/scsi/device_handler/scsi_dh_emc.c 2013-04-03 01:32:16.000000000 +0200
+++ linux-3.9-rc5-fast/drivers/scsi/device_handler/scsi_dh_emc.c 2013-04-03 01:45:13.000000000 +0200
@@ -111,6 +111,8 @@ struct clariion_dh_data {
* path's mapped LUN
*/
int current_sp;
+
+ struct mutex mtx;
};
static inline struct clariion_dh_data
@@ -536,6 +538,8 @@ static int clariion_activate(struct scsi
struct clariion_dh_data *csdev = get_clariion_data(sdev);
int result;
+ mutex_lock(&csdev->mtx);
+
result = clariion_send_inquiry(sdev, csdev);
if (result != SCSI_DH_OK)
goto done;
@@ -562,6 +566,8 @@ done:
csdev->port, lun_state[csdev->lun_state],
csdev->default_sp + 'A');
+ mutex_unlock(&csdev->mtx);
+
if (fn)
fn(data, result);
return 0;
@@ -602,6 +608,8 @@ static int clariion_set_params(struct sc
else
csdev->flags &= ~CLARIION_HONOR_RESERVATIONS;
+ mutex_lock(&csdev->mtx);
+
/*
* If this path is owned, we have to send a trespass command
* with the new parameters. If not, simply return. Next trespass
@@ -618,6 +626,8 @@ static int clariion_set_params(struct sc
/* Update status */
result = clariion_send_inquiry(sdev, csdev);
+ mutex_unlock(&csdev->mtx);
+
done:
return result;
}
@@ -683,6 +693,7 @@ static int clariion_bus_attach(struct sc
h->lun_state = CLARIION_LUN_UNINITIALIZED;
h->default_sp = CLARIION_UNBOUND_LU;
h->current_sp = CLARIION_UNBOUND_LU;
+ mutex_init(&h->mtx);
err = clariion_std_inquiry(sdev, h);
if (err != SCSI_DH_OK)
More information about the dm-devel
mailing list