diff options
Diffstat (limited to 'fs/xfs/xfs_sync.c')
| -rw-r--r-- | fs/xfs/xfs_sync.c | 36 | 
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index be5c51d8f75..f0994aedcd1 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c @@ -336,6 +336,32 @@ xfs_sync_fsdata(  	return error;  } +int +xfs_log_dirty_inode( +	struct xfs_inode	*ip, +	struct xfs_perag	*pag, +	int			flags) +{ +	struct xfs_mount	*mp = ip->i_mount; +	struct xfs_trans	*tp; +	int			error; + +	if (!ip->i_update_core) +		return 0; + +	tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); +	error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); +	if (error) { +		xfs_trans_cancel(tp, 0); +		return error; +	} + +	xfs_ilock(ip, XFS_ILOCK_EXCL); +	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); +	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); +	return xfs_trans_commit(tp, 0); +} +  /*   * When remounting a filesystem read-only or freezing the filesystem, we have   * two phases to execute. This first phase is syncing the data before we @@ -359,6 +385,16 @@ xfs_quiesce_data(  {  	int			error, error2 = 0; +	/* +	 * Log all pending size and timestamp updates.  The vfs writeback +	 * code is supposed to do this, but due to its overagressive +	 * livelock detection it will skip inodes where appending writes +	 * were written out in the first non-blocking sync phase if their +	 * completion took long enough that it happened after taking the +	 * timestamp for the cut-off in the blocking phase. +	 */ +	xfs_inode_ag_iterator(mp, xfs_log_dirty_inode, 0); +  	xfs_qm_sync(mp, SYNC_TRYLOCK);  	xfs_qm_sync(mp, SYNC_WAIT);  |