aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2013-04-29 18:07:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 18:54:33 -0400
commit7136851117744f1d291bed6d307432699d405109 (patch)
tree6dc7d6bef45e24ad0d3d5d1b9290a81109758172 /fs
parent106c992a5ebef28193cf5958e49ceff5e4aebb04 (diff)
mm: make snapshotting pages for stable writes a per-bio operation
Walking a bio's page mappings has proved problematic, so create a new bio flag to indicate that a bio's data needs to be snapshotted in order to guarantee stable pages during writeback. Next, for the one user (ext3/jbd) of snapshotting, hook all the places where writes can be initiated without PG_writeback set, and set BIO_SNAP_STABLE there. We must also flag journal "metadata" bios for stable writeout, since file data can be written through the journal. Finally, the MS_SNAP_STABLE mount flag (only used by ext3) is now superfluous, so get rid of it. [akpm@linux-foundation.org: rename _submit_bh()'s `flags' to `bio_flags', delobotomize the _submit_bh declaration] [akpm@linux-foundation.org: teeny cleanup] Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Artem Bityutskiy <dedekind1@gmail.com> Reviewed-by: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@kernel.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/buffer.c9
-rw-r--r--fs/ext3/super.c1
-rw-r--r--fs/jbd/commit.c25
3 files changed, 30 insertions, 5 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index b4dcb34c9635..71578d69b82d 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2949,7 +2949,7 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
2949 } 2949 }
2950} 2950}
2951 2951
2952int submit_bh(int rw, struct buffer_head * bh) 2952int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags)
2953{ 2953{
2954 struct bio *bio; 2954 struct bio *bio;
2955 int ret = 0; 2955 int ret = 0;
@@ -2984,6 +2984,7 @@ int submit_bh(int rw, struct buffer_head * bh)
2984 2984
2985 bio->bi_end_io = end_bio_bh_io_sync; 2985 bio->bi_end_io = end_bio_bh_io_sync;
2986 bio->bi_private = bh; 2986 bio->bi_private = bh;
2987 bio->bi_flags |= bio_flags;
2987 2988
2988 /* Take care of bh's that straddle the end of the device */ 2989 /* Take care of bh's that straddle the end of the device */
2989 guard_bh_eod(rw, bio, bh); 2990 guard_bh_eod(rw, bio, bh);
@@ -2997,6 +2998,12 @@ int submit_bh(int rw, struct buffer_head * bh)
2997 bio_put(bio); 2998 bio_put(bio);
2998 return ret; 2999 return ret;
2999} 3000}
3001EXPORT_SYMBOL_GPL(_submit_bh);
3002
3003int submit_bh(int rw, struct buffer_head *bh)
3004{
3005 return _submit_bh(rw, bh, 0);
3006}
3000EXPORT_SYMBOL(submit_bh); 3007EXPORT_SYMBOL(submit_bh);
3001 3008
3002/** 3009/**
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index fb5120a5505c..3dc48cc8b6eb 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2067,7 +2067,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
2067 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal": 2067 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
2068 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": 2068 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
2069 "writeback"); 2069 "writeback");
2070 sb->s_flags |= MS_SNAP_STABLE;
2071 2070
2072 return 0; 2071 return 0;
2073 2072
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 86b39b167c23..11bb11f48b3a 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -162,8 +162,17 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs,
162 162
163 for (i = 0; i < bufs; i++) { 163 for (i = 0; i < bufs; i++) {
164 wbuf[i]->b_end_io = end_buffer_write_sync; 164 wbuf[i]->b_end_io = end_buffer_write_sync;
165 /* We use-up our safety reference in submit_bh() */ 165 /*
166 submit_bh(write_op, wbuf[i]); 166 * Here we write back pagecache data that may be mmaped. Since
167 * we cannot afford to clean the page and set PageWriteback
168 * here due to lock ordering (page lock ranks above transaction
169 * start), the data can change while IO is in flight. Tell the
170 * block layer it should bounce the bio pages if stable data
171 * during write is required.
172 *
173 * We use up our safety reference in submit_bh().
174 */
175 _submit_bh(write_op, wbuf[i], 1 << BIO_SNAP_STABLE);
167 } 176 }
168} 177}
169 178
@@ -667,7 +676,17 @@ start_journal_io:
667 clear_buffer_dirty(bh); 676 clear_buffer_dirty(bh);
668 set_buffer_uptodate(bh); 677 set_buffer_uptodate(bh);
669 bh->b_end_io = journal_end_buffer_io_sync; 678 bh->b_end_io = journal_end_buffer_io_sync;
670 submit_bh(write_op, bh); 679 /*
680 * In data=journal mode, here we can end up
681 * writing pagecache data that might be
682 * mmapped. Since we can't afford to clean the
683 * page and set PageWriteback (see the comment
684 * near the other use of _submit_bh()), the
685 * data can change while the write is in
686 * flight. Tell the block layer to bounce the
687 * bio pages if stable pages are required.
688 */
689 _submit_bh(write_op, bh, 1 << BIO_SNAP_STABLE);
671 } 690 }
672 cond_resched(); 691 cond_resched();
673 692