diff options
author | Christoph Hellwig <hch@lst.de> | 2021-01-22 16:48:25 -0800 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-01-22 16:54:52 -0800 |
commit | ae29e4220fd3047b5442e7e8db8027d7745093f5 (patch) | |
tree | 188a3f6a0936b2377baf3ebe757296a08d103945 | |
parent | f22c7f87777361f94aa17f746fbadfa499248dc8 (diff) |
xfs: reduce ilock acquisitions in xfs_file_fsync
If the inode is not pinned by the time fsync is called we don't need the
ilock to protect against concurrent clearing of ili_fsync_fields as the
inode won't need a log flush or clearing of these fields. Not taking
the iolock allows for full concurrency of fsync and thus O_DSYNC
completions with io_uring/aio write submissions.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r-- | fs/xfs/xfs_file.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 9441c257d86c..48f6f89a38a9 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -200,7 +200,14 @@ xfs_file_fsync( else if (mp->m_logdev_targp != mp->m_ddev_targp) xfs_blkdev_issue_flush(mp->m_ddev_targp); - error = xfs_fsync_flush_log(ip, datasync, &log_flushed); + /* + * Any inode that has dirty modifications in the log is pinned. The + * racy check here for a pinned inode while not catch modifications + * that happen concurrently to the fsync call, but fsync semantics + * only require to sync previously completed I/O. + */ + if (xfs_ipincount(ip)) + error = xfs_fsync_flush_log(ip, datasync, &log_flushed); /* * If we only have a single device, and the log force about was |