diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/virtio_blk.c | 64 | ||||
-rw-r--r-- | drivers/block/xen-blkfront.c | 30 |
2 files changed, 81 insertions, 13 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 258bc2a..23b7c48 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -225,16 +225,6 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, struct gendisk *disk = bdev->bd_disk; struct virtio_blk *vblk = disk->private_data; - if (cmd == 0x56424944) { /* 'VBID' */ - void __user *usr_data = (void __user *)data; - char id_str[VIRTIO_BLK_ID_BYTES]; - int err; - - err = virtblk_get_id(disk, id_str); - if (!err && copy_to_user(usr_data, id_str, VIRTIO_BLK_ID_BYTES)) - err = -EFAULT; - return err; - } /* * Only allow the generic SCSI ioctls if the host can support it. */ @@ -281,6 +271,27 @@ static int index_to_minor(int index) return index << PART_BITS; } +static ssize_t virtblk_serial_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + int err; + + /* sysfs gives us a PAGE_SIZE buffer */ + BUILD_BUG_ON(PAGE_SIZE < VIRTIO_BLK_ID_BYTES); + + buf[VIRTIO_BLK_ID_BYTES] = '\0'; + err = virtblk_get_id(disk, buf); + if (!err) + return strlen(buf); + + if (err == -EIO) /* Unsupported? Make it empty. */ + return 0; + + return err; +} +DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); + static int __devinit virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -366,12 +377,32 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) vblk->disk->driverfs_dev = &vdev->dev; index++; - /* If barriers are supported, tell block layer that queue is ordered */ - if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) + if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) { + /* + * If the FLUSH feature is supported we do have support for + * flushing a volatile write cache on the host. Use that + * to implement write barrier support. + */ blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, virtblk_prepare_flush); - else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) + } else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) { + /* + * If the BARRIER feature is supported the host expects us + * to order request by tags. This implies there is not + * volatile write cache on the host, and that the host + * never re-orders outstanding I/O. This feature is not + * useful for real life scenarious and deprecated. + */ blk_queue_ordered(q, QUEUE_ORDERED_TAG, NULL); + } else { + /* + * If the FLUSH feature is not supported we must assume that + * the host does not perform any kind of volatile write + * caching. We still need to drain the queue to provider + * proper barrier semantics. + */ + blk_queue_ordered(q, QUEUE_ORDERED_DRAIN, NULL); + } /* If disk is read-only in the host, the guest should obey */ if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) @@ -445,8 +476,15 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) add_disk(vblk->disk); + err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); + if (err) + goto out_del_disk; + return 0; +out_del_disk: + del_gendisk(vblk->disk); + blk_cleanup_queue(vblk->disk->queue); out_put_disk: put_disk(vblk->disk); out_mempool: diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 82ed403..f63ac3d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -48,6 +48,7 @@ #include <xen/grant_table.h> #include <xen/events.h> #include <xen/page.h> +#include <xen/platform_pci.h> #include <xen/interface/grant_table.h> #include <xen/interface/io/blkif.h> @@ -737,6 +738,35 @@ static int blkfront_probe(struct xenbus_device *dev, } } + if (xen_hvm_domain()) { + char *type; + int len; + /* no unplug has been done: do not hook devices != xen vbds */ + if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) { + int major; + + if (!VDEV_IS_EXTENDED(vdevice)) + major = BLKIF_MAJOR(vdevice); + else + major = XENVBD_MAJOR; + + if (major != XENVBD_MAJOR) { + printk(KERN_INFO + "%s: HVM does not support vbd %d as xen block device\n", + __FUNCTION__, vdevice); + return -ENODEV; + } + } + /* do not create a PV cdrom device if we are an HVM guest */ + type = xenbus_read(XBT_NIL, dev->nodename, "device-type", &len); + if (IS_ERR(type)) + return -ENODEV; + if (strncmp(type, "cdrom", 5) == 0) { + kfree(type); + return -ENODEV; + } + kfree(type); + } info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); |