Skip to content

Commit

Permalink
xen/blkback: Propagate changed size of VBDs
Browse files Browse the repository at this point in the history
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: K. Y. Srinivasan <ksrinivasan@novell.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
  • Loading branch information
K. Y. Srinivasan authored and Konrad Rzeszutek Wilk committed Apr 14, 2011
1 parent 5cf6e4f commit 2ccbfe2
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/xen/blkback/blkback.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ static void print_stats(blkif_t *blkif)
int blkif_schedule(void *arg)
{
blkif_t *blkif = arg;
struct vbd *vbd = &blkif->vbd;

blkif_get(blkif);

Expand All @@ -216,6 +217,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,
Expand Down
2 changes: 2 additions & 0 deletions drivers/xen/blkback/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,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;
Expand Down Expand Up @@ -98,6 +99,7 @@ blkif_t *blkif_alloc(domid_t domid);
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) \
Expand Down
43 changes: 43 additions & 0 deletions drivers/xen/blkback/vbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major,
}

vbd->bdev = bdev;
vbd->size = vbd_size(vbd);

if (vbd->bdev->bd_disk == NULL) {
DPRINTK("vbd_creat: device %08x doesn't exist.\n",
Expand Down Expand Up @@ -116,3 +117,45 @@ int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
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);
}

0 comments on commit 2ccbfe2

Please sign in to comment.