diff options
author | Darrick J. Wong <djwong@kernel.org> | 2022-01-28 14:35:13 -0800 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2022-01-30 09:36:28 -0800 |
commit | 397aa0d3bf8c130bc58d043089c10bd348b6e0a4 (patch) | |
tree | 175aa8526f2795de21d07b1ae873f3f81051f1de | |
parent | 7ae9f5cb676afbf7121e417f9bde71a2a2819a5c (diff) |
xfs: ensure log flush at the end of a synchronous fallocate callxfs-fixes-5.17_2022-01-30
If the caller wanted us to persist the preallocation to disk before
returning to userspace, make sure we force the log to disk after making
all metadata updates.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r-- | fs/xfs/xfs_file.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 596533b713a8..69578ee8e89f 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -930,6 +930,7 @@ xfs_file_fallocate( uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; loff_t new_size = 0; bool do_file_insert = false; + bool flush_log; if (!S_ISREG(inode->i_mode)) return -EINVAL; @@ -1079,16 +1080,19 @@ xfs_file_fallocate( goto out_unlock; /* - * If we need to change the PREALLOC flag or flush the log, do so. - * We already updated the timestamps and cleared the suid flags, so we - * don't need to do that again. This must be committed before the size - * change so that we don't trim post-EOF preallocations. + * If we need to change the PREALLOC flag, do so. We already updated + * the timestamps and cleared the suid flags, so we don't need to do + * that again. This must be committed before the size change so that + * we don't trim post-EOF preallocations. If this is the last + * transaction we're going to make, make the update synchronous too. */ - if (xfs_file_sync_writes(file)) - flags |= XFS_PREALLOC_SYNC; + flush_log = xfs_file_sync_writes(file); if (flags) { flags |= XFS_PREALLOC_INVISIBLE; + if (flush_log && !(do_file_insert || new_size)) + flags |= XFS_PREALLOC_SYNC; + error = xfs_update_prealloc_flags(ip, flags); if (error) goto out_unlock; @@ -1112,8 +1116,22 @@ xfs_file_fallocate( * leave shifted extents past EOF and hence losing access to * the data that is contained within them. */ - if (do_file_insert) + if (do_file_insert) { error = xfs_insert_file_space(ip, offset, len); + if (error) + goto out_unlock; + } + + /* + * If the caller wants us to flush the log and either we've made + * changes since updating the PREALLOC flag or we didn't need to + * update the PREALLOC flag, then flush the log now. + */ + if (flush_log && (do_file_insert || new_size || flags == 0)) { + error = xfs_log_force_inode(ip); + if (error) + goto out_unlock; + } out_unlock: xfs_iunlock(ip, iolock); |