|
@@ -162,8 +162,17 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs,
|
|
|
|
|
|
for (i = 0; i < bufs; i++) {
|
|
|
wbuf[i]->b_end_io = end_buffer_write_sync;
|
|
|
- /* We use-up our safety reference in submit_bh() */
|
|
|
- submit_bh(write_op, wbuf[i]);
|
|
|
+ /*
|
|
|
+ * Here we write back pagecache data that may be mmaped. Since
|
|
|
+ * we cannot afford to clean the page and set PageWriteback
|
|
|
+ * here due to lock ordering (page lock ranks above transaction
|
|
|
+ * start), the data can change while IO is in flight. Tell the
|
|
|
+ * block layer it should bounce the bio pages if stable data
|
|
|
+ * during write is required.
|
|
|
+ *
|
|
|
+ * We use up our safety reference in submit_bh().
|
|
|
+ */
|
|
|
+ _submit_bh(write_op, wbuf[i], 1 << BIO_SNAP_STABLE);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -667,7 +676,17 @@ start_journal_io:
|
|
|
clear_buffer_dirty(bh);
|
|
|
set_buffer_uptodate(bh);
|
|
|
bh->b_end_io = journal_end_buffer_io_sync;
|
|
|
- submit_bh(write_op, bh);
|
|
|
+ /*
|
|
|
+ * In data=journal mode, here we can end up
|
|
|
+ * writing pagecache data that might be
|
|
|
+ * mmapped. Since we can't afford to clean the
|
|
|
+ * page and set PageWriteback (see the comment
|
|
|
+ * near the other use of _submit_bh()), the
|
|
|
+ * data can change while the write is in
|
|
|
+ * flight. Tell the block layer to bounce the
|
|
|
+ * bio pages if stable pages are required.
|
|
|
+ */
|
|
|
+ _submit_bh(write_op, bh, 1 << BIO_SNAP_STABLE);
|
|
|
}
|
|
|
cond_resched();
|
|
|
|