2010-07-07 11:12:45 +00:00
|
|
|
From: Hannes Reinecke <hare@suse.de>
|
|
|
|
Subject: DM-MPIO fails to tresspass LUNs on CLARiiON arrays
|
|
|
|
Reference: bnc#484529
|
|
|
|
Patch-mainline: Not yet
|
|
|
|
|
|
|
|
On Clariion arrays we fail to send the trespass command correctly.
|
|
|
|
We're trying to send the trespass command to via an disabled path,
|
|
|
|
causing the device handler to loop trying to send the command on
|
|
|
|
an invalid path.
|
|
|
|
|
|
|
|
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
|
|
|
|
|
|
|
---
|
|
|
|
drivers/md/dm-mpath.c | 12 +++++++++---
|
|
|
|
drivers/md/dm-table.c | 12 ++++++++----
|
|
|
|
2 files changed, 17 insertions(+), 7 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/md/dm-mpath.c
|
|
|
|
+++ b/drivers/md/dm-mpath.c
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -1230,8 +1230,9 @@ static void pg_init_done(void *data, int
|
2010-07-07 11:12:45 +00:00
|
|
|
errors = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
- DMERR("Could not failover the device: Handler scsi_dh_%s "
|
|
|
|
- "Error %d.", m->hw_handler_name, errors);
|
|
|
|
+ DMERR("Count not failover device %s: Handler scsi_dh_%s "
|
|
|
|
+ "was not loaded.", pgpath->path.pdev,
|
|
|
|
+ m->hw_handler_name);
|
|
|
|
/*
|
|
|
|
* Fail path for now, so we do not ping pong
|
|
|
|
*/
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -1244,6 +1245,10 @@ static void pg_init_done(void *data, int
|
2010-07-07 11:12:45 +00:00
|
|
|
*/
|
|
|
|
bypass_pg(m, pg, 1);
|
|
|
|
break;
|
|
|
|
+ case SCSI_DH_DEV_OFFLINED:
|
|
|
|
+ DMWARN("Device %s offlined.", pgpath->path.pdev);
|
|
|
|
+ errors = 0;
|
|
|
|
+ break;
|
|
|
|
case SCSI_DH_RETRY:
|
2011-04-19 20:09:59 +00:00
|
|
|
/* Wait before retrying. */
|
|
|
|
delay_retry = 1;
|
|
|
|
@@ -1264,7 +1269,8 @@ static void pg_init_done(void *data, int
|
2010-07-07 11:12:45 +00:00
|
|
|
spin_lock_irqsave(&m->lock, flags);
|
|
|
|
if (errors) {
|
|
|
|
if (pgpath == m->current_pgpath) {
|
|
|
|
- DMERR("Could not failover device. Error %d.", errors);
|
|
|
|
+ DMERR("Could not failover device %s, error %d.",
|
|
|
|
+ pgpath->path.pdev, errors);
|
|
|
|
m->current_pgpath = NULL;
|
|
|
|
m->current_pg = NULL;
|
|
|
|
}
|
|
|
|
--- a/drivers/md/dm-table.c
|
|
|
|
+++ b/drivers/md/dm-table.c
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -414,14 +414,18 @@ static int upgrade_mode(struct dm_dev_in
|
2010-07-07 11:12:45 +00:00
|
|
|
|
|
|
|
dd_new = dd_old = *dd;
|
|
|
|
|
|
|
|
- dd_new.dm_dev.mode |= new_mode;
|
|
|
|
+ dd_new.dm_dev.mode = new_mode;
|
|
|
|
dd_new.dm_dev.bdev = NULL;
|
|
|
|
|
|
|
|
r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
|
|
|
|
- if (r)
|
|
|
|
+ if (r == -EROFS) {
|
|
|
|
+ dd_new.dm_dev.mode &= ~FMODE_WRITE;
|
|
|
|
+ r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
|
|
|
|
+ }
|
|
|
|
+ if (!r)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
- dd->dm_dev.mode |= new_mode;
|
|
|
|
+ dd->dm_dev.mode = new_mode;
|
|
|
|
close_dev(&dd_old, md);
|
|
|
|
|
|
|
|
return 0;
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -483,7 +487,7 @@ static int __table_get_device(struct dm_
|
2010-07-07 11:12:45 +00:00
|
|
|
atomic_set(&dd->count, 0);
|
|
|
|
list_add(&dd->list, &t->devices);
|
|
|
|
|
|
|
|
- } else if (dd->dm_dev.mode != (mode | dd->dm_dev.mode)) {
|
|
|
|
+ } else if (dd->dm_dev.mode != mode) {
|
|
|
|
r = upgrade_mode(dd, mode, t->md);
|
|
|
|
if (r)
|
|
|
|
return r;
|