xfs: unlock the inode before log force in xfs_fsync
authorChristoph Hellwig <hch@infradead.org>
Mon, 19 Sep 2011 14:55:51 +0000 (14:55 +0000)
committerAlex Elder <aelder@sgi.com>
Wed, 12 Oct 2011 02:15:08 +0000 (21:15 -0500)
Only read the LSN we need to push to with the ilock held, and then release
it before we do the log force to improve concurrency.

This also removes the only direct caller of _xfs_trans_commit, thus
allowing it to be merged into the plain xfs_trans_commit again.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
fs/xfs/xfs_file.c
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans.h

index 558543c146b3a0c0450dfc35b3fe94fef1259aff..d8ef02eb178a8e3e128b35f8f4ecfa15a204a6fc 100644 (file)
@@ -137,6 +137,7 @@ xfs_file_fsync(
        struct xfs_trans        *tp;
        int                     error = 0;
        int                     log_flushed = 0;
+       xfs_lsn_t               lsn = 0;
 
        trace_xfs_file_fsync(ip);
 
@@ -214,9 +215,9 @@ xfs_file_fsync(
                 */
                xfs_trans_ijoin(tp, ip);
                xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-               xfs_trans_set_sync(tp);
-               error = _xfs_trans_commit(tp, 0, &log_flushed);
+               error = xfs_trans_commit(tp, 0);
 
+               lsn = ip->i_itemp->ili_last_lsn;
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
        } else {
                /*
@@ -227,14 +228,14 @@ xfs_file_fsync(
                 * disk yet, the inode will be still be pinned.  If it is,
                 * force the log.
                 */
-               if (xfs_ipincount(ip)) {
-                       error = _xfs_log_force_lsn(mp,
-                                       ip->i_itemp->ili_last_lsn,
-                                       XFS_LOG_SYNC, &log_flushed);
-               }
+               if (xfs_ipincount(ip))
+                       lsn = ip->i_itemp->ili_last_lsn;
                xfs_iunlock(ip, XFS_ILOCK_SHARED);
        }
 
+       if (!error && lsn)
+               error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed);
+
        /*
         * If we only have a single device, and the log force about was
         * a no-op we might have to flush the data device cache here.
index efc147f0e9b6068cfc67fdc9b3a6639d4d8e76d8..b64c8c79736a4d6627367c4436ede9fc01bb8af9 100644 (file)
@@ -1790,9 +1790,7 @@ xfs_trans_commit_cil(
 }
 
 /*
- * xfs_trans_commit
- *
- * Commit the given transaction to the log a/synchronously.
+ * Commit the given transaction to the log.
  *
  * XFS disk error handling mechanism is not based on a typical
  * transaction abort mechanism. Logically after the filesystem
@@ -1804,10 +1802,9 @@ xfs_trans_commit_cil(
  * Do not reference the transaction structure after this call.
  */
 int
-_xfs_trans_commit(
+xfs_trans_commit(
        struct xfs_trans        *tp,
-       uint                    flags,
-       int                     *log_flushed)
+       uint                    flags)
 {
        struct xfs_mount        *mp = tp->t_mountp;
        xfs_lsn_t               commit_lsn = -1;
@@ -1866,7 +1863,7 @@ _xfs_trans_commit(
        if (sync) {
                if (!error) {
                        error = _xfs_log_force_lsn(mp, commit_lsn,
-                                     XFS_LOG_SYNC, log_flushed);
+                                     XFS_LOG_SYNC, NULL);
                }
                XFS_STATS_INC(xs_trans_sync);
        } else {
index 06a9759b6352aa497d64396d9ce3fa0900506d3f..54b0b1cc3e3fbcaa6bad4a9158fff8607e66735d 100644 (file)
@@ -487,10 +487,7 @@ void               xfs_trans_log_efd_extent(xfs_trans_t *,
                                         struct xfs_efd_log_item *,
                                         xfs_fsblock_t,
                                         xfs_extlen_t);
-int            _xfs_trans_commit(xfs_trans_t *,
-                                 uint flags,
-                                 int *);
-#define xfs_trans_commit(tp, flags)    _xfs_trans_commit(tp, flags, NULL)
+int            xfs_trans_commit(xfs_trans_t *, uint flags);
 void           xfs_trans_cancel(xfs_trans_t *, int);
 int            xfs_trans_ail_init(struct xfs_mount *);
 void           xfs_trans_ail_destroy(struct xfs_mount *);