summaryrefslogtreecommitdiff
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorThomas Hellström <thomas.hellstrom@linux.intel.com>2025-03-19 11:08:52 +0100
committerThomas Hellström <thomas.hellstrom@linux.intel.com>2025-03-19 11:08:52 +0100
commit52eb8cd788f1a56a0645c1f6650e5795e04aaed0 (patch)
tree1d61fd7dbe5e7540e972069349b95ac65cd36880 /fs/btrfs/file.c
parent28f79ac609de2797cccdd5fa6c4d5ec8bcef92b4 (diff)
parent5da39dce1fa3c81dc6552a16a9f748ba2980d630 (diff)
Merge drm/drm-next into drm-xe-next
Backmerging to bring in the xe shrinker from drm-next. Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index ed3c0d6546c5d..0b568c8d24cbc 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1090,7 +1090,7 @@ ssize_t btrfs_buffered_write(struct kiocb *iocb, struct iov_iter *i)
u64 lockend;
size_t num_written = 0;
ssize_t ret;
- loff_t old_isize = i_size_read(inode);
+ loff_t old_isize;
unsigned int ilock_flags = 0;
const bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
unsigned int bdp_flags = (nowait ? BDP_ASYNC : 0);
@@ -1103,6 +1103,13 @@ ssize_t btrfs_buffered_write(struct kiocb *iocb, struct iov_iter *i)
if (ret < 0)
return ret;
+ /*
+ * We can only trust the isize with inode lock held, or it can race with
+ * other buffered writes and cause incorrect call of
+ * pagecache_isize_extended() to overwrite existing data.
+ */
+ old_isize = i_size_read(inode);
+
ret = generic_write_checks(iocb, i);
if (ret <= 0)
goto out;