From: Hannes Reinecke 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 --- 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 @@ -1230,8 +1230,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 */ @@ -1244,6 +1245,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; case SCSI_DH_RETRY: /* Wait before retrying. */ delay_retry = 1; @@ -1264,7 +1269,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 @@ -414,14 +414,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; @@ -483,7 +487,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;