diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2016-11-04 02:06:53 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-03-08 01:15:19 -0500 |
commit | a04e54f2c35823ca32d56afcd5cea5b783e2f51a (patch) | |
tree | 631bf922978866bf34f0405ad62f72229257f85e | |
parent | c1ae3cfa0e89fa1a7ecc4c99031f5e9ae99d9201 (diff) |
target/pscsi: Fix TYPE_TAPE + TYPE_MEDIMUM_CHANGER export
The following fixes a divide by zero OOPs with TYPE_TAPE
due to pscsi_tape_read_blocksize() failing causing a zero
sd->sector_size being propigated up via dev_attrib.hw_block_size.
It also fixes another long-standing bug where TYPE_TAPE and
TYPE_MEDIMUM_CHANGER where using pscsi_create_type_other(),
which does not call scsi_device_get() to take the device
reference. Instead, rename pscsi_create_type_rom() to
pscsi_create_type_nondisk() and use it for all cases.
Finally, also drop a dump_stack() in pscsi_get_blocks() for
non TYPE_DISK, which in modern target-core can get invoked
via target_sense_desc_format() during CHECK_CONDITION.
Reported-by: Malcolm Haak <insanemal@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_pscsi.c | 47 |
1 files changed, 12 insertions, 35 deletions
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index a8f8e53f2f57..44d92f23a3f0 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -154,7 +154,7 @@ static void pscsi_tape_read_blocksize(struct se_device *dev, | |||
154 | 154 | ||
155 | buf = kzalloc(12, GFP_KERNEL); | 155 | buf = kzalloc(12, GFP_KERNEL); |
156 | if (!buf) | 156 | if (!buf) |
157 | return; | 157 | goto out_free; |
158 | 158 | ||
159 | memset(cdb, 0, MAX_COMMAND_SIZE); | 159 | memset(cdb, 0, MAX_COMMAND_SIZE); |
160 | cdb[0] = MODE_SENSE; | 160 | cdb[0] = MODE_SENSE; |
@@ -169,9 +169,10 @@ static void pscsi_tape_read_blocksize(struct se_device *dev, | |||
169 | * If MODE_SENSE still returns zero, set the default value to 1024. | 169 | * If MODE_SENSE still returns zero, set the default value to 1024. |
170 | */ | 170 | */ |
171 | sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); | 171 | sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); |
172 | out_free: | ||
172 | if (!sdev->sector_size) | 173 | if (!sdev->sector_size) |
173 | sdev->sector_size = 1024; | 174 | sdev->sector_size = 1024; |
174 | out_free: | 175 | |
175 | kfree(buf); | 176 | kfree(buf); |
176 | } | 177 | } |
177 | 178 | ||
@@ -314,9 +315,10 @@ static int pscsi_add_device_to_list(struct se_device *dev, | |||
314 | sd->lun, sd->queue_depth); | 315 | sd->lun, sd->queue_depth); |
315 | } | 316 | } |
316 | 317 | ||
317 | dev->dev_attrib.hw_block_size = sd->sector_size; | 318 | dev->dev_attrib.hw_block_size = |
319 | min_not_zero((int)sd->sector_size, 512); | ||
318 | dev->dev_attrib.hw_max_sectors = | 320 | dev->dev_attrib.hw_max_sectors = |
319 | min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); | 321 | min_not_zero(sd->host->max_sectors, queue_max_hw_sectors(q)); |
320 | dev->dev_attrib.hw_queue_depth = sd->queue_depth; | 322 | dev->dev_attrib.hw_queue_depth = sd->queue_depth; |
321 | 323 | ||
322 | /* | 324 | /* |
@@ -339,8 +341,10 @@ static int pscsi_add_device_to_list(struct se_device *dev, | |||
339 | /* | 341 | /* |
340 | * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. | 342 | * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. |
341 | */ | 343 | */ |
342 | if (sd->type == TYPE_TAPE) | 344 | if (sd->type == TYPE_TAPE) { |
343 | pscsi_tape_read_blocksize(dev, sd); | 345 | pscsi_tape_read_blocksize(dev, sd); |
346 | dev->dev_attrib.hw_block_size = sd->sector_size; | ||
347 | } | ||
344 | return 0; | 348 | return 0; |
345 | } | 349 | } |
346 | 350 | ||
@@ -406,7 +410,7 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) | |||
406 | /* | 410 | /* |
407 | * Called with struct Scsi_Host->host_lock called. | 411 | * Called with struct Scsi_Host->host_lock called. |
408 | */ | 412 | */ |
409 | static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) | 413 | static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd) |
410 | __releases(sh->host_lock) | 414 | __releases(sh->host_lock) |
411 | { | 415 | { |
412 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; | 416 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
@@ -433,28 +437,6 @@ static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) | |||
433 | return 0; | 437 | return 0; |
434 | } | 438 | } |
435 | 439 | ||
436 | /* | ||
437 | * Called with struct Scsi_Host->host_lock called. | ||
438 | */ | ||
439 | static int pscsi_create_type_other(struct se_device *dev, | ||
440 | struct scsi_device *sd) | ||
441 | __releases(sh->host_lock) | ||
442 | { | ||
443 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; | ||
444 | struct Scsi_Host *sh = sd->host; | ||
445 | int ret; | ||
446 | |||
447 | spin_unlock_irq(sh->host_lock); | ||
448 | ret = pscsi_add_device_to_list(dev, sd); | ||
449 | if (ret) | ||
450 | return ret; | ||
451 | |||
452 | pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%llu\n", | ||
453 | phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, | ||
454 | sd->channel, sd->id, sd->lun); | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static int pscsi_configure_device(struct se_device *dev) | 440 | static int pscsi_configure_device(struct se_device *dev) |
459 | { | 441 | { |
460 | struct se_hba *hba = dev->se_hba; | 442 | struct se_hba *hba = dev->se_hba; |
@@ -542,11 +524,8 @@ static int pscsi_configure_device(struct se_device *dev) | |||
542 | case TYPE_DISK: | 524 | case TYPE_DISK: |
543 | ret = pscsi_create_type_disk(dev, sd); | 525 | ret = pscsi_create_type_disk(dev, sd); |
544 | break; | 526 | break; |
545 | case TYPE_ROM: | ||
546 | ret = pscsi_create_type_rom(dev, sd); | ||
547 | break; | ||
548 | default: | 527 | default: |
549 | ret = pscsi_create_type_other(dev, sd); | 528 | ret = pscsi_create_type_nondisk(dev, sd); |
550 | break; | 529 | break; |
551 | } | 530 | } |
552 | 531 | ||
@@ -611,8 +590,7 @@ static void pscsi_free_device(struct se_device *dev) | |||
611 | else if (pdv->pdv_lld_host) | 590 | else if (pdv->pdv_lld_host) |
612 | scsi_host_put(pdv->pdv_lld_host); | 591 | scsi_host_put(pdv->pdv_lld_host); |
613 | 592 | ||
614 | if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) | 593 | scsi_device_put(sd); |
615 | scsi_device_put(sd); | ||
616 | 594 | ||
617 | pdv->pdv_sd = NULL; | 595 | pdv->pdv_sd = NULL; |
618 | } | 596 | } |
@@ -1064,7 +1042,6 @@ static sector_t pscsi_get_blocks(struct se_device *dev) | |||
1064 | if (pdv->pdv_bd && pdv->pdv_bd->bd_part) | 1042 | if (pdv->pdv_bd && pdv->pdv_bd->bd_part) |
1065 | return pdv->pdv_bd->bd_part->nr_sects; | 1043 | return pdv->pdv_bd->bd_part->nr_sects; |
1066 | 1044 | ||
1067 | dump_stack(); | ||
1068 | return 0; | 1045 | return 0; |
1069 | } | 1046 | } |
1070 | 1047 | ||