86 lines
2.5 KiB
Plaintext
86 lines
2.5 KiB
Plaintext
|
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
|
||
|
@@ -1228,8 +1228,9 @@ static void pg_init_done(void *data, int
|
||
|
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
|
||
|
*/
|
||
|
@@ -1242,6 +1243,10 @@ static void pg_init_done(void *data, int
|
||
|
*/
|
||
|
bypass_pg(m, pg, 1);
|
||
|
break;
|
||
|
+ case SCSI_DH_DEV_OFFLINED:
|
||
|
+ DMWARN("Device %s offlined.", pgpath->path.pdev);
|
||
|
+ errors = 0;
|
||
|
+ break;
|
||
|
/* TODO: For SCSI_DH_RETRY we should wait a couple seconds */
|
||
|
case SCSI_DH_RETRY:
|
||
|
case SCSI_DH_IMM_RETRY:
|
||
|
@@ -1262,7 +1267,8 @@ static void pg_init_done(void *data, int
|
||
|
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
|
||
|
@@ -411,14 +411,18 @@ static int upgrade_mode(struct dm_dev_in
|
||
|
|
||
|
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;
|
||
|
@@ -480,7 +484,7 @@ static int __table_get_device(struct dm_
|
||
|
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;
|