Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
Browse files Browse the repository at this point in the history
* '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
  • Loading branch information
Linus Torvalds committed Dec 30, 2011
2 parents 1cac8e8 + be4f1ac commit d2bac6a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 25 deletions.
30 changes: 5 additions & 25 deletions fs/xfs/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -902,22 +881,23 @@ 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
* synchronous transaction we let the log force inside the
* ->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.
Expand Down
36 changes: 36 additions & 0 deletions fs/xfs/xfs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions fs/xfs/xfs_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit d2bac6a

Please sign in to comment.