1 jbd2: optimize jbd2_journal_force_commit
3 From: Dmitry Monakhov <dmonakhov@openvz.org>
5 Current implementation of jbd2_journal_force_commit() is suboptimal because
6 result in empty and useless commits. But callers just want to force and wait
7 any unfinished commits. We already have jbd2_journal_force_commit_nested()
8 which does exactly what we want, except we are guaranteed that we do not hold
9 journal transaction open.
11 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
12 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
14 fs/jbd2/journal.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
15 fs/jbd2/transaction.c | 23 -----------------------
16 include/linux/jbd2.h | 2 +-
17 3 files changed, 49 insertions(+), 38 deletions(-)
19 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
20 index 70990d6..0e6c13b 100644
21 --- a/fs/jbd2/journal.c
22 +++ b/fs/jbd2/journal.c
23 @@ -529,20 +529,17 @@ int jbd2_log_start_commit(journal_t *journal, tid_t tid)
27 - * Force and wait upon a commit if the calling process is not within
28 - * transaction. This is used for forcing out undo-protected data which contains
29 - * bitmaps, when the fs is running out of space.
31 - * We can only force the running transaction if we don't have an active handle;
32 - * otherwise, we will deadlock.
34 - * Returns true if a transaction was started.
35 + * Force and wait any uncommitted transactions. We can only force the running
36 + * transaction if we don't have an active handle, otherwise, we will deadlock.
37 + * Returns: <0 in case of error,
38 + * 0 if nothing to commit,
39 + * 1 if transaction was successfully committed.
41 -int jbd2_journal_force_commit_nested(journal_t *journal)
42 +static int __jbd2_journal_force_commit(journal_t *journal)
44 transaction_t *transaction = NULL;
46 - int need_to_start = 0;
47 + int need_to_start = 0, ret = 0;
49 read_lock(&journal->j_state_lock);
50 if (journal->j_running_transaction && !current->journal_info) {
51 @@ -553,16 +550,53 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
52 transaction = journal->j_committing_transaction;
55 + /* Nothing to commit */
56 read_unlock(&journal->j_state_lock);
57 - return 0; /* Nothing to retry */
61 tid = transaction->t_tid;
62 read_unlock(&journal->j_state_lock);
64 jbd2_log_start_commit(journal, tid);
65 - jbd2_log_wait_commit(journal, tid);
67 + ret = jbd2_log_wait_commit(journal, tid);
75 + * Force and wait upon a commit if the calling process is not within
76 + * transaction. This is used for forcing out undo-protected data which contains
77 + * bitmaps, when the fs is running out of space.
79 + * @journal: journal to force
80 + * Returns true if progress was made.
82 +int jbd2_journal_force_commit_nested(journal_t *journal)
86 + ret = __jbd2_journal_force_commit(journal);
91 + * int journal_force_commit() - force any uncommitted transactions
92 + * @journal: journal to force
94 + * Caller want unconditional commit. We can only force the running transaction
95 + * if we don't have an active handle, otherwise, we will deadlock.
97 +int jbd2_journal_force_commit(journal_t *journal)
101 + J_ASSERT(!current->journal_info);
102 + ret = __jbd2_journal_force_commit(journal);
109 diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
110 index f33342a..dd422e6 100644
111 --- a/fs/jbd2/transaction.c
112 +++ b/fs/jbd2/transaction.c
113 @@ -1661,29 +1661,6 @@ int jbd2_journal_stop(handle_t *handle)
118 - * int jbd2_journal_force_commit() - force any uncommitted transactions
119 - * @journal: journal to force
121 - * For synchronous operations: force any uncommitted transactions
122 - * to disk. May seem kludgy, but it reuses all the handle batching
123 - * code in a very simple manner.
125 -int jbd2_journal_force_commit(journal_t *journal)
130 - handle = jbd2_journal_start(journal, 1);
131 - if (IS_ERR(handle)) {
132 - ret = PTR_ERR(handle);
134 - handle->h_sync = 1;
135 - ret = jbd2_journal_stop(handle);
142 * List management code snippets: various functions for manipulating the
143 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
144 index fb91c8d..c3645b9 100644
145 --- a/include/linux/jbd2.h
146 +++ b/include/linux/jbd2.h
147 @@ -1160,6 +1160,7 @@ extern void jbd2_journal_ack_err (journal_t *);
148 extern int jbd2_journal_clear_err (journal_t *);
149 extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
150 extern int jbd2_journal_force_commit(journal_t *);
151 +extern int jbd2_journal_force_commit_nested(journal_t *);
152 extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
153 extern int jbd2_journal_begin_ordered_truncate(journal_t *journal,
154 struct jbd2_inode *inode, loff_t new_size);
155 @@ -1235,7 +1236,6 @@ extern void jbd2_clear_buffer_revoked_flags(journal_t *journal);
156 int jbd2_log_start_commit(journal_t *journal, tid_t tid);
157 int __jbd2_log_start_commit(journal_t *journal, tid_t tid);
158 int jbd2_journal_start_commit(journal_t *journal, tid_t *tid);
159 -int jbd2_journal_force_commit_nested(journal_t *journal);
160 int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
161 int jbd2_complete_transaction(journal_t *journal, tid_t tid);
162 int jbd2_log_do_checkpoint(journal_t *journal);