Re: [PATCH 2/2] Add serial number support for virtio_blk, V4a

2009-06-09 Thread Rusty Russell
On Thu, 4 Jun 2009 06:37:19 am you wrote:
 This patch extracts the opaque data from pci i/o
 region 0 via the added VIRTIO_BLK_F_IDENTIFY
 field.

Thanks John, I fixed textual conflicts and forwarded it to Jens: he has the 
other pending virtio_blk patches as well.

I removed one comment:

 +/* mapped into pci i/o region 0
 + */
  struct virtio_blk_config
  {

This is true for virtio_pci, but not for virtio in general.

Thanks,
Rusty.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] Add serial number support for virtio_blk, V4

2009-06-03 Thread Jens Axboe
On Mon, Jun 01 2009, Rusty Russell wrote:
 On Fri, 29 May 2009 01:45:27 pm john cooper wrote:
  virtio_blk-serial-4.patch
 
 Hate to ask dumb questions, but is there a scsi equivalent of this?  It'd be 
 nice if we could avoid being ATA-specific in the long run...

SCSI has mode pages, where ATA pretty much stuffs everything into the
identify data.

 Also, why u16?

The identify page is word based, so u16 makes sense.

 
 Thanks,
 Rusty.
 
  +/* return ATA identify data
  + */
  +static int virtblk_identify(struct gendisk *disk, void *argp)
  +{
  +   struct virtio_blk *vblk = disk-private_data;
  +   u16 *id;
  +   int err = -ENOMEM;
  +
  +   id = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
  +   if (!id)
  +   goto out;
  +
  +   err = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_IDENTIFY,
  +   offsetof(struct virtio_blk_config, identify), id,
  +   VIRTIO_BLK_ID_BYTES);
 

-- 
Jens Axboe

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] Add serial number support for virtio_blk, V4

2009-06-03 Thread john cooper
Jens Axboe wrote:
 On Mon, Jun 01 2009, Rusty Russell wrote:
 On Fri, 29 May 2009 01:45:27 pm john cooper wrote:
 virtio_blk-serial-4.patch
 Hate to ask dumb questions, but is there a scsi equivalent of this?  It'd be 
 nice if we could avoid being ATA-specific in the long run...
 
 SCSI has mode pages, where ATA pretty much stuffs everything into the
 identify data.
 
 Also, why u16?
 
 The identify page is word based, so u16 makes sense.

It is actually an artifact left over from the previous
version.  In that case the driver was only pulling
the serial number over, itself constructing a mocked-up
identify page, and needed to be aware of the internal
structure.

Currently qemu fabricates the identify page which the
driver treats as opaque data passed onto the user.  So
the u16 * structure has no meaning.

Sorry to be late in responding here.  A patch to address
this wrinkle and other feedback to follow shortly.

-john


 +/* return ATA identify data
 + */
 +static int virtblk_identify(struct gendisk *disk, void *argp)
 +{
 +   struct virtio_blk *vblk = disk-private_data;
 +   u16 *id;
 +   int err = -ENOMEM;
 +
 +   id = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
 +   if (!id)
 +   goto out;
 +
 +   err = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_IDENTIFY,
 +   offsetof(struct virtio_blk_config, identify), id,
 +   VIRTIO_BLK_ID_BYTES);
 


-- 
john.coo...@redhat.com
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] Add serial number support for virtio_blk, V4a

2009-06-03 Thread john cooper
This patch extracts the opaque data from pci i/o
region 0 via the added VIRTIO_BLK_F_IDENTIFY
field.  By convention this data takes the form of
that returned by an ATA IDENTIFY DEVICE command,
however the driver (except for structure size)
makes no interpretation of the data.  The structure
data is copied wholesale to userspace via a
HDIO_GET_IDENTITY ioctl command (eg: hdparm -i dev).

Signed-off-by: john cooper john.coo...@redhat.com
---

 drivers/block/virtio_blk.c |   41 ++---
 include/linux/virtio_blk.h |6 ++
 2 files changed, 44 insertions(+), 3 deletions(-)
=
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -146,12 +146,46 @@ static void do_virtblk_request(struct re
vblk-vq-vq_ops-kick(vblk-vq);
 }
 
+/* return ATA identify data
+ */
+static int virtblk_identify(struct gendisk *disk, void *argp)
+{
+   struct virtio_blk *vblk = disk-private_data;
+   void *opaque;
+   int err = -ENOMEM;
+
+   opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
+   if (!opaque)
+   goto out;
+
+   err = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_IDENTIFY,
+   offsetof(struct virtio_blk_config, identify), opaque,
+   VIRTIO_BLK_ID_BYTES);
+
+   if (err)
+   goto out_kfree;
+
+   if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
+   err = -EFAULT;
+
+out_kfree:
+   kfree(opaque);
+out:
+   return err;
+}
+
 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);
+   struct gendisk *disk = bdev-bd_disk;
+   void __user *argp = (void __user *)data;
+
+   switch (cmd) {
+   case HDIO_GET_IDENTITY:
+   return virtblk_identify(disk, argp);
+   default:
+   return scsi_cmd_ioctl(disk-queue, disk, mode, cmd, argp);
+   }
 }
 
 /* We provide getgeo only to please some old bootloader/partitioning tools */
@@ -356,6 +390,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_IDENTIFY
 };
 
 static struct virtio_driver virtio_blk = {
=
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -15,7 +15,12 @@
 #define VIRTIO_BLK_F_GEOMETRY  4   /* Legacy geometry available  */
 #define VIRTIO_BLK_F_RO5   /* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE  6   /* Block size of disk is available*/
+#define VIRTIO_BLK_F_IDENTIFY  8   /* ATA IDENTIFY supported */
 
+#define VIRTIO_BLK_ID_BYTES(sizeof (__u16[256]))   /* IDENTIFY DATA */
+
+/* mapped into pci i/o region 0
+ */
 struct virtio_blk_config
 {
/* The capacity (in 512-byte sectors). */
@@ -32,6 +37,7 @@ struct virtio_blk_config
} geometry;
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
__u32 blk_size;
+   __u8 identify[VIRTIO_BLK_ID_BYTES];
 } __attribute__((packed));
 
 /* These two define direction. */

-- 
john.coo...@redhat.com

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] Add serial number support for virtio_blk, V4

2009-06-01 Thread Rusty Russell
On Fri, 29 May 2009 01:45:27 pm john cooper wrote:
 virtio_blk-serial-4.patch

Hate to ask dumb questions, but is there a scsi equivalent of this?  It'd be 
nice if we could avoid being ATA-specific in the long run...

Also, why u16?

Thanks,
Rusty.

 +/* return ATA identify data
 + */
 +static int virtblk_identify(struct gendisk *disk, void *argp)
 +{
 + struct virtio_blk *vblk = disk-private_data;
 + u16 *id;
 + int err = -ENOMEM;
 +
 + id = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
 + if (!id)
 + goto out;
 +
 + err = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_IDENTIFY,
 + offsetof(struct virtio_blk_config, identify), id,
 + VIRTIO_BLK_ID_BYTES);

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] [PATCH 2/2] Add serial number support for virtio_blk, V4

2009-05-31 Thread Christoph Hellwig
On Fri, May 29, 2009 at 12:15:27AM -0400, john cooper wrote:
 virtio_blk-serial-4.patch
 
 

The patch looks good to me, but to get it applied to the kernel tree the
patch needs a good description and we also need your Signed-off-by line (See
Documentation/SubmittingPatches in the kernel source tree)
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] [PATCH 2/2] Add serial number support for virtio_blk, V3

2009-05-28 Thread john cooper

 +if (!(id = kzalloc(ATA_ID_WORDS, GFP_KERNEL)))
 +rv = -ENOMEM;
 
 Doesn't ATA_ID_WORDS seem like a strange name for a number of bytes?

Yes I caught that bug in the rework as well.

 What's this *for* BTW?

Sorry -- I assumed you were on either list.
Please see patch to follow.

-john

-- 
john.coo...@redhat.com

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] [PATCH 2/2] Add serial number support for virtio_blk, V3

2009-05-28 Thread john cooper
Christoph Hellwig wrote:
 On Wed, May 27, 2009 at 09:49:19AM +0200, Christoph Hellwig wrote:
 /*
  * IDE-compatible identify ioctl.
  *
  * Currenlyt only returns the serial number and leaves all other fields
  * zero.
  */
 
 Btw, thinking about it the rest of the information in the ioctl should
 probably be filled up with faked data, similar to how we do it for
 the ide emulation inside qemu.

Agreed.  I've done so to the extent it makes sense
in the case of the more generic fields.  A fair
amount of the identify information being generated
by hw/ide.c appears obsoleted.

-john

-- 
john.coo...@redhat.com

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] Add serial number support for virtio_blk, V4

2009-05-28 Thread john cooper
virtio_blk-serial-4.patch



 drivers/block/virtio_blk.c |   41 ++---
 include/linux/virtio_blk.h |7 +++
 2 files changed, 45 insertions(+), 3 deletions(-)
=
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -146,12 +146,46 @@ static void do_virtblk_request(struct re
vblk-vq-vq_ops-kick(vblk-vq);
 }
 
+/* return ATA identify data
+ */
+static int virtblk_identify(struct gendisk *disk, void *argp)
+{
+   struct virtio_blk *vblk = disk-private_data;
+   u16 *id;
+   int err = -ENOMEM;
+
+   id = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
+   if (!id)
+   goto out;
+
+   err = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_IDENTIFY,
+   offsetof(struct virtio_blk_config, identify), id,
+   VIRTIO_BLK_ID_BYTES);
+
+   if (err)
+   goto out_kfree;
+
+   if (copy_to_user(argp, id, VIRTIO_BLK_ID_BYTES))
+   err = -EFAULT;
+
+out_kfree:
+   kfree(id);
+out:
+   return err;
+}
+
 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);
+   struct gendisk *disk = bdev-bd_disk;
+   void __user *argp = (void __user *)data;
+
+   switch (cmd) {
+   case HDIO_GET_IDENTITY:
+   return virtblk_identify(disk, argp);
+   default:
+   return scsi_cmd_ioctl(disk-queue, disk, mode, cmd, argp);
+   }
 }
 
 /* We provide getgeo only to please some old bootloader/partitioning tools */
@@ -356,6 +390,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_IDENTIFY
 };
 
 static struct virtio_driver virtio_blk = {
=
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -15,7 +15,13 @@
 #define VIRTIO_BLK_F_GEOMETRY  4   /* Legacy geometry available  */
 #define VIRTIO_BLK_F_RO5   /* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE  6   /* Block size of disk is available*/
+#define VIRTIO_BLK_F_IDENTIFY  8   /* ATA IDENTIFY supported */
 
+#define VIRTIO_BLK_ID_LEN 256
+#define VIRTIO_BLK_ID_BYTES (VIRTIO_BLK_ID_LEN * sizeof (u16))
+
+/* mapped into pci i/o region 0
+ */
 struct virtio_blk_config
 {
/* The capacity (in 512-byte sectors). */
@@ -32,6 +38,7 @@ struct virtio_blk_config
} geometry;
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
__u32 blk_size;
+   __u16 identify[VIRTIO_BLK_ID_LEN];
 } __attribute__((packed));
 
 /* These two define direction. */
-- 
john.coo...@redhat.com



--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] [PATCH 2/2] Add serial number support for virtio_blk, V3

2009-05-27 Thread Christoph Hellwig
You should probably include rusty as he's collecting the patches
for the virtio guest drivers.

Also can you send the patch inline next time? That makes quoting it for
review a lot easier.


 drivers/block/virtio_blk.c |   32 +---
 include/linux/virtio_blk.h |6 ++
 2 files changed, 35 insertions(+), 3 deletions(-)
=
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -146,12 +146,37 @@ static void do_virtblk_request(struct re
vblk-vq-vq_ops-kick(vblk-vq);
 }
 
+/* return serial# in IDE identify data (all other fields are currently zero)
+ */
+static int virtblk_identity(struct block_device *bdev, void *buf)
+{
+   struct virtio_blk *vblk = bdev-bd_disk-private_data;
+   u16 *id;
+   int rv;
+
+   if (!(id = kzalloc(ATA_ID_WORDS, GFP_KERNEL)))
+   rv = -ENOMEM;
+   else if ((rv = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_SN,
+   offsetof(struct virtio_blk_config, serial), id[ATA_ID_SERNO],
+   ATA_ID_SERNO_LEN)))
+   ;
+   else if (copy_to_user(buf, id, ATA_ID_WORDS))
+   rv = -EFAULT;
+   else
+   rv = 0;
+   if (id)
+   kfree(id);
+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 == HDIO_GET_IDENTITY)
+   return (virtblk_identity(bdev, (void __user *)data));
+   else
+   return scsi_cmd_ioctl(bdev-bd_disk-queue, bdev-bd_disk,
+   mode, cmd, (void __user *)data);
 }
 

This looks functionally correct, but pretty far from normal kernel coding
style.  I'd envision something like this instead:

/*
 * IDE-compatible identify ioctl.
 *
 * Currenlyt only returns the serial number and leaves all other fields
 * zero.
 */
static int virtblk_identity(struct gendisk *disk, void *argp)
{
struct virtio_blk *vblk = disk-private_data;
u16 *id;
int error = -ENOMEM;

id = kzalloc(ATA_ID_WORDS, GFP_KERNEL)
if (!id)
goto out;

error = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_SN,
  offsetof(struct virtio_blk_config, serial),
  id[ATA_ID_SERNO], ATA_ID_SERNO_LEN);
if (error)
goto out_kfree;

if (copy_to_user(argp, id, ATA_ID_WORDS))
error = -EFAULT;

out_kfree:
kfree(id);
out:
return error;
}


static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
 unsigned cmd, unsigned long arg)
{
struct gendisk *disk = bdev-bd_disk;
void __user *argp = (void __user *arg);

switch (cmd) {
case HDIO_GET_IDENTITY:
return virtblk_identity(disk, argp);
default:
return scsi_cmd_ioctl(disk-queue, disk, mode, cmd, argp);
}
}
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] [PATCH 2/2] Add serial number support for virtio_blk, V3

2009-05-27 Thread Christoph Hellwig
On Wed, May 27, 2009 at 09:49:19AM +0200, Christoph Hellwig wrote:
 /*
  * IDE-compatible identify ioctl.
  *
  * Currenlyt only returns the serial number and leaves all other fields
  * zero.
  */

Btw, thinking about it the rest of the information in the ioctl should
probably be filled up with faked data, similar to how we do it for
the ide emulation inside qemu.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] [PATCH 2/2] Add serial number support for virtio_blk, V3

2009-05-27 Thread Rusty Russell
On Wed, 27 May 2009 05:19:19 pm Christoph Hellwig wrote:
 You should probably include rusty as he's collecting the patches
 for the virtio guest drivers.

Yes.  It *does* help to cc the maintainer if you want your patches applied :)

And I particularly love untested code like this!

 + if (!(id = kzalloc(ATA_ID_WORDS, GFP_KERNEL)))
 + rv = -ENOMEM;

Doesn't ATA_ID_WORDS seem like a strange name for a number of bytes?

What's this *for* BTW?
Rusty.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] Add serial number support for virtio_blk, V3

2009-05-26 Thread john cooper


--
john.coo...@redhat.com

 drivers/block/virtio_blk.c |   32 +---
 include/linux/virtio_blk.h |6 ++
 2 files changed, 35 insertions(+), 3 deletions(-)
=
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -146,12 +146,37 @@ static void do_virtblk_request(struct re
 		vblk-vq-vq_ops-kick(vblk-vq);
 }
 
+/* return serial# in IDE identify data (all other fields are currently zero)
+ */
+static int virtblk_identity(struct block_device *bdev, void *buf)
+{
+	struct virtio_blk *vblk = bdev-bd_disk-private_data;
+	u16 *id;
+	int rv;
+
+	if (!(id = kzalloc(ATA_ID_WORDS, GFP_KERNEL)))
+		rv = -ENOMEM;
+	else if ((rv = virtio_config_buf(vblk-vdev, VIRTIO_BLK_F_SN,
+		offsetof(struct virtio_blk_config, serial), id[ATA_ID_SERNO],
+		ATA_ID_SERNO_LEN)))
+			;
+	else if (copy_to_user(buf, id, ATA_ID_WORDS))
+		rv = -EFAULT;
+	else
+		rv = 0;
+	if (id)
+	kfree(id);
+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 == HDIO_GET_IDENTITY)
+		return (virtblk_identity(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 */
@@ -356,6 +381,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 = {
=
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -15,7 +15,12 @@
 #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		8	/* serial number supported */
 
+#define BLOCK_SERIAL_STRLEN	20
+
+/* mapped into pci i/o region 0
+ */
 struct virtio_blk_config
 {
 	/* The capacity (in 512-byte sectors). */
@@ -32,6 +37,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. */


[PATCH 2/2] Add serial number support for virtio_blk, V2

2009-05-13 Thread john cooper


--
john.coo...@redhat.com

 drivers/block/virtio_blk.c |   35 ---
 include/linux/virtio_blk.h |   10 ++
 2 files changed, 42 insertions(+), 3 deletions(-)
=
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -146,12 +146,40 @@ 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.
+ */
+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 */
@@ -356,6 +384,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 = {
=
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -15,7 +15,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		8	/* 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). */
@@ -32,6 +41,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. */


[PATCH 2/2] Add serial number support for virtio_blk

2009-04-29 Thread john cooper


--
john.coo...@third-harmonic.com
 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 = {


[PATCH 2/2] Add serial number support for virtio_blk

2009-04-29 Thread john cooper


--
john.coo...@third-harmonic.com
 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 = {