Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] dh_rdac: Associate HBA and storage in rdac_controller to support partitions in storage

rdac hardware handler assumes that there is one-to-one relation ship
between the host and the controller w.r.t lun. IOW, it does not
support "multiple storage partitions" within a storage.

Example:
HBA1 and HBA2 see lun 0 and 1 in storage A (1)
HBA3 and HBA4 see lun 0 and 1 in storage A (2)
HBA5 and HBA6 see lun 0 and 1 in storage A (3)

luns 0 and 1 in (1), (2) and (3) are totally different.

But, rdac handler treats the lun 0s (and lun 1s) as the same when
sending a mode select to the controller, which is wrong.

This patch makes the rdac hardware handler associate HBA and the
storage w.r.t lun (and not the host itself).

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Chandra Seetharaman and committed by
James Bottomley
d6857595 f170c684

+6 -3
+6 -3
drivers/scsi/device_handler/scsi_dh_rdac.c
··· 158 158 } mode_select; 159 159 u8 index; 160 160 u8 array_name[ARRAY_LABEL_LEN]; 161 + struct Scsi_Host *host; 161 162 spinlock_t ms_lock; 162 163 int ms_queued; 163 164 struct work_struct ms_work; ··· 371 370 } 372 371 373 372 static struct rdac_controller *get_controller(int index, char *array_name, 374 - u8 *array_id) 373 + u8 *array_id, struct scsi_device *sdev) 375 374 { 376 375 struct rdac_controller *ctlr, *tmp; 377 376 ··· 379 378 380 379 list_for_each_entry(tmp, &ctlr_list, node) { 381 380 if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) && 382 - (tmp->index == index)) { 381 + (tmp->index == index) && 382 + (tmp->host == sdev->host)) { 383 383 kref_get(&tmp->kref); 384 384 spin_unlock(&list_lock); 385 385 return tmp; ··· 393 391 /* initialize fields of controller */ 394 392 memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN); 395 393 ctlr->index = index; 394 + ctlr->host = sdev->host; 396 395 memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN); 397 396 398 397 kref_init(&ctlr->kref); ··· 516 513 index = 0; 517 514 else 518 515 index = 1; 519 - h->ctlr = get_controller(index, array_name, array_id); 516 + h->ctlr = get_controller(index, array_name, array_id, sdev); 520 517 if (!h->ctlr) 521 518 err = SCSI_DH_RES_TEMP_UNAVAIL; 522 519 }