>From 542e237ea9ddbc17b54bf3b6b8d964b58f311b94 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 21 Jul 2010 17:09:09 +0200 Subject: [PATCH 1/2] block: Introduce barrier counters Introduce a barrier counters to the block device that are incremented each time before we send a barrier and after the barrier is completed. Filesystems can then use this counter to verify whether they need to issue a barrier to flush file's data during fsync. Signed-off-by: Jan Kara --- block/blk-core.c | 5 +++++ fs/bio.c | 7 +++++++ include/linux/fs.h | 4 ++++ 3 files changed, 16 insertions(+), 0 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index f0640d7..6fc58e6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1600,6 +1600,11 @@ void submit_bio(int rw, struct bio *bio) bdevname(bio->bi_bdev, b)); } } + if (rw & (1 << BIO_RW_BARRIER)) { + atomic_inc(&bio->bi_bdev->bd_barriers_sent); + /* Make sure counter update is seen before IO happens */ + smp_mb__after_atomic_inc(); + } generic_make_request(bio); } diff --git a/fs/bio.c b/fs/bio.c index e7bf6ca..59f01cb 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1427,6 +1427,13 @@ void bio_endio(struct bio *bio, int error) else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) error = -EIO; + /* + * Increment even in case of error so that sent and completed + * counters don't get out of sync + */ + if (bio_rw_flagged(bio, BIO_RW_BARRIER)) + atomic_inc(&bio->bi_bdev->bd_barriers_completed); + if (bio->bi_end_io) bio->bi_end_io(bio, error); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 68ca1b0..4a6c91d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -654,6 +654,10 @@ struct block_device { void * bd_claiming; void * bd_holder; int bd_holders; + /* Incremented each time before we send a barrier */ + atomic_t bd_barriers_sent; + /* Incremented each time after a barrier request completes */ + atomic_t bd_barriers_completed; #ifdef CONFIG_SYSFS struct list_head bd_holder_list; #endif -- 1.6.4.2