diff options
author | Ingo Molnar <mingo@kernel.org> | 2025-03-08 00:54:06 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2025-03-08 00:54:06 +0100 |
commit | f23ecef20af6fbd489e0362d33cdf8d9429fa901 (patch) | |
tree | 713f06d8335b7c3388bbfbc46cb6d2a568951252 /fs/btrfs/file.c | |
parent | c929d08df8bee855528b9d15b853c892c54e1eee (diff) | |
parent | 85b2b9c16d053364e2004883140538e73b333cdb (diff) |
Merge branch 'locking/urgent' into locking/core, to pick up locking fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index ed3c0d6546c5..0b568c8d24cb 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; |