aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-05-04 17:07:27 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-05-05 13:43:24 -0400
commit24f567f952aa308c3352f3340b9d296fc72bd066 (patch)
tree6cbc385ed612254b9eb0a77c0934804f85697e94 /drivers/block/xen-blkback
parent73d842af27b863cbc816e75003edbc287bf57130 (diff)
xen/blkback: Add support for BLKIF_OP_FLUSH_DISKCACHE and drop BLKIF_OP_WRITE_BARRIER.
We drop the support for 'feature-barrier' and add in the support for the 'feature-flush-cache' if the real backend storage supports flushing. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkback')
-rw-r--r--drivers/block/xen-blkback/blkback.c33
-rw-r--r--drivers/block/xen-blkback/common.h7
-rw-r--r--drivers/block/xen-blkback/xenbus.c19
3 files changed, 34 insertions, 25 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index eb068d0b47e..72ede0bf269 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -46,8 +46,6 @@
46#include <asm/xen/hypercall.h> 46#include <asm/xen/hypercall.h>
47#include "common.h" 47#include "common.h"
48 48
49#define WRITE_BARRIER (REQ_WRITE | REQ_FLUSH | REQ_FUA)
50
51/* 49/*
52 * These are rather arbitrary. They are fairly large because adjacent requests 50 * These are rather arbitrary. They are fairly large because adjacent requests
53 * pulled from a communication ring are quite likely to end up being part of 51 * pulled from a communication ring are quite likely to end up being part of
@@ -256,9 +254,9 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
256 254
257static void print_stats(struct blkif_st *blkif) 255static void print_stats(struct blkif_st *blkif)
258{ 256{
259 printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | br %4d\n", 257 printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | f %4d\n",
260 current->comm, blkif->st_oo_req, 258 current->comm, blkif->st_oo_req,
261 blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req); 259 blkif->st_rd_req, blkif->st_wr_req, blkif->st_f_req);
262 blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); 260 blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
263 blkif->st_rd_req = 0; 261 blkif->st_rd_req = 0;
264 blkif->st_wr_req = 0; 262 blkif->st_wr_req = 0;
@@ -414,10 +412,10 @@ static int xen_blkbk_map(struct blkif_request *req, struct pending_req *pending_
414static void __end_block_io_op(struct pending_req *pending_req, int error) 412static void __end_block_io_op(struct pending_req *pending_req, int error)
415{ 413{
416 /* An error fails the entire request. */ 414 /* An error fails the entire request. */
417 if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) && 415 if ((pending_req->operation == BLKIF_OP_FLUSH_DISKCACHE) &&
418 (error == -EOPNOTSUPP)) { 416 (error == -EOPNOTSUPP)) {
419 DPRINTK("blkback: write barrier op failed, not supported\n"); 417 DPRINTK("blkback: flush diskcache op failed, not supported\n");
420 xen_blkbk_barrier(XBT_NIL, pending_req->blkif->be, 0); 418 xen_blkbk_flush_diskcache(XBT_NIL, pending_req->blkif->be, 0);
421 pending_req->status = BLKIF_RSP_EOPNOTSUPP; 419 pending_req->status = BLKIF_RSP_EOPNOTSUPP;
422 } else if (error) { 420 } else if (error) {
423 DPRINTK("Buffer not up-to-date at end of operation, " 421 DPRINTK("Buffer not up-to-date at end of operation, "
@@ -506,13 +504,14 @@ static int do_block_io_op(struct blkif_st *blkif)
506 blkif->st_rd_req++; 504 blkif->st_rd_req++;
507 dispatch_rw_block_io(blkif, &req, pending_req); 505 dispatch_rw_block_io(blkif, &req, pending_req);
508 break; 506 break;
509 case BLKIF_OP_WRITE_BARRIER: 507 case BLKIF_OP_FLUSH_DISKCACHE:
510 blkif->st_br_req++; 508 blkif->st_f_req++;
511 /* fall through */ 509 /* fall through */
512 case BLKIF_OP_WRITE: 510 case BLKIF_OP_WRITE:
513 blkif->st_wr_req++; 511 blkif->st_wr_req++;
514 dispatch_rw_block_io(blkif, &req, pending_req); 512 dispatch_rw_block_io(blkif, &req, pending_req);
515 break; 513 break;
514 case BLKIF_OP_WRITE_BARRIER:
516 default: 515 default:
517 /* A good sign something is wrong: sleep for a while to 516 /* A good sign something is wrong: sleep for a while to
518 * avoid excessive CPU consumption by a bad guest. */ 517 * avoid excessive CPU consumption by a bad guest. */
@@ -556,9 +555,14 @@ static void dispatch_rw_block_io(struct blkif_st *blkif,
556 case BLKIF_OP_WRITE: 555 case BLKIF_OP_WRITE:
557 operation = WRITE_ODIRECT; 556 operation = WRITE_ODIRECT;
558 break; 557 break;
559 case BLKIF_OP_WRITE_BARRIER: 558 case BLKIF_OP_FLUSH_DISKCACHE:
560 operation = WRITE_BARRIER; 559 operation = WRITE_FLUSH;
560 /* The frontend likes to set this to -1, which vbd_translate
561 * is alergic too. */
562 req->u.rw.sector_number = 0;
561 break; 563 break;
564 case BLKIF_OP_WRITE_BARRIER:
565 /* Should never get here. */
562 default: 566 default:
563 operation = 0; /* make gcc happy */ 567 operation = 0; /* make gcc happy */
564 BUG(); 568 BUG();
@@ -566,7 +570,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif,
566 570
567 /* Check that the number of segments is sane. */ 571 /* Check that the number of segments is sane. */
568 nseg = req->nr_segments; 572 nseg = req->nr_segments;
569 if (unlikely(nseg == 0 && operation != WRITE_BARRIER) || 573 if (unlikely(nseg == 0 && operation != WRITE_FLUSH) ||
570 unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { 574 unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
571 DPRINTK("Bad number of segments in request (%d)\n", nseg); 575 DPRINTK("Bad number of segments in request (%d)\n", nseg);
572 /* Haven't submitted any bio's yet. */ 576 /* Haven't submitted any bio's yet. */
@@ -643,7 +647,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif,
643 647
644 /* This will be hit if the operation was a barrier. */ 648 /* This will be hit if the operation was a barrier. */
645 if (!bio) { 649 if (!bio) {
646 BUG_ON(operation != WRITE_BARRIER); 650 BUG_ON(operation != WRITE_FLUSH);
647 bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, 0); 651 bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, 0);
648 if (unlikely(bio == NULL)) 652 if (unlikely(bio == NULL))
649 goto fail_put_bio; 653 goto fail_put_bio;
@@ -651,7 +655,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif,
651 bio->bi_bdev = preq.bdev; 655 bio->bi_bdev = preq.bdev;
652 bio->bi_private = pending_req; 656 bio->bi_private = pending_req;
653 bio->bi_end_io = end_block_io_op; 657 bio->bi_end_io = end_block_io_op;
654 bio->bi_sector = -1;
655 } 658 }
656 659
657 660
@@ -671,7 +674,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif,
671 674
672 if (operation == READ) 675 if (operation == READ)
673 blkif->st_rd_sect += preq.nr_sects; 676 blkif->st_rd_sect += preq.nr_sects;
674 else if (operation == WRITE || operation == WRITE_BARRIER) 677 else if (operation == WRITE || operation == WRITE_FLUSH)
675 blkif->st_wr_sect += preq.nr_sects; 678 blkif->st_wr_sect += preq.nr_sects;
676 679
677 return; 680 return;
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 16af388268e..af93837e129 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -53,6 +53,7 @@ struct vbd {
53 u32 pdevice; /* phys device that this vbd maps to */ 53 u32 pdevice; /* phys device that this vbd maps to */
54 struct block_device *bdev; 54 struct block_device *bdev;
55 sector_t size; /* Cached size parameter */ 55 sector_t size; /* Cached size parameter */
56 bool flush_support;
56}; 57};
57 58
58struct backend_info; 59struct backend_info;
@@ -85,7 +86,7 @@ struct blkif_st {
85 int st_rd_req; 86 int st_rd_req;
86 int st_wr_req; 87 int st_wr_req;
87 int st_oo_req; 88 int st_oo_req;
88 int st_br_req; 89 int st_f_req;
89 int st_rd_sect; 90 int st_rd_sect;
90 int st_wr_sect; 91 int st_wr_sect;
91 92
@@ -120,8 +121,8 @@ int xen_blkif_xenbus_init(void);
120irqreturn_t xen_blkif_be_int(int irq, void *dev_id); 121irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
121int xen_blkif_schedule(void *arg); 122int xen_blkif_schedule(void *arg);
122 123
123int xen_blkbk_barrier(struct xenbus_transaction xbt, 124int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
124 struct backend_info *be, int state); 125 struct backend_info *be, int state);
125 126
126struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be); 127struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);
127 128
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 64b0a1c760f..9adcf806f83 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -276,7 +276,7 @@ int __init xen_blkif_interface_init(void)
276VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req); 276VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
277VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req); 277VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
278VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req); 278VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
279VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req); 279VBD_SHOW(f_req, "%d\n", be->blkif->st_f_req);
280VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect); 280VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
281VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect); 281VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
282 282
@@ -284,7 +284,7 @@ static struct attribute *vbdstat_attrs[] = {
284 &dev_attr_oo_req.attr, 284 &dev_attr_oo_req.attr,
285 &dev_attr_rd_req.attr, 285 &dev_attr_rd_req.attr,
286 &dev_attr_wr_req.attr, 286 &dev_attr_wr_req.attr,
287 &dev_attr_br_req.attr, 287 &dev_attr_f_req.attr,
288 &dev_attr_rd_sect.attr, 288 &dev_attr_rd_sect.attr,
289 &dev_attr_wr_sect.attr, 289 &dev_attr_wr_sect.attr,
290 NULL 290 NULL
@@ -343,6 +343,7 @@ static int vbd_create(struct blkif_st *blkif, blkif_vdev_t handle,
343{ 343{
344 struct vbd *vbd; 344 struct vbd *vbd;
345 struct block_device *bdev; 345 struct block_device *bdev;
346 struct request_queue *q;
346 347
347 vbd = &blkif->vbd; 348 vbd = &blkif->vbd;
348 vbd->handle = handle; 349 vbd->handle = handle;
@@ -375,6 +376,10 @@ static int vbd_create(struct blkif_st *blkif, blkif_vdev_t handle,
375 if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) 376 if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE)
376 vbd->type |= VDISK_REMOVABLE; 377 vbd->type |= VDISK_REMOVABLE;
377 378
379 q = bdev_get_queue(bdev);
380 if (q && q->flush_flags)
381 vbd->flush_support = true;
382
378 DPRINTK("Successful creation of handle=%04x (dom=%u)\n", 383 DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
379 handle, blkif->domid); 384 handle, blkif->domid);
380 return 0; 385 return 0;
@@ -406,16 +411,16 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
406 return 0; 411 return 0;
407} 412}
408 413
409int xen_blkbk_barrier(struct xenbus_transaction xbt, 414int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
410 struct backend_info *be, int state) 415 struct backend_info *be, int state)
411{ 416{
412 struct xenbus_device *dev = be->dev; 417 struct xenbus_device *dev = be->dev;
413 int err; 418 int err;
414 419
415 err = xenbus_printf(xbt, dev->nodename, "feature-barrier", 420 err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache",
416 "%d", state); 421 "%d", state);
417 if (err) 422 if (err)
418 xenbus_dev_fatal(dev, err, "writing feature-barrier"); 423 xenbus_dev_fatal(dev, err, "writing feature-flush-cache");
419 424
420 return err; 425 return err;
421} 426}
@@ -642,7 +647,7 @@ again:
642 return; 647 return;
643 } 648 }
644 649
645 err = xen_blkbk_barrier(xbt, be, 1); 650 err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
646 if (err) 651 if (err)
647 goto abort; 652 goto abort;
648 653