Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 263512
Collapse All | Expand All

(-)a/fs/ext4/inode.c (-4 / +2 lines)
Lines 46-55 Link Here
46
static inline int ext4_begin_ordered_truncate(struct inode *inode,
46
static inline int ext4_begin_ordered_truncate(struct inode *inode,
47
					      loff_t new_size)
47
					      loff_t new_size)
48
{
48
{
49
	return jbd2_journal_begin_ordered_truncate(
49
	return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode,
50
					EXT4_SB(inode->i_sb)->s_journal,
50
						   new_size);
51
					&EXT4_I(inode)->jinode,
52
					new_size);
53
}
51
}
54
52
55
static void ext4_invalidatepage(struct page *page, unsigned long offset);
53
static void ext4_invalidatepage(struct page *page, unsigned long offset);
(-)a/fs/jbd2/transaction.c (-31 / +11 lines)
Lines 2050-2095 done: Link Here
2050
}
2050
}
2051
2051
2052
/*
2052
/*
2053
 * File truncate and transaction commit interact with each other in a
2053
 * This function must be called when inode is journaled in ordered mode
2054
 * non-trivial way.  If a transaction writing data block A is
2054
 * before truncation happens. It starts writeout of truncated part in
2055
 * committing, we cannot discard the data by truncate until we have
2055
 * case it is in the committing transaction so that we stand to ordered
2056
 * written them.  Otherwise if we crashed after the transaction with
2056
 * mode consistency guarantees.
2057
 * write has committed but before the transaction with truncate has
2058
 * committed, we could see stale data in block A.  This function is a
2059
 * helper to solve this problem.  It starts writeout of the truncated
2060
 * part in case it is in the committing transaction.
2061
 *
2062
 * Filesystem code must call this function when inode is journaled in
2063
 * ordered mode before truncation happens and after the inode has been
2064
 * placed on orphan list with the new inode size. The second condition
2065
 * avoids the race that someone writes new data and we start
2066
 * committing the transaction after this function has been called but
2067
 * before a transaction for truncate is started (and furthermore it
2068
 * allows us to optimize the case where the addition to orphan list
2069
 * happens in the same transaction as write --- we don't have to write
2070
 * any data in such case).
2071
 */
2057
 */
2072
int jbd2_journal_begin_ordered_truncate(journal_t *journal,
2058
int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode,
2073
					struct jbd2_inode *jinode,
2074
					loff_t new_size)
2059
					loff_t new_size)
2075
{
2060
{
2076
	transaction_t *inode_trans, *commit_trans;
2061
	journal_t *journal;
2062
	transaction_t *commit_trans;
2077
	int ret = 0;
2063
	int ret = 0;
2078
2064
2079
	/* This is a quick check to avoid locking if not necessary */
2065
	if (!inode->i_transaction && !inode->i_next_transaction)
2080
	if (!jinode->i_transaction)
2081
		goto out;
2066
		goto out;
2082
	/* Locks are here just to force reading of recent values, it is
2067
	journal = inode->i_transaction->t_journal;
2083
	 * enough that the transaction was not committing before we started
2084
	 * a transaction adding the inode to orphan list */
2085
	spin_lock(&journal->j_state_lock);
2068
	spin_lock(&journal->j_state_lock);
2086
	commit_trans = journal->j_committing_transaction;
2069
	commit_trans = journal->j_committing_transaction;
2087
	spin_unlock(&journal->j_state_lock);
2070
	spin_unlock(&journal->j_state_lock);
2088
	spin_lock(&journal->j_list_lock);
2071
	if (inode->i_transaction == commit_trans) {
2089
	inode_trans = jinode->i_transaction;
2072
		ret = filemap_fdatawrite_range(inode->i_vfs_inode->i_mapping,
2090
	spin_unlock(&journal->j_list_lock);
2091
	if (inode_trans == commit_trans) {
2092
		ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping,
2093
			new_size, LLONG_MAX);
2073
			new_size, LLONG_MAX);
2094
		if (ret)
2074
		if (ret)
2095
			jbd2_journal_abort(journal, ret);
2075
			jbd2_journal_abort(journal, ret);
(-)a/fs/ocfs2/journal.h (-4 / +2 lines)
Lines 445-454 static inline int ocfs2_jbd2_file_inode( Link Here
445
static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
445
static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
446
					       loff_t new_size)
446
					       loff_t new_size)
447
{
447
{
448
	return jbd2_journal_begin_ordered_truncate(
448
	return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode,
449
				OCFS2_SB(inode->i_sb)->journal->j_journal,
449
						   new_size);
450
				&OCFS2_I(inode)->ip_jinode,
451
				new_size);
452
}
450
}
453
451
454
#endif /* OCFS2_JOURNAL_H */
452
#endif /* OCFS2_JOURNAL_H */
(-)a/include/linux/jbd2.h (-2 / +1 lines)
Lines 1087-1094 extern int jbd2_journal_clear_err (j Link Here
1087
extern int	   jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
1087
extern int	   jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
1088
extern int	   jbd2_journal_force_commit(journal_t *);
1088
extern int	   jbd2_journal_force_commit(journal_t *);
1089
extern int	   jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
1089
extern int	   jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
1090
extern int	   jbd2_journal_begin_ordered_truncate(journal_t *journal,
1090
extern int	   jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size);
1091
				struct jbd2_inode *inode, loff_t new_size);
1092
extern void	   jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode);
1091
extern void	   jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode);
1093
extern void	   jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_inode *jinode);
1092
extern void	   jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_inode *jinode);
1094
1093

Return to bug 263512