aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-09-19 10:55:51 -0400
committerAlex Elder <aelder@sgi.com>2011-10-11 22:15:08 -0400
commitb10370585349d364ff3c550afa7922e6e21f029d (patch)
tree23996ee7961fc5595d72c5e149a4250c444356f4 /fs/xfs
parent815cb21662b914e1e14c256a3d662b1352c8509e (diff)
xfs: unlock the inode before log force in xfs_fsync
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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_file.c15
-rw-r--r--fs/xfs/xfs_trans.c11
-rw-r--r--fs/xfs/xfs_trans.h5
3 files changed, 13 insertions, 18 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 558543c146b3..d8ef02eb178a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -137,6 +137,7 @@ xfs_file_fsync(
137 struct xfs_trans *tp; 137 struct xfs_trans *tp;
138 int error = 0; 138 int error = 0;
139 int log_flushed = 0; 139 int log_flushed = 0;
140 xfs_lsn_t lsn = 0;
140 141
141 trace_xfs_file_fsync(ip); 142 trace_xfs_file_fsync(ip);
142 143
@@ -214,9 +215,9 @@ xfs_file_fsync(
214 */ 215 */
215 xfs_trans_ijoin(tp, ip); 216 xfs_trans_ijoin(tp, ip);
216 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 217 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
217 xfs_trans_set_sync(tp); 218 error = xfs_trans_commit(tp, 0);
218 error = _xfs_trans_commit(tp, 0, &log_flushed);
219 219
220 lsn = ip->i_itemp->ili_last_lsn;
220 xfs_iunlock(ip, XFS_ILOCK_EXCL); 221 xfs_iunlock(ip, XFS_ILOCK_EXCL);
221 } else { 222 } else {
222 /* 223 /*
@@ -227,14 +228,14 @@ xfs_file_fsync(
227 * disk yet, the inode will be still be pinned. If it is, 228 * disk yet, the inode will be still be pinned. If it is,
228 * force the log. 229 * force the log.
229 */ 230 */
230 if (xfs_ipincount(ip)) { 231 if (xfs_ipincount(ip))
231 error = _xfs_log_force_lsn(mp, 232 lsn = ip->i_itemp->ili_last_lsn;
232 ip->i_itemp->ili_last_lsn,
233 XFS_LOG_SYNC, &log_flushed);
234 }
235 xfs_iunlock(ip, XFS_ILOCK_SHARED); 233 xfs_iunlock(ip, XFS_ILOCK_SHARED);
236 } 234 }
237 235
236 if (!error && lsn)
237 error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed);
238
238 /* 239 /*
239 * If we only have a single device, and the log force about was 240 * If we only have a single device, and the log force about was
240 * a no-op we might have to flush the data device cache here. 241 * a no-op we might have to flush the data device cache here.
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index efc147f0e9b6..b64c8c79736a 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1790,9 +1790,7 @@ xfs_trans_commit_cil(
1790} 1790}
1791 1791
1792/* 1792/*
1793 * xfs_trans_commit 1793 * Commit the given transaction to the log.
1794 *
1795 * Commit the given transaction to the log a/synchronously.
1796 * 1794 *
1797 * XFS disk error handling mechanism is not based on a typical 1795 * XFS disk error handling mechanism is not based on a typical
1798 * transaction abort mechanism. Logically after the filesystem 1796 * transaction abort mechanism. Logically after the filesystem
@@ -1804,10 +1802,9 @@ xfs_trans_commit_cil(
1804 * Do not reference the transaction structure after this call. 1802 * Do not reference the transaction structure after this call.
1805 */ 1803 */
1806int 1804int
1807_xfs_trans_commit( 1805xfs_trans_commit(
1808 struct xfs_trans *tp, 1806 struct xfs_trans *tp,
1809 uint flags, 1807 uint flags)
1810 int *log_flushed)
1811{ 1808{
1812 struct xfs_mount *mp = tp->t_mountp; 1809 struct xfs_mount *mp = tp->t_mountp;
1813 xfs_lsn_t commit_lsn = -1; 1810 xfs_lsn_t commit_lsn = -1;
@@ -1866,7 +1863,7 @@ _xfs_trans_commit(
1866 if (sync) { 1863 if (sync) {
1867 if (!error) { 1864 if (!error) {
1868 error = _xfs_log_force_lsn(mp, commit_lsn, 1865 error = _xfs_log_force_lsn(mp, commit_lsn,
1869 XFS_LOG_SYNC, log_flushed); 1866 XFS_LOG_SYNC, NULL);
1870 } 1867 }
1871 XFS_STATS_INC(xs_trans_sync); 1868 XFS_STATS_INC(xs_trans_sync);
1872 } else { 1869 } else {
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 06a9759b6352..54b0b1cc3e3f 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -487,10 +487,7 @@ void xfs_trans_log_efd_extent(xfs_trans_t *,
487 struct xfs_efd_log_item *, 487 struct xfs_efd_log_item *,
488 xfs_fsblock_t, 488 xfs_fsblock_t,
489 xfs_extlen_t); 489 xfs_extlen_t);
490int _xfs_trans_commit(xfs_trans_t *, 490int xfs_trans_commit(xfs_trans_t *, uint flags);
491 uint flags,
492 int *);
493#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL)
494void xfs_trans_cancel(xfs_trans_t *, int); 491void xfs_trans_cancel(xfs_trans_t *, int);
495int xfs_trans_ail_init(struct xfs_mount *); 492int xfs_trans_ail_init(struct xfs_mount *);
496void xfs_trans_ail_destroy(struct xfs_mount *); 493void xfs_trans_ail_destroy(struct xfs_mount *);