diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2013-04-29 18:07:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 18:54:33 -0400 |
commit | 7136851117744f1d291bed6d307432699d405109 (patch) | |
tree | 6dc7d6bef45e24ad0d3d5d1b9290a81109758172 /fs/jbd/commit.c | |
parent | 106c992a5ebef28193cf5958e49ceff5e4aebb04 (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/jbd/commit.c')
-rw-r--r-- | fs/jbd/commit.c | 25 |
1 files changed, 22 insertions, 3 deletions
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 | ||