xfs: optimize fsync on directories
Directories are only updated transactionally, which means fsync only needs to flush the log the inode is currently dirty, but not bother with checking for dirty data, non-transactional updates, and most importanly doesn't have to flush disk caches except as part of a transaction commit. While the first two optimizations can't easily be measured, the latter actually makes a difference when doing lots of fsync that do not actually have to commit the inode, e.g. because an earlier fsync already pushed the log far enough. The new xfs_dir_fsync is identical to xfs_nfs_commit_metadata except for the prototype, but I'm not sure creating a common helper for the two is worth it given how simple the functions are. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
Родитель
670ce93fef
Коммит
1da2f2dbf2
|
@ -124,6 +124,35 @@ xfs_iozero(
|
|||
return (-status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fsync operations on directories are much simpler than on regular files,
|
||||
* as there is no file data to flush, and thus also no need for explicit
|
||||
* cache flush operations, and there are no non-transaction metadata updates
|
||||
* on directories either.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_dir_fsync(
|
||||
struct file *file,
|
||||
loff_t start,
|
||||
loff_t end,
|
||||
int datasync)
|
||||
{
|
||||
struct xfs_inode *ip = XFS_I(file->f_mapping->host);
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
xfs_lsn_t lsn = 0;
|
||||
|
||||
trace_xfs_dir_fsync(ip);
|
||||
|
||||
xfs_ilock(ip, XFS_ILOCK_SHARED);
|
||||
if (xfs_ipincount(ip))
|
||||
lsn = ip->i_itemp->ili_last_lsn;
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
|
||||
if (!lsn)
|
||||
return 0;
|
||||
return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_file_fsync(
|
||||
struct file *file,
|
||||
|
@ -1140,7 +1169,7 @@ const struct file_operations xfs_dir_file_operations = {
|
|||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = xfs_file_compat_ioctl,
|
||||
#endif
|
||||
.fsync = xfs_file_fsync,
|
||||
.fsync = xfs_dir_fsync,
|
||||
};
|
||||
|
||||
static const struct vm_operations_struct xfs_file_vm_ops = {
|
||||
|
|
|
@ -576,6 +576,7 @@ DEFINE_INODE_EVENT(xfs_vm_bmap);
|
|||
DEFINE_INODE_EVENT(xfs_file_ioctl);
|
||||
DEFINE_INODE_EVENT(xfs_file_compat_ioctl);
|
||||
DEFINE_INODE_EVENT(xfs_ioctl_setattr);
|
||||
DEFINE_INODE_EVENT(xfs_dir_fsync);
|
||||
DEFINE_INODE_EVENT(xfs_file_fsync);
|
||||
DEFINE_INODE_EVENT(xfs_destroy_inode);
|
||||
DEFINE_INODE_EVENT(xfs_write_inode);
|
||||
|
|
Загрузка…
Ссылка в новой задаче