aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikanth Karthikesan <knikanth@suse.de>2009-03-24 07:29:54 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-03-24 07:35:18 -0400
commit68db1961bbf4e16c220ccec4a780e966bc1fece3 (patch)
tree8101ee12fb24abd2e794ecadfedbc0e0c6859891
parent05378940caf979a8655c18b18a17213dcfa52412 (diff)
loop: support barrier writes
Honour barrier requests in the loop back block device driver. In case of barrier bios, flush the backing file once before processing the barrier and once after to guarantee ordering. In case of filesystems that does not support fsync, barrier bios would be failed with -EOPNOTSUPP. Signed-off-by: Nikanth Karthikesan <knikanth@suse.de> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--drivers/block/loop.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bf0345577672..9721d100caf1 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -474,10 +474,35 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
474 int ret; 474 int ret;
475 475
476 pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; 476 pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
477 if (bio_rw(bio) == WRITE) 477
478 if (bio_rw(bio) == WRITE) {
479 int barrier = bio_barrier(bio);
480 struct file *file = lo->lo_backing_file;
481
482 if (barrier) {
483 if (unlikely(!file->f_op->fsync)) {
484 ret = -EOPNOTSUPP;
485 goto out;
486 }
487
488 ret = vfs_fsync(file, file->f_path.dentry, 0);
489 if (unlikely(ret)) {
490 ret = -EIO;
491 goto out;
492 }
493 }
494
478 ret = lo_send(lo, bio, pos); 495 ret = lo_send(lo, bio, pos);
479 else 496
497 if (barrier && !ret) {
498 ret = vfs_fsync(file, file->f_path.dentry, 0);
499 if (unlikely(ret))
500 ret = -EIO;
501 }
502 } else
480 ret = lo_receive(lo, bio, lo->lo_blocksize, pos); 503 ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
504
505out:
481 return ret; 506 return ret;
482} 507}
483 508
@@ -826,6 +851,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
826 lo->lo_queue->queuedata = lo; 851 lo->lo_queue->queuedata = lo;
827 lo->lo_queue->unplug_fn = loop_unplug; 852 lo->lo_queue->unplug_fn = loop_unplug;
828 853
854 if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
855 blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL);
856
829 set_capacity(lo->lo_disk, size); 857 set_capacity(lo->lo_disk, size);
830 bd_set_size(bdev, size << 9); 858 bd_set_size(bdev, size << 9);
831 859