Commit 2ccbfe26 authored by K. Y. Srinivasan's avatar K. Y. Srinivasan Committed by Konrad Rzeszutek Wilk

xen/blkback: Propagate changed size of VBDs

Support dynamic resizing of virtual block devices. This patch supports
both file backed block devices as well as physical devices that can be
dynamically resized on the host side.
Signed-off-by: default avatarK. Y. Srinivasan <ksrinivasan@novell.com>
Signed-off-by: default avatarJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
parent 5cf6e4f6
...@@ -207,6 +207,7 @@ static void print_stats(blkif_t *blkif) ...@@ -207,6 +207,7 @@ static void print_stats(blkif_t *blkif)
int blkif_schedule(void *arg) int blkif_schedule(void *arg)
{ {
blkif_t *blkif = arg; blkif_t *blkif = arg;
struct vbd *vbd = &blkif->vbd;
blkif_get(blkif); blkif_get(blkif);
...@@ -216,6 +217,8 @@ int blkif_schedule(void *arg) ...@@ -216,6 +217,8 @@ int blkif_schedule(void *arg)
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
if (try_to_freeze()) if (try_to_freeze())
continue; continue;
if (unlikely(vbd->size != vbd_size(vbd)))
vbd_resize(blkif);
wait_event_interruptible( wait_event_interruptible(
blkif->wq, blkif->wq,
......
...@@ -52,6 +52,7 @@ struct vbd { ...@@ -52,6 +52,7 @@ struct vbd {
unsigned char type; /* VDISK_xxx */ unsigned char type; /* VDISK_xxx */
u32 pdevice; /* phys device that this vbd maps to */ u32 pdevice; /* phys device that this vbd maps to */
struct block_device *bdev; struct block_device *bdev;
sector_t size; /* Cached size parameter */
}; };
struct backend_info; struct backend_info;
...@@ -98,6 +99,7 @@ blkif_t *blkif_alloc(domid_t domid); ...@@ -98,6 +99,7 @@ blkif_t *blkif_alloc(domid_t domid);
void blkif_disconnect(blkif_t *blkif); void blkif_disconnect(blkif_t *blkif);
void blkif_free(blkif_t *blkif); void blkif_free(blkif_t *blkif);
int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); 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_get(_b) (atomic_inc(&(_b)->refcnt))
#define blkif_put(_b) \ #define blkif_put(_b) \
......
...@@ -73,6 +73,7 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, ...@@ -73,6 +73,7 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major,
} }
vbd->bdev = bdev; vbd->bdev = bdev;
vbd->size = vbd_size(vbd);
if (vbd->bdev->bd_disk == NULL) { if (vbd->bdev->bd_disk == NULL) {
DPRINTK("vbd_creat: device %08x doesn't exist.\n", DPRINTK("vbd_creat: device %08x doesn't exist.\n",
...@@ -116,3 +117,45 @@ int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) ...@@ -116,3 +117,45 @@ int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
out: out:
return rc; 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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment