Skip to content

Commit

Permalink
loop: support barrier writes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nikanth Karthikesan authored and Jens Axboe committed Mar 24, 2009
1 parent 0537894 commit 68db196
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,10 +474,35 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
int ret;

pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
if (bio_rw(bio) == WRITE)

if (bio_rw(bio) == WRITE) {
int barrier = bio_barrier(bio);
struct file *file = lo->lo_backing_file;

if (barrier) {
if (unlikely(!file->f_op->fsync)) {
ret = -EOPNOTSUPP;
goto out;
}

ret = vfs_fsync(file, file->f_path.dentry, 0);
if (unlikely(ret)) {
ret = -EIO;
goto out;
}
}

ret = lo_send(lo, bio, pos);
else

if (barrier && !ret) {
ret = vfs_fsync(file, file->f_path.dentry, 0);
if (unlikely(ret))
ret = -EIO;
}
} else
ret = lo_receive(lo, bio, lo->lo_blocksize, pos);

out:
return ret;
}

Expand Down Expand Up @@ -826,6 +851,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
lo->lo_queue->queuedata = lo;
lo->lo_queue->unplug_fn = loop_unplug;

if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL);

set_capacity(lo->lo_disk, size);
bd_set_size(bdev, size << 9);

Expand Down

0 comments on commit 68db196

Please sign in to comment.