]> git.hungrycats.org Git - linux/commitdiff
XFS: Fold some code paths together in the xfs fsync implementation.
authorStephen Lord <lord@sgi.com>
Thu, 26 Sep 2002 23:25:34 +0000 (01:25 +0200)
committerChristoph Hellwig <hch@sgi.com>
Thu, 26 Sep 2002 23:25:34 +0000 (01:25 +0200)
Modid: 2.5.x-xfs:slinx:128239a

fs/xfs/xfs_vnodeops.c

index 19c903a719d0d680306bddeb5e7046b710c225d3..46c42a2cd8edf6d007b40814822c936746003e8f 100644 (file)
@@ -1144,138 +1144,70 @@ xfs_fsync(
         * (Note that xfs_inode_item_format() called at commit clears
         * the update_* fields.)
         */
-       if (!(flag & FSYNC_DATA)) {
-               xfs_ilock(ip, XFS_ILOCK_SHARED);
+       xfs_ilock(ip, XFS_ILOCK_SHARED);
 
-               if (ip->i_update_core == 0)  {
-                       /*
-                        * Timestamps/size haven't changed since last inode
-                        * flush or inode transaction commit.  That means
-                        * either nothing got written or a transaction
-                        * committed which caught the updates.  If the
-                        * latter happened and the transaction hasn't
-                        * hit the disk yet, the inode will be still
-                        * be pinned.  If it is, force the log.
-                        */
-                       if (xfs_ipincount(ip) == 0)  {
-                               xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-                                               XFS_ILOCK_SHARED);
-                       } else  {
-                               xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-                                               XFS_ILOCK_SHARED);
-                               xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
-                                             XFS_LOG_FORCE |
-                                             ((flag & FSYNC_WAIT)
-                                              ? XFS_LOG_SYNC : 0));
-                       }
-                       error = 0;
-               } else  {
-                       /*
-                        * Kick off a transaction to log the inode
-                        * core to get the updates.  Make it
-                        * sync if FSYNC_WAIT is passed in (which
-                        * is done by everybody but specfs).  The
-                        * sync transaction will also force the log.
-                        */
-                       xfs_iunlock(ip, XFS_ILOCK_SHARED);
-                       tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
-                       if ((error = xfs_trans_reserve(tp, 0,
-                                       XFS_FSYNC_TS_LOG_RES(ip->i_mount),
-                                       0, 0, 0)))  {
-                               xfs_trans_cancel(tp, 0);
-                               xfs_iunlock(ip, XFS_IOLOCK_EXCL);
-                               return error;
-                       }
-                       xfs_ilock(ip, XFS_ILOCK_EXCL);
+       /* If we are flushing data then we care about update_size
+        * being set, otherwise we care about update_core
+        */
+       if ((flag & FSYNC_DATA) ?
+                       (ip->i_update_size == 0) :
+                       (ip->i_update_core == 0)) {
+               /*
+                * Timestamps/size haven't changed since last inode
+                * flush or inode transaction commit.  That means
+                * either nothing got written or a transaction
+                * committed which caught the updates.  If the
+                * latter happened and the transaction hasn't
+                * hit the disk yet, the inode will be still
+                * be pinned.  If it is, force the log.
+                */
 
-                       /*
-                        * Note - it's possible that we might have pushed
-                        * ourselves out of the way during trans_reserve
-                        * which would flush the inode.  But there's no
-                        * guarantee that the inode buffer has actually
-                        * gone out yet (it's delwri).  Plus the buffer
-                        * could be pinned anyway if it's part of an
-                        * inode in another recent transaction.  So we
-                        * play it safe and fire off the transaction anyway.
-                        */
-                       xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
-                       xfs_trans_ihold(tp, ip);
-                       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-                       if (flag & FSYNC_WAIT)
-                               xfs_trans_set_sync(tp);
-                       error = xfs_trans_commit(tp, 0, NULL);
-
-                       xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
+               xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED);
+
+               if (xfs_ipincount(ip)) {
+                       xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
+                                     XFS_LOG_FORCE |
+                                     ((flag & FSYNC_WAIT)
+                                      ? XFS_LOG_SYNC : 0));
                }
-       } else {
+               error = 0;
+       } else  {
                /*
-                * We don't care about the timestamps here.  We
-                * only care about the size field growing on us
-                * and forcing any space allocation transactions.
-                * We have to flush changes to the size fields
-                * otherwise we could write out data that
-                * becomes inaccessible after a crash.
+                * Kick off a transaction to log the inode
+                * core to get the updates.  Make it
+                * sync if FSYNC_WAIT is passed in (which
+                * is done by everybody but specfs).  The
+                * sync transaction will also force the log.
                 */
-               xfs_ilock(ip, XFS_ILOCK_SHARED);
-
-               if (ip->i_update_size == 0)  {
-                       /*
-                        * Force the log if the inode is pinned.
-                        * That ensures that all transactions committed
-                        * against the inode hit the disk.  This may do
-                        * too much work but it's safe.
-                        */
-                       if (xfs_ipincount(ip) == 0)  {
-                               xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-                                               XFS_ILOCK_SHARED);
-                       } else  {
-                               xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-                                               XFS_ILOCK_SHARED);
-                               xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
-                                             XFS_LOG_FORCE |
-                                             ((flag & FSYNC_WAIT)
-                                              ? XFS_LOG_SYNC : 0));
-                       }
-                       error = 0;
-               } else  {
-                       /*
-                        * Kick off a sync transaction to log the inode
-                        * core.  The transaction has to be sync since
-                        * we need these updates to guarantee that the
-                        * data written will be seen.  The sync
-                        * transaction will also force the log.
-                        */
-                       xfs_iunlock(ip, XFS_ILOCK_SHARED);
+               xfs_iunlock(ip, XFS_ILOCK_SHARED);
+               tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
+               if ((error = xfs_trans_reserve(tp, 0,
+                               XFS_FSYNC_TS_LOG_RES(ip->i_mount),
+                               0, 0, 0)))  {
+                       xfs_trans_cancel(tp, 0);
+                       xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+                       return error;
+               }
+               xfs_ilock(ip, XFS_ILOCK_EXCL);
 
-                       tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
-                       if ((error = xfs_trans_reserve(tp, 0,
-                                       XFS_FSYNC_TS_LOG_RES(ip->i_mount),
-                                       0, 0, 0)))  {
-                               xfs_trans_cancel(tp, 0);
-                               xfs_iunlock(ip, XFS_IOLOCK_EXCL);
-                               return error;
-                       }
-                       xfs_ilock(ip, XFS_ILOCK_EXCL);
+               /*
+                * Note - it's possible that we might have pushed
+                * ourselves out of the way during trans_reserve
+                * which would flush the inode.  But there's no
+                * guarantee that the inode buffer has actually
+                * gone out yet (it's delwri).  Plus the buffer
+                * could be pinned anyway if it's part of an
+                * inode in another recent transaction.  So we
+                * play it safe and fire off the transaction anyway.
+                */
+               xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
+               xfs_trans_ihold(tp, ip);
+               xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+               if (flag & FSYNC_WAIT)
+                       xfs_trans_set_sync(tp);
+               error = xfs_trans_commit(tp, 0, NULL);
 
-                       /*
-                        * Note - it's possible that we might have pushed
-                        * ourselves out of the way during trans_reserve
-                        * which would flush the inode.  But there's no
-                        * guarantee that the inode buffer has actually
-                        * gone out yet (it's delwri).  Plus the buffer
-                        * could be pinned anyway if it's part of an
-                        * inode in another recent transaction.  So we
-                        * play it safe and fire off the transaction anyway.
-                        */
-                       xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
-                       xfs_trans_ihold(tp, ip);
-                       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-                       if (flag & FSYNC_WAIT)
-                               xfs_trans_set_sync(tp);
-                       error = xfs_trans_commit(tp, 0, NULL);
-
-                       xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
-               }
+               xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
        }
        return error;
 }