[f2fs-dev] [PATCH v2] f2fs: use adjusted write range after f2fs_write_checks()

Seongjae Jeong <[email protected]>
Newsgroups net.sourceforge.lists.linux-f2fs-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
generic_write_checks() in f2fs_write_checks() can adjust iocb->ki_pos
for append writes and truncate the iterator to limit the number of bytes
to write.

In f2fs_file_write_iter(), the pinned-file overwrite check currently
uses the position and count saved before f2fs_write_checks(), so it
can check a range different from the actual write range.

The forced buffered I/O cleanup also uses orig_pos saved before
f2fs_write_checks(). For O_APPEND writes, this can make the cleanup
flush and invalidate the wrong page cache range.

Move the pinned-file overwrite check after f2fs_write_checks() and use
the adjusted iocb->ki_pos and iov_iter_count(from). Also save the
adjusted write position and use it for the forced buffered I/O cleanup.

Fixes: 3fdd89b452c2 ("f2fs: prevent writing without fallocate() for pinned files")
Fixes: 92318f20d703 ("f2fs: preserve direct write semantics when buffering is forced")
Signed-off-by: Seongjae Jeong <[email protected]>
---
V1 -> V2: Move the pinned-file overwrite check after f2fs_write_checks() and
use the adjusted write position and iterator count

 fs/f2fs/file.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index d82be8c1502a..d440231b8cb9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -5641,9 +5641,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	bool dio;
 	bool may_need_sync = true;
 	int preallocated;
-	const loff_t pos = iocb->ki_pos;
-	const ssize_t count = iov_iter_count(from);
 	ssize_t ret;
+	loff_t bufio_start_pos;
 
 	if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) {
 		ret = -EIO;
@@ -5664,15 +5663,17 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 		inode_lock(inode);
 	}
 
+	ret = f2fs_write_checks(iocb, from);
+	if (ret <= 0)
+		goto out_unlock;
+
 	if (f2fs_is_pinned_file(inode) &&
-	    !f2fs_overwrite_io(inode, pos, count)) {
+	    !f2fs_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) {
 		ret = -EIO;
 		goto out_unlock;
 	}
 
-	ret = f2fs_write_checks(iocb, from);
-	if (ret <= 0)
-		goto out_unlock;
+	bufio_start_pos = iocb->ki_pos;
 
 	/* Determine whether we will do a direct write or a buffered write. */
 	dio = f2fs_should_use_dio(inode, iocb, from);
@@ -5727,8 +5728,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	 */
 	if (ret > 0 && !dio && (iocb->ki_flags & IOCB_DIRECT))
 		f2fs_flush_buffered_write(iocb->ki_filp->f_mapping,
-					  orig_pos,
-					  orig_pos + ret - 1);
+					  bufio_start_pos,
+					  bufio_start_pos + ret - 1);
 
 	return ret;
 }

base-commit: dafb84f092a6387748b2df4c8f647d46873bc1a0
-- 
2.53.0


_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.