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: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
		
					parent
					
						
							
								981250ca89
							
						
					
				
			
			
				commit
				
					
						9ff8644624
					
				
			
		
					 3 changed files with 49 additions and 38 deletions
				
			
		| 
						 | 
					@ -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)
 | 
				
			||||||
		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)
 | 
				
			||||||
	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 *);
 | 
				
			||||||
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);
 | 
				
			||||||
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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue