/* Filesystem code must call this function when inode is journaled in ordered mode before truncation happens and after the inode has been placed on orphan list with the new inode size. The second condition avoids the race that someone writes new data and we start committing the transaction after this function has been called but before a transaction for truncate is started (and furthermore it allows us to optimize the case where the addition to orphan list happens in the same transaction as write  */
int jbd2_journal_begin_ordered_truncate(journal_t *journal, struct jbd2_inode *jinode, loff_t new_size)
/* Filesystem code must call this function when inode is journaled in ordered mode before truncation happens and after the inode has been placed on orphan list with the new inode size. The second condition avoids the race that someone writes new data and we start committing the transaction after this function has been called but before a transaction for truncate is started (and furthermore it allows us to optimize the case where the addition to orphan list happens in the same transaction as write  */
int jbd2_journal_begin_ordered_truncate(journal_t *journal, struct jbd2_inode *jinode, loff_t new_size)
{
	transaction_t *inode_trans, *commit_trans;
	int ret = 0;
	if (!jinode->i_transaction)
		goto out;
	spin_lock(&journal->j_state_lock);
	commit_trans = journal->j_committing_transaction;
	spin_unlock(&journal->j_state_lock);
	spin_lock(&journal->j_list_lock);
	inode_trans = jinode->i_transaction;
	spin_unlock(&journal->j_list_lock);
	if (inode_trans == commit_trans) {
		ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping,
			new_size, LLONG_MAX);
		if (ret)
			jbd2_journal_abort(journal, ret);
	}
out:
	return ret;
}