ext4: Fix async commit mode to be safe by using a barrier
Previously the journal_async_commit mount option was equivalent to using barrier=0 (and just as unsafe). This patch fixes it so that we eliminate the barrier before the commit block (by not using ordered mode), and explicitly issuing an empty barrier bio after writing the commit block. Because of the journal checksum, it is safe to do this; if the journal blocks are not all written before a power failure, the checksum in the commit block will prevent the last transaction from being replayed. Using the fs_mark benchmark, using journal_async_commit shows a 50% improvement: FSUse% Count Size Files/sec App Overhead 8 1000 10240 30.5 28242 vs. FSUse% Count Size Files/sec App Overhead 8 1000 10240 45.8 28620 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
71290b368a
commit
0e3d2a6313
@ -25,6 +25,7 @@
|
|||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
|
#include <linux/blkdev.h>
|
||||||
#include <trace/events/jbd2.h>
|
#include <trace/events/jbd2.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -133,8 +134,8 @@ static int journal_submit_commit_record(journal_t *journal,
|
|||||||
bh->b_end_io = journal_end_buffer_io_sync;
|
bh->b_end_io = journal_end_buffer_io_sync;
|
||||||
|
|
||||||
if (journal->j_flags & JBD2_BARRIER &&
|
if (journal->j_flags & JBD2_BARRIER &&
|
||||||
!JBD2_HAS_INCOMPAT_FEATURE(journal,
|
!JBD2_HAS_INCOMPAT_FEATURE(journal,
|
||||||
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
|
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
|
||||||
set_buffer_ordered(bh);
|
set_buffer_ordered(bh);
|
||||||
barrier_done = 1;
|
barrier_done = 1;
|
||||||
}
|
}
|
||||||
@ -706,11 +707,13 @@ start_journal_io:
|
|||||||
/* Done it all: now write the commit record asynchronously. */
|
/* Done it all: now write the commit record asynchronously. */
|
||||||
|
|
||||||
if (JBD2_HAS_INCOMPAT_FEATURE(journal,
|
if (JBD2_HAS_INCOMPAT_FEATURE(journal,
|
||||||
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
|
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
|
||||||
err = journal_submit_commit_record(journal, commit_transaction,
|
err = journal_submit_commit_record(journal, commit_transaction,
|
||||||
&cbh, crc32_sum);
|
&cbh, crc32_sum);
|
||||||
if (err)
|
if (err)
|
||||||
__jbd2_journal_abort_hard(journal);
|
__jbd2_journal_abort_hard(journal);
|
||||||
|
if (journal->j_flags & JBD2_BARRIER)
|
||||||
|
blkdev_issue_flush(journal->j_dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -833,7 +836,7 @@ wait_for_iobuf:
|
|||||||
jbd_debug(3, "JBD: commit phase 5\n");
|
jbd_debug(3, "JBD: commit phase 5\n");
|
||||||
|
|
||||||
if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
|
if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
|
||||||
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
|
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
|
||||||
err = journal_submit_commit_record(journal, commit_transaction,
|
err = journal_submit_commit_record(journal, commit_transaction,
|
||||||
&cbh, crc32_sum);
|
&cbh, crc32_sum);
|
||||||
if (err)
|
if (err)
|
||||||
|
Loading…
Reference in New Issue
Block a user