]> Pileus Git - ~andy/linux/commitdiff
[XFS] split out two helpers from xfs_syncsub
authorChristoph Hellwig <hch@infradead.org>
Thu, 30 Oct 2008 06:14:53 +0000 (17:14 +1100)
committerLachlan McIlroy <lachlan@sgi.com>
Thu, 30 Oct 2008 06:14:53 +0000 (17:14 +1100)
Split out two helpers from xfs_syncsub for the dummy log commit and the
superblock writeout.

SGI-PV: 988140

SGI-Modid: xfs-linux-melb:xfs-kern:32303a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
fs/xfs/linux-2.6/xfs_sync.c

index 53d85ecb1d50ec4ddca94fa236e723a9c207ef9e..59da3327a6b5eaa4250ba1dabf63bdb9678c34ce 100644 (file)
@@ -315,6 +315,93 @@ xfs_sync_inodes(
        return XFS_ERROR(last_error);
 }
 
+STATIC int
+xfs_commit_dummy_trans(
+       struct xfs_mount        *mp,
+       uint                    log_flags)
+{
+       struct xfs_inode        *ip = mp->m_rootip;
+       struct xfs_trans        *tp;
+       int                     error;
+
+       /*
+        * Put a dummy transaction in the log to tell recovery
+        * that all others are OK.
+        */
+       tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
+       error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_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_ihold(tp, ip);
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+       /* XXX(hch): ignoring the error here.. */
+       error = xfs_trans_commit(tp, 0);
+
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+       xfs_log_force(mp, 0, log_flags);
+       return 0;
+}
+
+STATIC int
+xfs_sync_fsdata(
+       struct xfs_mount        *mp,
+       int                     flags)
+{
+       struct xfs_buf          *bp;
+       struct xfs_buf_log_item *bip;
+       int                     error = 0;
+
+       /*
+        * If this is xfssyncd() then only sync the superblock if we can
+        * lock it without sleeping and it is not pinned.
+        */
+       if (flags & SYNC_BDFLUSH) {
+               ASSERT(!(flags & SYNC_WAIT));
+
+               bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
+               if (!bp)
+                       goto out;
+
+               bip = XFS_BUF_FSPRIVATE(bp, struct xfs_buf_log_item *);
+               if (!bip || !xfs_buf_item_dirty(bip) || XFS_BUF_ISPINNED(bp))
+                       goto out_brelse;
+       } else {
+               bp = xfs_getsb(mp, 0);
+
+               /*
+                * If the buffer is pinned then push on the log so we won't
+                * get stuck waiting in the write for someone, maybe
+                * ourselves, to flush the log.
+                *
+                * Even though we just pushed the log above, we did not have
+                * the superblock buffer locked at that point so it can
+                * become pinned in between there and here.
+                */
+               if (XFS_BUF_ISPINNED(bp))
+                       xfs_log_force(mp, 0, XFS_LOG_FORCE);
+       }
+
+
+       if (flags & SYNC_WAIT)
+               XFS_BUF_UNASYNC(bp);
+       else
+               XFS_BUF_ASYNC(bp);
+
+       return xfs_bwrite(mp, bp);
+
+ out_brelse:
+       xfs_buf_relse(bp);
+ out:
+       return error;
+}
+
 /*
  * xfs sync routine for internal use
  *
@@ -331,8 +418,6 @@ xfs_syncsub(
        int             error = 0;
        int             last_error = 0;
        uint            log_flags = XFS_LOG_FORCE;
-       xfs_buf_t       *bp;
-       xfs_buf_log_item_t      *bip;
 
        /*
         * Sync out the log.  This ensures that the log is periodically
@@ -355,83 +440,22 @@ xfs_syncsub(
         * log activity, so if this isn't vfs_sync() then flush
         * the log again.
         */
-       if (flags & SYNC_DELWRI) {
-               xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
-       }
+       if (flags & SYNC_DELWRI)
+               xfs_log_force(mp, 0, log_flags);
 
        if (flags & SYNC_FSDATA) {
-               /*
-                * If this is vfs_sync() then only sync the superblock
-                * if we can lock it without sleeping and it is not pinned.
-                */
-               if (flags & SYNC_BDFLUSH) {
-                       bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
-                       if (bp != NULL) {
-                               bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
-                               if ((bip != NULL) &&
-                                   xfs_buf_item_dirty(bip)) {
-                                       if (!(XFS_BUF_ISPINNED(bp))) {
-                                               XFS_BUF_ASYNC(bp);
-                                               error = xfs_bwrite(mp, bp);
-                                       } else {
-                                               xfs_buf_relse(bp);
-                                       }
-                               } else {
-                                       xfs_buf_relse(bp);
-                               }
-                       }
-               } else {
-                       bp = xfs_getsb(mp, 0);
-                       /*
-                        * If the buffer is pinned then push on the log so
-                        * we won't get stuck waiting in the write for
-                        * someone, maybe ourselves, to flush the log.
-                        * Even though we just pushed the log above, we
-                        * did not have the superblock buffer locked at
-                        * that point so it can become pinned in between
-                        * there and here.
-                        */
-                       if (XFS_BUF_ISPINNED(bp))
-                               xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
-                       if (flags & SYNC_WAIT)
-                               XFS_BUF_UNASYNC(bp);
-                       else
-                               XFS_BUF_ASYNC(bp);
-                       error = xfs_bwrite(mp, bp);
-               }
-               if (error) {
+               error = xfs_sync_fsdata(mp, flags);
+               if (error)
                        last_error = error;
-               }
        }
 
        /*
         * Now check to see if the log needs a "dummy" transaction.
         */
        if (!(flags & SYNC_REMOUNT) && xfs_log_need_covered(mp)) {
-               xfs_trans_t *tp;
-               xfs_inode_t *ip;
-
-               /*
-                * Put a dummy transaction in the log to tell
-                * recovery that all others are OK.
-                */
-               tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
-               if ((error = xfs_trans_reserve(tp, 0,
-                               XFS_ICHANGE_LOG_RES(mp),
-                               0, 0, 0)))  {
-                       xfs_trans_cancel(tp, 0);
+               error = xfs_commit_dummy_trans(mp, log_flags);
+               if (error)
                        return error;
-               }
-
-               ip = mp->m_rootip;
-               xfs_ilock(ip, XFS_ILOCK_EXCL);
-
-               xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-               xfs_trans_ihold(tp, ip);
-               xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-               error = xfs_trans_commit(tp, 0);
-               xfs_iunlock(ip, XFS_ILOCK_EXCL);
-               xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
        }
 
        /*