Commit 9ff86446 authored by Dmitry Monakhov's avatar Dmitry Monakhov Committed by Theodore Ts'o

jbd2: optimize jbd2_journal_force_commit

Current implementation of jbd2_journal_force_commit() is suboptimal because
result in empty and useless commits. But callers just want to force and wait
any unfinished commits. We already have jbd2_journal_force_commit_nested()
which does exactly what we want, except we are guaranteed that we do not hold
journal transaction open.
Signed-off-by: default avatarDmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 981250ca
...@@ -529,20 +529,17 @@ int jbd2_log_start_commit(journal_t *journal, tid_t tid) ...@@ -529,20 +529,17 @@ int jbd2_log_start_commit(journal_t *journal, tid_t tid)
} }
/* /*
* Force and wait upon a commit if the calling process is not within * Force and wait any uncommitted transactions. We can only force the running
* transaction. This is used for forcing out undo-protected data which contains * transaction if we don't have an active handle, otherwise, we will deadlock.
* bitmaps, when the fs is running out of space. * Returns: <0 in case of error,
* * 0 if nothing to commit,
* We can only force the running transaction if we don't have an active handle; * 1 if transaction was successfully committed.
* otherwise, we will deadlock.
*
* Returns true if a transaction was started.
*/ */
int jbd2_journal_force_commit_nested(journal_t *journal) static int __jbd2_journal_force_commit(journal_t *journal)
{ {
transaction_t *transaction = NULL; transaction_t *transaction = NULL;
tid_t tid; tid_t tid;
int need_to_start = 0; int need_to_start = 0, ret = 0;
read_lock(&journal->j_state_lock); read_lock(&journal->j_state_lock);
if (journal->j_running_transaction && !current->journal_info) { if (journal->j_running_transaction && !current->journal_info) {
...@@ -553,16 +550,53 @@ int jbd2_journal_force_commit_nested(journal_t *journal) ...@@ -553,16 +550,53 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
transaction = journal->j_committing_transaction; transaction = journal->j_committing_transaction;
if (!transaction) { if (!transaction) {
/* Nothing to commit */
read_unlock(&journal->j_state_lock); read_unlock(&journal->j_state_lock);
return 0; /* Nothing to retry */ return 0;
} }
tid = transaction->t_tid; tid = transaction->t_tid;
read_unlock(&journal->j_state_lock); read_unlock(&journal->j_state_lock);
if (need_to_start) if (need_to_start)
jbd2_log_start_commit(journal, tid); jbd2_log_start_commit(journal, tid);
jbd2_log_wait_commit(journal, tid); ret = jbd2_log_wait_commit(journal, tid);
return 1; if (!ret)
ret = 1;
return ret;
}
/**
* Force and wait upon a commit if the calling process is not within
* transaction. This is used for forcing out undo-protected data which contains
* bitmaps, when the fs is running out of space.
*
* @journal: journal to force
* Returns true if progress was made.
*/
int jbd2_journal_force_commit_nested(journal_t *journal)
{
int ret;
ret = __jbd2_journal_force_commit(journal);
return ret > 0;
}
/**
* int journal_force_commit() - force any uncommitted transactions
* @journal: journal to force
*
* Caller want unconditional commit. We can only force the running transaction
* if we don't have an active handle, otherwise, we will deadlock.
*/
int jbd2_journal_force_commit(journal_t *journal)
{
int ret;
J_ASSERT(!current->journal_info);
ret = __jbd2_journal_force_commit(journal);
if (ret > 0)
ret = 0;
return ret;
} }
/* /*
......
...@@ -1661,29 +1661,6 @@ int jbd2_journal_stop(handle_t *handle) ...@@ -1661,29 +1661,6 @@ int jbd2_journal_stop(handle_t *handle)
return err; return err;
} }
/**
* int jbd2_journal_force_commit() - force any uncommitted transactions
* @journal: journal to force
*
* For synchronous operations: force any uncommitted transactions
* to disk. May seem kludgy, but it reuses all the handle batching
* code in a very simple manner.
*/
int jbd2_journal_force_commit(journal_t *journal)
{
handle_t *handle;
int ret;
handle = jbd2_journal_start(journal, 1);
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
} else {
handle->h_sync = 1;
ret = jbd2_journal_stop(handle);
}
return ret;
}
/* /*
* *
* List management code snippets: various functions for manipulating the * List management code snippets: various functions for manipulating the
......
...@@ -1160,6 +1160,7 @@ extern void jbd2_journal_ack_err (journal_t *); ...@@ -1160,6 +1160,7 @@ extern void jbd2_journal_ack_err (journal_t *);
extern int jbd2_journal_clear_err (journal_t *); extern int jbd2_journal_clear_err (journal_t *);
extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *); extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
extern int jbd2_journal_force_commit(journal_t *); extern int jbd2_journal_force_commit(journal_t *);
extern int jbd2_journal_force_commit_nested(journal_t *);
extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode); extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
extern int jbd2_journal_begin_ordered_truncate(journal_t *journal, extern int jbd2_journal_begin_ordered_truncate(journal_t *journal,
struct jbd2_inode *inode, loff_t new_size); struct jbd2_inode *inode, loff_t new_size);
...@@ -1235,7 +1236,6 @@ extern void jbd2_clear_buffer_revoked_flags(journal_t *journal); ...@@ -1235,7 +1236,6 @@ extern void jbd2_clear_buffer_revoked_flags(journal_t *journal);
int jbd2_log_start_commit(journal_t *journal, tid_t tid); int jbd2_log_start_commit(journal_t *journal, tid_t tid);
int __jbd2_log_start_commit(journal_t *journal, tid_t tid); int __jbd2_log_start_commit(journal_t *journal, tid_t tid);
int jbd2_journal_start_commit(journal_t *journal, tid_t *tid); int jbd2_journal_start_commit(journal_t *journal, tid_t *tid);
int jbd2_journal_force_commit_nested(journal_t *journal);
int jbd2_log_wait_commit(journal_t *journal, tid_t tid); int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
int jbd2_complete_transaction(journal_t *journal, tid_t tid); int jbd2_complete_transaction(journal_t *journal, tid_t tid);
int jbd2_log_do_checkpoint(journal_t *journal); int jbd2_log_do_checkpoint(journal_t *journal);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment