summaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback/xenbus.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk2011-10-10 06:42:22 +0200
committerKonrad Rzeszutek Wilk2011-10-13 15:48:36 +0200
commit29bde093787f3bdf7b9b4270ada6be7c8076e36b (patch)
tree4fff697e0acb2471b1bd575cbd006fa4efc3937d /drivers/block/xen-blkback/xenbus.c
parentxen-blkfront: plug device number leak in xlblk_init() error path (diff)
downloadkernel-qcow2-linux-29bde093787f3bdf7b9b4270ada6be7c8076e36b.tar.gz
kernel-qcow2-linux-29bde093787f3bdf7b9b4270ada6be7c8076e36b.tar.xz
kernel-qcow2-linux-29bde093787f3bdf7b9b4270ada6be7c8076e36b.zip
xen/blkback: Support 'feature-barrier' aka old-style BARRIER requests.
We emulate the barrier requests by draining the outstanding bio's and then sending the WRITE_FLUSH command. To drain the I/Os we use the refcnt that is used during disconnect to wait for all the I/Os before disconnecting from the frontend. We latch on its value and if it reaches either the threshold for disconnect or when there are no more outstanding I/Os, then we have drained all I/Os. Suggested-by: Christopher Hellwig <hch@infradead.org> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkback/xenbus.c')
-rw-r--r--drivers/block/xen-blkback/xenbus.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 1c44b3254134..a6d43030b107 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -114,6 +114,8 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
spin_lock_init(&blkif->blk_ring_lock);
atomic_set(&blkif->refcnt, 1);
init_waitqueue_head(&blkif->wq);
+ init_completion(&blkif->drain_complete);
+ atomic_set(&blkif->drain, 0);
blkif->st_print = jiffies;
init_waitqueue_head(&blkif->waiting_to_free);
@@ -474,6 +476,19 @@ kfree:
out:
return err;
}
+int xen_blkbk_barrier(struct xenbus_transaction xbt,
+ struct backend_info *be, int state)
+{
+ struct xenbus_device *dev = be->dev;
+ int err;
+
+ err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
+ "%d", state);
+ if (err)
+ xenbus_dev_fatal(dev, err, "writing feature-barrier");
+
+ return err;
+}
/*
* Entry point to this code when a new device is created. Allocate the basic
@@ -708,6 +723,9 @@ again:
err = xen_blkbk_discard(xbt, be);
+ /* If we can't advertise it is OK. */
+ err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
+
err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
(unsigned long long)vbd_sz(&be->blkif->vbd));
if (err) {