diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-09-24 02:17:36 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-05 10:13:09 -0400 |
commit | 30d0e7953b17462b8e42ad374ace70c76e31d410 (patch) | |
tree | 8722d5dfa60c29f8edbc9cb67c978122503ce298 | |
parent | df8b0d944cae63df86dba0edaa8fa8f5efaa7e03 (diff) |
bcache: Fix flushes in writeback mode
commit c0f04d88e46d14de51f4baebb6efafb7d59e9f96 upstream.
In writeback mode, when we get a cache flush we need to make sure we
issue a flush to the backing device.
The code for sending down an extra flush was wrong - by cloning the bio
we were probably getting flags that didn't make sense for a bare flush,
and also the old code was firing for FUA bios, for which we don't need
to send a flush to the backing device.
This was causing data corruption somehow - the mechanism was never
determined, but this patch fixes it for the users that were seeing it.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/md/bcache/request.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index afb9a998a737..2fe37fac1ca2 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -1056,14 +1056,17 @@ static void request_write(struct cached_dev *dc, struct search *s) | |||
1056 | trace_bcache_writeback(s->orig_bio); | 1056 | trace_bcache_writeback(s->orig_bio); |
1057 | bch_writeback_add(dc, bio_sectors(bio)); | 1057 | bch_writeback_add(dc, bio_sectors(bio)); |
1058 | 1058 | ||
1059 | if (s->op.flush_journal) { | 1059 | if (bio->bi_rw & REQ_FLUSH) { |
1060 | /* Also need to send a flush to the backing device */ | 1060 | /* Also need to send a flush to the backing device */ |
1061 | s->op.cache_bio = bio_clone_bioset(bio, GFP_NOIO, | 1061 | struct bio *flush = bio_alloc_bioset(0, GFP_NOIO, |
1062 | dc->disk.bio_split); | 1062 | dc->disk.bio_split); |
1063 | 1063 | ||
1064 | bio->bi_size = 0; | 1064 | flush->bi_rw = WRITE_FLUSH; |
1065 | bio->bi_vcnt = 0; | 1065 | flush->bi_bdev = bio->bi_bdev; |
1066 | closure_bio_submit(bio, cl, s->d); | 1066 | flush->bi_end_io = request_endio; |
1067 | flush->bi_private = cl; | ||
1068 | |||
1069 | closure_bio_submit(flush, cl, s->d); | ||
1067 | } else { | 1070 | } else { |
1068 | s->op.cache_bio = bio; | 1071 | s->op.cache_bio = bio; |
1069 | } | 1072 | } |