Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Dec 2011 01:05:45 +0000 (17:05 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Dec 2011 01:05:45 +0000 (17:05 -0800)
* '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

fs/xfs/xfs_super.c
fs/xfs/xfs_sync.c
fs/xfs/xfs_sync.h

index 3eca58f..8a89949 100644 (file)
@@ -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.
index be5c51d..f0994ae 100644 (file)
@@ -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);
 
index 941202e..fa96547 100644 (file)
@@ -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);