cciss: Preserve all 8 bytes of LUN ID for logical drives.
Preserve all 8 bytes of the LunID field returned by CCISS_REPORT_LOGICAL instead of only saving 4 bytes. This fixes a bug with logical volume addressing encountered on an MSA2012. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Родитель
983333cb0c
Коммит
39ccf9a645
|
@ -846,7 +846,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
|
||||||
if (MINOR(bdev->bd_dev) & 0x0f) {
|
if (MINOR(bdev->bd_dev) & 0x0f) {
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
/* if it is, make sure we have a LUN ID */
|
/* if it is, make sure we have a LUN ID */
|
||||||
} else if (drv->LunID == 0) {
|
} else if (memcmp(drv->LunID, CTLR_LUNID,
|
||||||
|
sizeof(drv->LunID))) {
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1216,7 +1217,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
|
||||||
case CCISS_GETLUNINFO:{
|
case CCISS_GETLUNINFO:{
|
||||||
LogvolInfo_struct luninfo;
|
LogvolInfo_struct luninfo;
|
||||||
|
|
||||||
luninfo.LunID = drv->LunID;
|
memcpy(&luninfo.LunID, drv->LunID,
|
||||||
|
sizeof(luninfo.LunID));
|
||||||
luninfo.num_opens = drv->usage_count;
|
luninfo.num_opens = drv->usage_count;
|
||||||
luninfo.num_parts = 0;
|
luninfo.num_parts = 0;
|
||||||
if (copy_to_user(argp, &luninfo,
|
if (copy_to_user(argp, &luninfo,
|
||||||
|
@ -1611,13 +1613,11 @@ static void cciss_softirq_done(struct request *rq)
|
||||||
spin_unlock_irqrestore(&h->lock, flags);
|
spin_unlock_irqrestore(&h->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[],
|
static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
|
||||||
uint32_t log_unit)
|
unsigned char scsi3addr[], uint32_t log_unit)
|
||||||
{
|
{
|
||||||
log_unit = h->drv[log_unit].LunID & 0x03fff;
|
memcpy(scsi3addr, h->drv[log_unit].LunID,
|
||||||
memset(&scsi3addr[4], 0, 4);
|
sizeof(h->drv[log_unit].LunID));
|
||||||
memcpy(&scsi3addr[0], &log_unit, 4);
|
|
||||||
scsi3addr[3] |= 0x40;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function gets the SCSI vendor, model, and revision of a logical drive
|
/* This function gets the SCSI vendor, model, and revision of a logical drive
|
||||||
|
@ -1924,7 +1924,8 @@ static void cciss_free_gendisk(ctlr_info_t *h, int drv_index)
|
||||||
* a means to talk to the controller in case no logical
|
* a means to talk to the controller in case no logical
|
||||||
* drives have yet been configured.
|
* drives have yet been configured.
|
||||||
*/
|
*/
|
||||||
static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
|
static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[],
|
||||||
|
int controller_node)
|
||||||
{
|
{
|
||||||
int drv_index;
|
int drv_index;
|
||||||
|
|
||||||
|
@ -1943,7 +1944,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h->drv[drv_index].LunID = lunid;
|
memcpy(h->drv[drv_index].LunID, lunid,
|
||||||
|
sizeof(h->drv[drv_index].LunID));
|
||||||
if (h->drv[drv_index].dev == NULL) {
|
if (h->drv[drv_index].dev == NULL) {
|
||||||
if (cciss_create_ld_sysfs_entry(h, drv_index))
|
if (cciss_create_ld_sysfs_entry(h, drv_index))
|
||||||
goto err_free_disk;
|
goto err_free_disk;
|
||||||
|
@ -1973,7 +1975,7 @@ static void cciss_add_controller_node(ctlr_info_t *h)
|
||||||
if (h->gendisk[0] != NULL) /* already did this? Then bail. */
|
if (h->gendisk[0] != NULL) /* already did this? Then bail. */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
drv_index = cciss_add_gendisk(h, 0, 1);
|
drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1);
|
||||||
if (drv_index == -1)
|
if (drv_index == -1)
|
||||||
goto error;
|
goto error;
|
||||||
h->drv[drv_index].block_size = 512;
|
h->drv[drv_index].block_size = 512;
|
||||||
|
@ -2012,7 +2014,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
|
||||||
int i;
|
int i;
|
||||||
int drv_found;
|
int drv_found;
|
||||||
int drv_index = 0;
|
int drv_index = 0;
|
||||||
__u32 lunid = 0;
|
unsigned char lunid[8] = CTLR_LUNID;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_RAWIO))
|
if (!capable(CAP_SYS_RAWIO))
|
||||||
|
@ -2069,9 +2071,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < num_luns; j++) {
|
for (j = 0; j < num_luns; j++) {
|
||||||
memcpy(&lunid, &ld_buff->LUN[j][0], 4);
|
memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid));
|
||||||
lunid = le32_to_cpu(lunid);
|
if (memcmp(h->drv[i].LunID, lunid,
|
||||||
if (h->drv[i].LunID == lunid) {
|
sizeof(lunid)) == 0) {
|
||||||
drv_found = 1;
|
drv_found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2096,9 +2098,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
|
||||||
|
|
||||||
drv_found = 0;
|
drv_found = 0;
|
||||||
|
|
||||||
memcpy(&lunid, &ld_buff->LUN[i][0], 4);
|
memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid));
|
||||||
lunid = le32_to_cpu(lunid);
|
|
||||||
|
|
||||||
/* Find if the LUN is already in the drive array
|
/* Find if the LUN is already in the drive array
|
||||||
* of the driver. If so then update its info
|
* of the driver. If so then update its info
|
||||||
* if not in use. If it does not exist then find
|
* if not in use. If it does not exist then find
|
||||||
|
@ -2106,7 +2106,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
|
||||||
*/
|
*/
|
||||||
for (j = 0; j <= h->highest_lun; j++) {
|
for (j = 0; j <= h->highest_lun; j++) {
|
||||||
if (h->drv[j].raid_level != -1 &&
|
if (h->drv[j].raid_level != -1 &&
|
||||||
h->drv[j].LunID == lunid) {
|
memcmp(h->drv[j].LunID, lunid,
|
||||||
|
sizeof(h->drv[j].LunID)) == 0) {
|
||||||
drv_index = j;
|
drv_index = j;
|
||||||
drv_found = 1;
|
drv_found = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -2254,8 +2255,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
|
||||||
}
|
}
|
||||||
h->highest_lun = newhighest;
|
h->highest_lun = newhighest;
|
||||||
}
|
}
|
||||||
|
memset(drv->LunID, 0, sizeof(drv->LunID));
|
||||||
drv->LunID = 0;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2686,7 +2686,8 @@ static int cciss_revalidate(struct gendisk *disk)
|
||||||
InquiryData_struct *inq_buff = NULL;
|
InquiryData_struct *inq_buff = NULL;
|
||||||
|
|
||||||
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
|
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
|
||||||
if (h->drv[logvol].LunID == drv->LunID) {
|
if (memcmp(h->drv[logvol].LunID, drv->LunID,
|
||||||
|
sizeof(drv->LunID)) == 0) {
|
||||||
FOUND = 1;
|
FOUND = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3171,8 +3172,7 @@ static void do_cciss_request(struct request_queue *q)
|
||||||
/* The first 2 bits are reserved for controller error reporting. */
|
/* The first 2 bits are reserved for controller error reporting. */
|
||||||
c->Header.Tag.lower = (c->cmdindex << 3);
|
c->Header.Tag.lower = (c->cmdindex << 3);
|
||||||
c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
|
c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
|
||||||
c->Header.LUN.LogDev.VolId = drv->LunID;
|
memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
|
||||||
c->Header.LUN.LogDev.Mode = 1;
|
|
||||||
c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
|
c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
|
||||||
c->Request.Type.Type = TYPE_CMD; // It is a command.
|
c->Request.Type.Type = TYPE_CMD; // It is a command.
|
||||||
c->Request.Type.Attribute = ATTR_SIMPLE;
|
c->Request.Type.Attribute = ATTR_SIMPLE;
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct access_method {
|
||||||
};
|
};
|
||||||
typedef struct _drive_info_struct
|
typedef struct _drive_info_struct
|
||||||
{
|
{
|
||||||
__u32 LunID;
|
unsigned char LunID[8];
|
||||||
int usage_count;
|
int usage_count;
|
||||||
struct request_queue *queue;
|
struct request_queue *queue;
|
||||||
sector_t nr_blocks;
|
sector_t nr_blocks;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче