# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1268659879 0
# Node ID f7f420bd7b7ad94e97946b7dda4df15b0657cd16
# Parent 505690874cd9d5220b7864f2a3c8e1b28b8add79
xenblk: dynamic vbd resizing
Signed-off-by: K. Y. Srinivasan <ksrinivasan@xxxxxxxxxx>
---
drivers/xen/blkback/blkback.c | 3 ++
drivers/xen/blkback/common.h | 2 +
drivers/xen/blkback/vbd.c | 43 ++++++++++++++++++++++++++++++++++++++++
drivers/xen/blkfront/blkfront.c | 19 +++++++++++++++--
4 files changed, 65 insertions(+), 2 deletions(-)
diff -r 505690874cd9 -r f7f420bd7b7a drivers/xen/blkback/blkback.c
--- a/drivers/xen/blkback/blkback.c Mon Mar 15 13:20:21 2010 +0000
+++ b/drivers/xen/blkback/blkback.c Mon Mar 15 13:31:19 2010 +0000
@@ -205,6 +205,7 @@ int blkif_schedule(void *arg)
int blkif_schedule(void *arg)
{
blkif_t *blkif = arg;
+ struct vbd *vbd = &blkif->vbd;
blkif_get(blkif);
@@ -214,6 +215,8 @@ int blkif_schedule(void *arg)
while (!kthread_should_stop()) {
if (try_to_freeze())
continue;
+ if (unlikely(vbd->size != vbd_size(vbd)))
+ vbd_resize(blkif);
wait_event_interruptible(
blkif->wq,
diff -r 505690874cd9 -r f7f420bd7b7a drivers/xen/blkback/common.h
--- a/drivers/xen/blkback/common.h Mon Mar 15 13:20:21 2010 +0000
+++ b/drivers/xen/blkback/common.h Mon Mar 15 13:31:19 2010 +0000
@@ -56,6 +56,7 @@ struct vbd {
unsigned char type; /* VDISK_xxx */
u32 pdevice; /* phys device that this vbd maps to */
struct block_device *bdev;
+ sector_t size; /* Cached size parameter */
};
struct backend_info;
@@ -104,6 +105,7 @@ void blkif_disconnect(blkif_t *blkif);
void blkif_disconnect(blkif_t *blkif);
void blkif_free(blkif_t *blkif);
int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
+void vbd_resize(blkif_t *blkif);
#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
#define blkif_put(_b) \
diff -r 505690874cd9 -r f7f420bd7b7a drivers/xen/blkback/vbd.c
--- a/drivers/xen/blkback/vbd.c Mon Mar 15 13:20:21 2010 +0000
+++ b/drivers/xen/blkback/vbd.c Mon Mar 15 13:31:19 2010 +0000
@@ -73,6 +73,7 @@ int vbd_create(blkif_t *blkif, blkif_vde
}
vbd->bdev = bdev;
+ vbd->size = vbd_size(vbd);
if (vbd->bdev->bd_disk == NULL) {
DPRINTK("vbd_creat: device %08x doesn't exist.\n",
@@ -116,3 +117,45 @@ int vbd_translate(struct phys_req *req,
out:
return rc;
}
+
+void vbd_resize(blkif_t *blkif)
+{
+ struct vbd *vbd = &blkif->vbd;
+ struct xenbus_transaction xbt;
+ int err;
+ struct xenbus_device *dev = blkif->be->dev;
+ unsigned long long new_size = vbd_size(vbd);
+
+ printk(KERN_INFO "VBD Resize: new size %Lu\n", new_size);
+ vbd->size = new_size;
+again:
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
+ printk(KERN_WARNING "Error starting transaction");
+ return;
+ }
+ err = xenbus_printf(xbt, dev->nodename, "sectors", "%Lu",
+ vbd_size(vbd));
+ if (err) {
+ printk(KERN_WARNING "Error writing new size");
+ goto abort;
+ }
+ /*
+ * Write the current state; we will use this to synchronize
+ * the front-end. If the current state is "connected" the
+ * front-end will get the new size information online.
+ */
+ err = xenbus_printf(xbt, dev->nodename, "state", "%d", dev->state);
+ if (err) {
+ printk(KERN_WARNING "Error writing the state");
+ goto abort;
+ }
+
+ err = xenbus_transaction_end(xbt, 0);
+ if (err == -EAGAIN)
+ goto again;
+ if (err)
+ printk(KERN_WARNING "Error ending transaction");
+abort:
+ xenbus_transaction_end(xbt, 1);
+}
diff -r 505690874cd9 -r f7f420bd7b7a drivers/xen/blkfront/blkfront.c
--- a/drivers/xen/blkfront/blkfront.c Mon Mar 15 13:20:21 2010 +0000
+++ b/drivers/xen/blkfront/blkfront.c Mon Mar 15 13:31:19 2010 +0000
@@ -326,9 +326,24 @@ static void connect(struct blkfront_info
unsigned int binfo;
int err;
- if ((info->connected == BLKIF_STATE_CONNECTED) ||
- (info->connected == BLKIF_STATE_SUSPENDED) )
+ switch (info->connected) {
+ case BLKIF_STATE_CONNECTED:
+ /*
+ * Potentially, the back-end may be signalling
+ * a capacity change; update the capacity.
+ */
+ err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+ "sectors", "%Lu", §ors);
+ if (XENBUS_EXIST_ERR(err))
+ return;
+ printk(KERN_INFO "Setting capacity to %Lu\n",
+ sectors);
+ set_capacity(info->gd, sectors);
+
+ /* fall through */
+ case BLKIF_STATE_SUSPENDED:
return;
+ }
DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|