From patchwork Wed Apr 29 14:54:06 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: john cooper X-Patchwork-Id: 20731 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n3TF13sq008080 for ; Wed, 29 Apr 2009 15:01:03 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753474AbZD2PA6 (ORCPT ); Wed, 29 Apr 2009 11:00:58 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753275AbZD2PA5 (ORCPT ); Wed, 29 Apr 2009 11:00:57 -0400 Received: from dpc691978010.direcpc.com ([69.19.78.10]:43719 "EHLO anvil.third-harmonic.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752520AbZD2PA4 (ORCPT ); Wed, 29 Apr 2009 11:00:56 -0400 Received: from anvil.naka.net (localhost.localdomain [127.0.0.1]) by anvil.third-harmonic.com (8.14.1/8.14.1) with ESMTP id n3TEs6HY024060; Wed, 29 Apr 2009 10:54:07 -0400 Message-ID: <49F86A0E.8040604@third-harmonic.com> Date: Wed, 29 Apr 2009 10:54:06 -0400 From: john cooper User-Agent: Thunderbird 2.0.0.9 (X11/20071115) MIME-Version: 1.0 To: kvm@vger.kernel.org CC: john cooper , john.cooper@redhat.com Subject: [PATCH 2/2] Add serial number support for virtio_blk Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org drivers/block/virtio_blk.c | 36 +++++++++++++++++++++++++++++++++--- include/linux/virtio_blk.h | 10 ++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) ================================================================= --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h @@ -14,7 +14,16 @@ #define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ +#define VIRTIO_BLK_F_SN 7 /* serial number supported */ +/* ioctl cmd to retrieve serial# +*/ +#define VBLK_GET_SN ((unsigned int)('V' << 24 | 'B' << 16 | 'L' << 8 | 'K')) + +#define BLOCK_SERIAL_STRLEN 20 + +/* mapped into pci i/o region 0 + */ struct virtio_blk_config { /* The capacity (in 512-byte sectors). */ @@ -31,6 +40,7 @@ struct virtio_blk_config } geometry; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ __u32 blk_size; + __u8 serial[BLOCK_SERIAL_STRLEN]; } __attribute__((packed)); /* These two define direction. */ ================================================================= --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -146,12 +146,41 @@ static void do_virtblk_request(struct re vblk->vq->vq_ops->kick(vblk->vq); } +/* user passes the address of a char[] for serial# return, and has set char[0] + * to the array size. copy serial# to this char[] and return number of + * characters copied excluding any trailing '\0' pad chars in buffer. + */ +#define _min(a,b) ((a) < (b) ? (a) : (b)) +static int get_virtblk_sn(struct block_device *bdev, void *buf) +{ + struct virtio_blk *vblk = bdev->bd_disk->private_data; + unsigned char serial[BLOCK_SERIAL_STRLEN]; + unsigned char snlen; + int rv; + + if (copy_from_user(&snlen, buf, sizeof (snlen))) + rv = -EFAULT; + else if ((rv = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_SN, + offsetof(struct virtio_blk_config, serial), &serial))) + ; + else if (copy_to_user(buf, serial, + snlen = min(snlen, (unsigned char)sizeof (serial)))) + rv = -EFAULT; + else + for (rv = 0; rv < snlen; ++rv) + if (!serial[rv]) + break; + return (rv); +} + static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { - return scsi_cmd_ioctl(bdev->bd_disk->queue, - bdev->bd_disk, mode, cmd, - (void __user *)data); + if (cmd == VBLK_GET_SN) + return (get_virtblk_sn(bdev, (void __user *)data)); + else + return scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk, + mode, cmd, (void __user *)data); } /* We provide getgeo only to please some old bootloader/partitioning tools */ @@ -339,6 +368,7 @@ static struct virtio_device_id id_table[ static unsigned int features[] = { VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, + VIRTIO_BLK_F_SN }; static struct virtio_driver virtio_blk = {