aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
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