summaryrefslogtreecommitdiffstats
path: root/fs/libfs.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2023-09-13 18:28:15 +0200
committerChristian Brauner <brauner@kernel.org>2023-09-20 14:22:01 +0200
commit8287474aa5ffb41df52552c4ae4748e791d2faf2 (patch)
tree34a5b4df660fac2032abb851c71c6b3eefac85ad /fs/libfs.c
parent2251588143f65636cf3f3f12beb009084fa2d5d7 (diff)
downloadlinux-8287474aa5ffb41df52552c4ae4748e791d2faf2.tar.gz
linux-8287474aa5ffb41df52552c4ae4748e791d2faf2.tar.bz2
linux-8287474aa5ffb41df52552c4ae4748e791d2faf2.zip
direct_write_fallback(): on error revert the ->ki_pos update from buffered write
If we fail filemap_write_and_wait_range() on the range the buffered write went into, we only report the "number of bytes which we direct-written", to quote the comment in there. Which is fine, but buffered write has already advanced iocb->ki_pos, so we need to roll that back. Otherwise we end up with e.g. write(2) advancing position by more than the amount it reports having written. Fixes: 182c25e9c157 "filemap: update ki_pos in generic_perform_write" Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Message-Id: <20230827214518.GU3390869@ZenIV> Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/libfs.c')
-rw-r--r--fs/libfs.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/libfs.c b/fs/libfs.c
index a4eb12757886..37f2d34ee090 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1903,6 +1903,7 @@ ssize_t direct_write_fallback(struct kiocb *iocb, struct iov_iter *iter,
* We don't know how much we wrote, so just return the number of
* bytes which were direct-written
*/
+ iocb->ki_pos -= buffered_written;
if (direct_written)
return direct_written;
return err;