- needs_update: Merge or delete remaining patches.
authorHannes Reinecke <hare@suse.de>
Fri, 11 Dec 2009 08:30:49 +0000 (09:30 +0100)
committerHannes Reinecke <hare@suse.de>
Fri, 11 Dec 2009 08:30:49 +0000 (09:30 +0100)
- patches.fixes/scsi-dh-emc-mode-select-10-size: DM-MPIO fails
  to tresspass LUNs on CLARiiON arrays (bnc#484529).
- patches.fixes/scsi-dh-emc-rw-mismatch: Server crashes when
  path failures occur against EMC storage (bnc#474482).
- patches.fixes/scsi-dh-rdac-add-stk: STK arrays missing from
  rdac devicehandler (bnc#503855).
- patches.fixes/scsi-retry-alua-transition-in-progress: I/O
  errors for ALUA state transitions (bnc#491289).
- patches.suse/dm-mpath-no-activate-for-offlined-paths: DM-MPIO
  fails to tresspass LUNs on CLARiiON arrays (bnc#484529).
- patches.suse/dm-mpath-no-partitions-feature: Disable partitions
  scan for multipathed devices (bnc#402922,bnc#514767).

suse-commit: abe18afd7862fb90eecc79dd086e01c8c12d76f7

drivers/md/dm-mpath.c
drivers/md/dm-table.c
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/scsi_error.c

index bef4c53..76714e2 100644 (file)
@@ -57,6 +57,8 @@ struct priority_group {
        struct list_head pgpaths;
 };
 
+#define FEATURE_NO_PARTITIONS 1
+
 /* Multipath context */
 struct multipath {
        struct list_head list;
@@ -82,6 +84,7 @@ struct multipath {
        unsigned saved_queue_if_no_path;/* Saved state during suspension */
        unsigned pg_init_retries;       /* Number of times to retry pg_init */
        unsigned pg_init_count;         /* Number of times pg_init called */
+       unsigned features;              /* Additional selected features */
 
        struct work_struct process_queued_ios;
        struct list_head queued_ios;
@@ -462,6 +465,9 @@ static void process_queued_ios(struct work_struct *work)
                m->pg_init_count++;
                m->pg_init_required = 0;
                list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) {
+                       /* Skip disabled paths or failed paths */
+                       if (!tmp->path.dev || !tmp->is_active)
+                               continue;
                        if (queue_work(kmpath_handlerd, &tmp->activate_path))
                                m->pg_init_in_progress++;
                }
@@ -836,6 +842,10 @@ static int parse_features(struct arg_set *as, struct multipath *m)
                        continue;
                }
 
+               if (!strnicmp(param_name, MESG_STR("no_partitions"))) {
+                       m->features |= FEATURE_NO_PARTITIONS;
+                       continue;
+               }
                if (!strnicmp(param_name, MESG_STR("pg_init_retries")) &&
                    (argc >= 1)) {
                        r = read_param(_params + 1, shift(as),
@@ -1184,8 +1194,8 @@ static void pg_init_done(void *data, int errors)
                        errors = 0;
                        break;
                }
-               DMERR("Cannot failover device because scsi_dh_%s was not "
-                     "loaded.", m->hw_handler_name);
+               DMERR("Cannot failover device %s because scsi_dh_%s was not "
+                     "loaded.", pgpath->path.pdev, m->hw_handler_name);
                /*
                 * Fail path for now, so we do not ping pong
                 */
@@ -1198,6 +1208,10 @@ static void pg_init_done(void *data, int errors)
                 */
                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:
@@ -1218,7 +1232,8 @@ static void pg_init_done(void *data, int errors)
        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;
                }
@@ -1406,11 +1421,14 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
                DMEMIT("2 %u %u ", m->queue_size, m->pg_init_count);
        else {
                DMEMIT("%u ", m->queue_if_no_path +
-                             (m->pg_init_retries > 0) * 2);
+                             (m->pg_init_retries > 0) * 2 +
+                             (m->features & FEATURE_NO_PARTITIONS));
                if (m->queue_if_no_path)
                        DMEMIT("queue_if_no_path ");
                if (m->pg_init_retries)
                        DMEMIT("pg_init_retries %u ", m->pg_init_retries);
+               if (m->features & FEATURE_NO_PARTITIONS)
+                       DMEMIT("no_partitions ");
        }
 
        if (!m->hw_handler_name || type == STATUSTYPE_INFO)
index b4328f2..ff79a56 100644 (file)
@@ -407,14 +407,18 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
 
        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;
@@ -477,7 +481,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
                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;
index 286a16b..e3b1dd3 100644 (file)
@@ -272,7 +272,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
        int len = 0;
 
        rq = blk_get_request(sdev->request_queue,
-                       (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO);
+                       (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
        if (!rq) {
                sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
                return NULL;
@@ -286,14 +286,17 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
                len = sizeof(short_trespass);
                rq->cmd_flags |= REQ_RW;
                rq->cmd[1] = 0x10;
+               rq->cmd[4] = len;
                break;
        case MODE_SELECT_10:
                len = sizeof(long_trespass);
                rq->cmd_flags |= REQ_RW;
                rq->cmd[1] = 0x10;
+               rq->cmd[8] = len;
                break;
        case INQUIRY:
                len = CLARIION_BUFFER_SIZE;
+               rq->cmd[4] = len;
                memset(buffer, 0, len);
                break;
        default:
@@ -301,7 +304,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
                break;
        }
 
-       rq->cmd[4] = len;
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
                         REQ_FAILFAST_DRIVER;
index 9b608a5..6c8f282 100644 (file)
@@ -756,6 +756,8 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
        {"SGI", "TP9500", 0},
        {"SGI", "IS", 0},
        {"STK", "OPENstorage D280", 0},
+       {"STK", "FLEXLINE 380", 0},
+       {"SUN", "STK6580_6780", 0},
        {"SUN", "CSM200_R", 0},
        {"SUN", "LCSM100_I", 0},
        {"SUN", "LCSM100_S", 0},
index 433a9d3..cdd31c2 100644 (file)
@@ -372,7 +372,8 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
                 * if the device is in the process of becoming ready, we 
                 * should retry.
                 */
-               if ((sshdr.asc == 0x04) && (sshdr.ascq == 0x01))
+               if ((sshdr.asc == 0x04) &&
+                   (sshdr.ascq == 0x01 || sshdr.ascq == 0x0a))
                        return NEEDS_RETRY;
                /*
                 * if the device is not started, we need to wake