[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] xenblk: dynamic vbd resizing



# 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", &sectors);
+               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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.