From: kwolf@suse.de
Subject: blktap: Write Barriers
Patch-mainline: Never, SUSE-Xen specific

--- a/drivers/xen/blktap/blktap.c
+++ b/drivers/xen/blktap/blktap.c
@@ -1404,6 +1404,9 @@ static int _do_block_io_op(blkif_t *blki
 			dispatch_rw_block_io(blkif, &req, pending_req);
 			break;
 
+		case BLKIF_OP_WRITE_BARRIER:
+			/* TODO Some counter? */
+			/* Fall through */
 		case BLKIF_OP_WRITE:
 			blkif->st_wr_req++;
 			dispatch_rw_block_io(blkif, &req, pending_req);
@@ -1485,7 +1488,7 @@ static void dispatch_rw_block_io(blkif_t
 
 	/* Check that number of segments is sane. */
 	nseg = req->nr_segments;
-	if ( unlikely(nseg == 0) || 
+	if (unlikely(nseg == 0 && req->operation != BLKIF_OP_WRITE_BARRIER) ||
 	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) ) {
 		WPRINTK("Bad number of segments in request (%d)\n", nseg);
 		goto fail_response;
@@ -1512,8 +1515,13 @@ static void dispatch_rw_block_io(blkif_t
 	pending_req->nr_pages  = nseg;
 
 	flags = GNTMAP_host_map;
-	if (req->operation == BLKIF_OP_WRITE)
+	switch (req->operation) {
+	case BLKIF_OP_WRITE:
+	case BLKIF_OP_WRITE_BARRIER:
 		flags |= GNTMAP_readonly;
+		break;
+	}
+
 	op = 0;
 	if (!xen_feature(XENFEAT_auto_translated_physmap))
 		down_read(&mm->mmap_sem);
@@ -1672,6 +1680,7 @@ static void dispatch_rw_block_io(blkif_t
 		blkif->st_rd_sect += nr_sects;
 		break;
 	case BLKIF_OP_WRITE:
+	case BLKIF_OP_WRITE_BARRIER:
 		blkif->st_wr_sect += nr_sects;
 		break;
 	}
--- a/drivers/xen/blktap/xenbus.c
+++ b/drivers/xen/blktap/xenbus.c
@@ -415,7 +415,28 @@ static void connect(struct backend_info
 	int err;
 
 	struct xenbus_device *dev = be->dev;
+	struct xenbus_transaction xbt;
 
+	/* Write feature-barrier to xenstore */
+again:
+	err = xenbus_transaction_start(&xbt);
+	if (err) {
+		xenbus_dev_fatal(dev, err, "starting transaction");
+		return;
+	}
+
+	err = xenbus_printf(xbt, dev->nodename, "feature-barrier",  "1");
+	if (err) {
+		xenbus_dev_fatal(dev, err, "writing feature-barrier");
+		xenbus_transaction_end(xbt, 1);
+		return;
+	}
+
+	err = xenbus_transaction_end(xbt, 0);
+	if (err == -EAGAIN)
+		goto again;
+
+	/* Switch state */
 	err = xenbus_switch_state(dev, XenbusStateConnected);
 	if (err)
 		xenbus_dev_fatal(dev, err, "%s: switching to Connected state",
