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

[SCSI] virtio-scsi: Add vdrv->scan for post VIRTIO_CONFIG_S_DRIVER_OK LUN scanning

This patch changes virtio-scsi to use a new virtio_driver->scan() callback
so that scsi_scan_host() can be properly invoked once virtio_dev_probe() has
set add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK) to signal active virtio-ring
operation, instead of from within virtscsi_probe().

This fixes a bug where SCSI LUN scanning for both virtio-scsi-raw and
virtio-scsi/tcm_vhost setups was happening before VIRTIO_CONFIG_S_DRIVER_OK
had been set, causing VIRTIO_SCSI_S_BAD_TARGET to occur. This fixes a bug
with virtio-scsi/tcm_vhost where LUN scan was not detecting LUNs.

Tested with virtio-scsi-raw + virtio-scsi/tcm_vhost w/ IBLOCK on 3.5-rc2 code.

Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Nicholas Bellinger and committed by
James Bottomley
59057fbc 0b1017aa

+17 -4
+12 -3
drivers/scsi/virtio_scsi.c
··· 571 571 return tgt; 572 572 } 573 573 574 + static void virtscsi_scan(struct virtio_device *vdev) 575 + { 576 + struct Scsi_Host *shost = (struct Scsi_Host *)vdev->priv; 577 + 578 + scsi_scan_host(shost); 579 + } 580 + 574 581 static void virtscsi_remove_vqs(struct virtio_device *vdev) 575 582 { 576 583 struct Scsi_Host *sh = virtio_scsi_host(vdev); ··· 684 677 err = scsi_add_host(shost, &vdev->dev); 685 678 if (err) 686 679 goto scsi_add_host_failed; 687 - 688 - scsi_scan_host(shost); 689 - 680 + /* 681 + * scsi_scan_host() happens in virtscsi_scan() via virtio_driver->scan() 682 + * after VIRTIO_CONFIG_S_DRIVER_OK has been set.. 683 + */ 690 684 return 0; 691 685 692 686 scsi_add_host_failed: ··· 743 735 .driver.owner = THIS_MODULE, 744 736 .id_table = id_table, 745 737 .probe = virtscsi_probe, 738 + .scan = virtscsi_scan, 746 739 #ifdef CONFIG_PM 747 740 .freeze = virtscsi_freeze, 748 741 .restore = virtscsi_restore,
+4 -1
drivers/virtio/virtio.c
··· 141 141 err = drv->probe(dev); 142 142 if (err) 143 143 add_status(dev, VIRTIO_CONFIG_S_FAILED); 144 - else 144 + else { 145 145 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); 146 + if (drv->scan) 147 + drv->scan(dev); 148 + } 146 149 147 150 return err; 148 151 }
+1
include/linux/virtio.h
··· 92 92 const unsigned int *feature_table; 93 93 unsigned int feature_table_size; 94 94 int (*probe)(struct virtio_device *dev); 95 + void (*scan)(struct virtio_device *dev); 95 96 void (*remove)(struct virtio_device *dev); 96 97 void (*config_changed)(struct virtio_device *dev); 97 98 #ifdef CONFIG_PM