diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 16:49:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 16:49:37 -0400 |
commit | 552c7dbb3459c219e44a65fd6bca21b1227c0e33 (patch) | |
tree | 686c62c2821e687c73754c29145bca4e55f45224 /drivers/block | |
parent | db7a1535d2dcf91115ba0fb940b1902c05305843 (diff) | |
parent | 6c99a8528f9a81dda6bbbf83854b8475ce79c745 (diff) |
Merge branch 'virtio' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* 'virtio' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
virtio_blk: Remove VBID ioctl
virtio_blk: Add 'serial' attribute to virtio-blk devices (v2)
virtio_blk: support barriers without FLUSH feature
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/virtio_blk.c | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 258bc2ae2885..23b7c48df843 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, | |||
225 | struct gendisk *disk = bdev->bd_disk; | 225 | struct gendisk *disk = bdev->bd_disk; |
226 | struct virtio_blk *vblk = disk->private_data; | 226 | struct virtio_blk *vblk = disk->private_data; |
227 | 227 | ||
228 | if (cmd == 0x56424944) { /* 'VBID' */ | ||
229 | void __user *usr_data = (void __user *)data; | ||
230 | char id_str[VIRTIO_BLK_ID_BYTES]; | ||
231 | int err; | ||
232 | |||
233 | err = virtblk_get_id(disk, id_str); | ||
234 | if (!err && copy_to_user(usr_data, id_str, VIRTIO_BLK_ID_BYTES)) | ||
235 | err = -EFAULT; | ||
236 | return err; | ||
237 | } | ||
238 | /* | 228 | /* |
239 | * Only allow the generic SCSI ioctls if the host can support it. | 229 | * Only allow the generic SCSI ioctls if the host can support it. |
240 | */ | 230 | */ |
@@ -281,6 +271,27 @@ static int index_to_minor(int index) | |||
281 | return index << PART_BITS; | 271 | return index << PART_BITS; |
282 | } | 272 | } |
283 | 273 | ||
274 | static ssize_t virtblk_serial_show(struct device *dev, | ||
275 | struct device_attribute *attr, char *buf) | ||
276 | { | ||
277 | struct gendisk *disk = dev_to_disk(dev); | ||
278 | int err; | ||
279 | |||
280 | /* sysfs gives us a PAGE_SIZE buffer */ | ||
281 | BUILD_BUG_ON(PAGE_SIZE < VIRTIO_BLK_ID_BYTES); | ||
282 | |||
283 | buf[VIRTIO_BLK_ID_BYTES] = '\0'; | ||
284 | err = virtblk_get_id(disk, buf); | ||
285 | if (!err) | ||
286 | return strlen(buf); | ||
287 | |||
288 | if (err == -EIO) /* Unsupported? Make it empty. */ | ||
289 | return 0; | ||
290 | |||
291 | return err; | ||
292 | } | ||
293 | DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); | ||
294 | |||
284 | static int __devinit virtblk_probe(struct virtio_device *vdev) | 295 | static int __devinit virtblk_probe(struct virtio_device *vdev) |
285 | { | 296 | { |
286 | struct virtio_blk *vblk; | 297 | struct virtio_blk *vblk; |
@@ -366,12 +377,32 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
366 | vblk->disk->driverfs_dev = &vdev->dev; | 377 | vblk->disk->driverfs_dev = &vdev->dev; |
367 | index++; | 378 | index++; |
368 | 379 | ||
369 | /* If barriers are supported, tell block layer that queue is ordered */ | 380 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) { |
370 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) | 381 | /* |
382 | * If the FLUSH feature is supported we do have support for | ||
383 | * flushing a volatile write cache on the host. Use that | ||
384 | * to implement write barrier support. | ||
385 | */ | ||
371 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, | 386 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, |
372 | virtblk_prepare_flush); | 387 | virtblk_prepare_flush); |
373 | else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) | 388 | } else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) { |
389 | /* | ||
390 | * If the BARRIER feature is supported the host expects us | ||
391 | * to order request by tags. This implies there is not | ||
392 | * volatile write cache on the host, and that the host | ||
393 | * never re-orders outstanding I/O. This feature is not | ||
394 | * useful for real life scenarious and deprecated. | ||
395 | */ | ||
374 | blk_queue_ordered(q, QUEUE_ORDERED_TAG, NULL); | 396 | blk_queue_ordered(q, QUEUE_ORDERED_TAG, NULL); |
397 | } else { | ||
398 | /* | ||
399 | * If the FLUSH feature is not supported we must assume that | ||
400 | * the host does not perform any kind of volatile write | ||
401 | * caching. We still need to drain the queue to provider | ||
402 | * proper barrier semantics. | ||
403 | */ | ||
404 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN, NULL); | ||
405 | } | ||
375 | 406 | ||
376 | /* If disk is read-only in the host, the guest should obey */ | 407 | /* If disk is read-only in the host, the guest should obey */ |
377 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) | 408 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) |
@@ -445,8 +476,15 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
445 | 476 | ||
446 | 477 | ||
447 | add_disk(vblk->disk); | 478 | add_disk(vblk->disk); |
479 | err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); | ||
480 | if (err) | ||
481 | goto out_del_disk; | ||
482 | |||
448 | return 0; | 483 | return 0; |
449 | 484 | ||
485 | out_del_disk: | ||
486 | del_gendisk(vblk->disk); | ||
487 | blk_cleanup_queue(vblk->disk->queue); | ||
450 | out_put_disk: | 488 | out_put_disk: |
451 | put_disk(vblk->disk); | 489 | put_disk(vblk->disk); |
452 | out_mempool: | 490 | out_mempool: |