Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2bac6ab authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* 'for-linus' of git://oss.sgi.com/xfs/xfs:
  xfs: log all dirty inodes in xfs_fs_sync_fs
  xfs: log the inode in ->write_inode calls for kupdate
parents 1cac8e88 be4f1ac8
Loading
Loading
Loading
Loading
+5 −25
Original line number Diff line number Diff line
@@ -868,27 +868,6 @@ xfs_fs_dirty_inode(
	XFS_I(inode)->i_update_core = 1;
}

STATIC int
xfs_log_inode(
	struct xfs_inode	*ip)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_trans	*tp;
	int			error;

	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);
}

STATIC int
xfs_fs_write_inode(
	struct inode		*inode,
@@ -902,10 +881,8 @@ xfs_fs_write_inode(

	if (XFS_FORCED_SHUTDOWN(mp))
		return -XFS_ERROR(EIO);
	if (!ip->i_update_core)
		return 0;

	if (wbc->sync_mode == WB_SYNC_ALL) {
	if (wbc->sync_mode == WB_SYNC_ALL || wbc->for_kupdate) {
		/*
		 * Make sure the inode has made it it into the log.  Instead
		 * of forcing it all the way to stable storage using a
@@ -913,11 +890,14 @@ xfs_fs_write_inode(
		 * ->sync_fs call do that for thus, which reduces the number
		 * of synchronous log forces dramatically.
		 */
		error = xfs_log_inode(ip);
		error = xfs_log_dirty_inode(ip, NULL, 0);
		if (error)
			goto out;
		return 0;
	} else {
		if (!ip->i_update_core)
			return 0;

		/*
		 * We make this non-blocking if the inode is contended, return
		 * EAGAIN to indicate to the caller that they did not succeed.
+36 −0
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ void xfs_quiesce_attr(struct xfs_mount *mp);

void xfs_flush_inodes(struct xfs_inode *ip);

int xfs_log_dirty_inode(struct xfs_inode *ip, struct xfs_perag *pag, int flags);

int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
int xfs_reclaim_inodes_count(struct xfs_mount *mp);
void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);