|
@@ -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);
|