2018-01-03 16:03:56

by Stefan Hajnoczi

[permalink] [raw]
Subject: [PATCH] virtio_blk: print capacity at probe time

Print the capacity of the block device when the driver is probed. Many
users expect this since SCSI disks (sd) do it. Moreover, kernel dmesg
output is the primary source of troubleshooting information so it's
helpful to include the disk size there.

The capacity is already printed by virtio_blk when a resize event
occurs. Extract the code and reuse it from virtblk_probe().

This patch also adds the block device name to the message so it can be
correlated with a specific device:

virtio_blk virtio0: [vda] 20971520 512-byte logical blocks (10.7 GB/10.0 GiB)

Cc: Rodrigo A B Freire <[email protected]>
Cc: Michael S. Tsirkin <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
---
drivers/block/virtio_blk.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 68846897d213..787cd2a10b0b 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -373,14 +373,12 @@ static ssize_t virtblk_serial_show(struct device *dev,

static DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);

-static void virtblk_config_changed_work(struct work_struct *work)
+/* The queue's logical block size must be set before calling this */
+static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize)
{
- struct virtio_blk *vblk =
- container_of(work, struct virtio_blk, config_work);
struct virtio_device *vdev = vblk->vdev;
struct request_queue *q = vblk->disk->queue;
char cap_str_2[10], cap_str_10[10];
- char *envp[] = { "RESIZE=1", NULL };
unsigned long long nblocks;
u64 capacity;

@@ -402,13 +400,24 @@ static void virtblk_config_changed_work(struct work_struct *work)
STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));

dev_notice(&vdev->dev,
- "new size: %llu %d-byte logical blocks (%s/%s)\n",
+ "[%s] %s%llu %d-byte logical blocks (%s/%s)\n",
+ vblk->disk->disk_name,
+ resize ? "new size: " : "",
nblocks,
queue_logical_block_size(q),
cap_str_10,
cap_str_2);

set_capacity(vblk->disk, capacity);
+}
+
+static void virtblk_config_changed_work(struct work_struct *work)
+{
+ struct virtio_blk *vblk =
+ container_of(work, struct virtio_blk, config_work);
+ char *envp[] = { "RESIZE=1", NULL };
+
+ virtblk_update_capacity(vblk, true);
revalidate_disk(vblk->disk);
kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp);
}
@@ -621,7 +630,6 @@ static int virtblk_probe(struct virtio_device *vdev)
struct request_queue *q;
int err, index;

- u64 cap;
u32 v, blk_size, sg_elems, opt_io_size;
u16 min_io_size;
u8 physical_block_exp, alignment_offset;
@@ -719,17 +727,6 @@ static int virtblk_probe(struct virtio_device *vdev)
if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO))
set_disk_ro(vblk->disk, 1);

- /* Host must always specify the capacity. */
- virtio_cread(vdev, struct virtio_blk_config, capacity, &cap);
-
- /* If capacity is too big, truncate with warning. */
- if ((sector_t)cap != cap) {
- dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
- (unsigned long long)cap);
- cap = (sector_t)-1;
- }
- set_capacity(vblk->disk, cap);
-
/* We can handle whatever the host told us to handle. */
blk_queue_max_segments(q, vblk->sg_elems-2);

@@ -780,6 +777,7 @@ static int virtblk_probe(struct virtio_device *vdev)
if (!err && opt_io_size)
blk_queue_io_opt(q, blk_size * opt_io_size);

+ virtblk_update_capacity(vblk, false);
virtio_device_ready(vdev);

device_add_disk(&vdev->dev, vblk->disk);
--
2.14.3


2018-01-19 16:44:59

by Stefan Hajnoczi

[permalink] [raw]
Subject: Re: [PATCH] virtio_blk: print capacity at probe time

On Wed, Jan 3, 2018 at 4:03 PM, Stefan Hajnoczi <[email protected]> wrote:
> Print the capacity of the block device when the driver is probed. Many
> users expect this since SCSI disks (sd) do it. Moreover, kernel dmesg
> output is the primary source of troubleshooting information so it's
> helpful to include the disk size there.
>
> The capacity is already printed by virtio_blk when a resize event
> occurs. Extract the code and reuse it from virtblk_probe().
>
> This patch also adds the block device name to the message so it can be
> correlated with a specific device:
>
> virtio_blk virtio0: [vda] 20971520 512-byte logical blocks (10.7 GB/10.0 GiB)
>
> Cc: Rodrigo A B Freire <[email protected]>
> Cc: Michael S. Tsirkin <[email protected]>
> Signed-off-by: Stefan Hajnoczi <[email protected]>
> ---
> drivers/block/virtio_blk.c | 32 +++++++++++++++-----------------
> 1 file changed, 15 insertions(+), 17 deletions(-)

Ping?

> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> index 68846897d213..787cd2a10b0b 100644
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -373,14 +373,12 @@ static ssize_t virtblk_serial_show(struct device *dev,
>
> static DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
>
> -static void virtblk_config_changed_work(struct work_struct *work)
> +/* The queue's logical block size must be set before calling this */
> +static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize)
> {
> - struct virtio_blk *vblk =
> - container_of(work, struct virtio_blk, config_work);
> struct virtio_device *vdev = vblk->vdev;
> struct request_queue *q = vblk->disk->queue;
> char cap_str_2[10], cap_str_10[10];
> - char *envp[] = { "RESIZE=1", NULL };
> unsigned long long nblocks;
> u64 capacity;
>
> @@ -402,13 +400,24 @@ static void virtblk_config_changed_work(struct work_struct *work)
> STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));
>
> dev_notice(&vdev->dev,
> - "new size: %llu %d-byte logical blocks (%s/%s)\n",
> + "[%s] %s%llu %d-byte logical blocks (%s/%s)\n",
> + vblk->disk->disk_name,
> + resize ? "new size: " : "",
> nblocks,
> queue_logical_block_size(q),
> cap_str_10,
> cap_str_2);
>
> set_capacity(vblk->disk, capacity);
> +}
> +
> +static void virtblk_config_changed_work(struct work_struct *work)
> +{
> + struct virtio_blk *vblk =
> + container_of(work, struct virtio_blk, config_work);
> + char *envp[] = { "RESIZE=1", NULL };
> +
> + virtblk_update_capacity(vblk, true);
> revalidate_disk(vblk->disk);
> kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp);
> }
> @@ -621,7 +630,6 @@ static int virtblk_probe(struct virtio_device *vdev)
> struct request_queue *q;
> int err, index;
>
> - u64 cap;
> u32 v, blk_size, sg_elems, opt_io_size;
> u16 min_io_size;
> u8 physical_block_exp, alignment_offset;
> @@ -719,17 +727,6 @@ static int virtblk_probe(struct virtio_device *vdev)
> if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO))
> set_disk_ro(vblk->disk, 1);
>
> - /* Host must always specify the capacity. */
> - virtio_cread(vdev, struct virtio_blk_config, capacity, &cap);
> -
> - /* If capacity is too big, truncate with warning. */
> - if ((sector_t)cap != cap) {
> - dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
> - (unsigned long long)cap);
> - cap = (sector_t)-1;
> - }
> - set_capacity(vblk->disk, cap);
> -
> /* We can handle whatever the host told us to handle. */
> blk_queue_max_segments(q, vblk->sg_elems-2);
>
> @@ -780,6 +777,7 @@ static int virtblk_probe(struct virtio_device *vdev)
> if (!err && opt_io_size)
> blk_queue_io_opt(q, blk_size * opt_io_size);
>
> + virtblk_update_capacity(vblk, false);
> virtio_device_ready(vdev);
>
> device_add_disk(&vdev->dev, vblk->disk);
> --
> 2.14.3
>
> _______________________________________________
> Virtualization mailing list
> [email protected]
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization