xfs
[Top] [All Lists]

[PATCH 2/4] xfs: make sure xfs_sync_fsdata covers the log

To: xfs@xxxxxxxxxxx
Subject: [PATCH 2/4] xfs: make sure xfs_sync_fsdata covers the log
From: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Date: Wed, 16 Sep 2009 09:18:20 -0400
Cc: Dave Chinner <david@xxxxxxxxxxxxx>
References: <20090916131818.939008605@xxxxxxxxxxxxxxxxxxxxxx>
User-agent: quilt/0.47-1
From: Dave Chinner <david@xxxxxxxxxxxxx>

We want to always cover the log after writing out the superblock, and
in case of a synchronous writeout make sure we actually wait for the
log to be covered.  That way a filesystem that has been sync()ed can
be considered clean by log recovery.

Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
Signed-off-by: Christoph Hellwig <hch@xxxxxx>
Reviewed-by: Eric Sandeen <sandeen@xxxxxxxxxxx>

Index: xfs/fs/xfs/linux-2.6/xfs_sync.c
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_sync.c        2009-09-16 10:04:30.869278510 
-0300
+++ xfs/fs/xfs/linux-2.6/xfs_sync.c     2009-09-16 10:04:41.193004640 -0300
@@ -309,11 +309,15 @@ xfs_sync_attr(
 STATIC int
 xfs_commit_dummy_trans(
        struct xfs_mount        *mp,
-       uint                    log_flags)
+       uint                    flags)
 {
        struct xfs_inode        *ip = mp->m_rootip;
        struct xfs_trans        *tp;
        int                     error;
+       int                     log_flags = XFS_LOG_FORCE;
+
+       if (flags & SYNC_WAIT)
+               log_flags |= XFS_LOG_SYNC;
 
        /*
         * Put a dummy transaction in the log to tell recovery
@@ -331,16 +335,15 @@ xfs_commit_dummy_trans(
        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);
 
+       /* the log force ensures this transaction is pushed to disk */
        xfs_log_force(mp, 0, log_flags);
-       return 0;
+       return error;
 }
 
-int
+int
 xfs_sync_fsdata(
        struct xfs_mount        *mp,
        int                     flags)
@@ -385,7 +388,20 @@ xfs_sync_fsdata(
        else
                XFS_BUF_ASYNC(bp);
 
-       return xfs_bwrite(mp, bp);
+       error = xfs_bwrite(mp, bp);
+       if (error)
+               return error;
+
+       /*
+        * If this is a data integrity sync make sure all pending buffers
+        * are flushed out for the log coverage check below.
+        */
+       if (flags & SYNC_WAIT)
+               xfs_flush_buftarg(mp->m_ddev_targp, 1);
+
+       if (xfs_log_need_covered(mp))
+               error = xfs_commit_dummy_trans(mp, flags);
+       return error;
 
  out_brelse:
        xfs_buf_relse(bp);
@@ -572,8 +588,6 @@ xfs_sync_worker(
                /* dgc: errors ignored here */
                error = xfs_qm_sync(mp, SYNC_TRYLOCK);
                error = xfs_sync_fsdata(mp, SYNC_TRYLOCK);
-               if (xfs_log_need_covered(mp))
-                       error = xfs_commit_dummy_trans(mp, XFS_LOG_FORCE);
        }
        mp->m_sync_seq++;
        wake_up(&mp->m_wait_single_sync_task);

<Prev in Thread] Current Thread [Next in Thread>