[PATCH 07/15] remap_range: move file_start_write() to after permission hook

Amir Goldstein
2023-11-14T15:33:15Z

In vfs code, file_start_write() is usually called after the permission
hook in rw_verify_area(). vfs_dedupe_file_range_one() is an exception
to this rule.

In vfs_dedupe_file_range_one(), move file_start_write() to after the
the rw_verify_area() checks to make them "start-write-safe".

This is needed for fanotify "pre content" events.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/remap_range.c | 32 +++++++++++++-------------------
1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/fs/remap_range.c b/fs/remap_range.c
index 42f79cb2b1b1..de4b09d0ba1d 100644
--- a/fs/remap_range.c
+++ b/fs/remap_range.c
@@ -445,46 +445,40 @@ loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
WARN_ON_ONCE(remap_flags & ~(REMAP_FILE_DEDUP |
REMAP_FILE_CAN_SHORTEN));

- ret = mnt_want_write_file(dst_file);
- if (ret)
- return ret;
-
/*
* This is redundant if called from vfs_dedupe_file_range(), but other
* callers need it and it's not performance sesitive...
*/
ret = remap_verify_area(src_file, src_pos, len, false);
if (ret)
- goto out_drop_write;
+ return ret;

ret = remap_verify_area(dst_file, dst_pos, len, true);
if (ret)
- goto out_drop_write;
+ return ret;

- ret = -EPERM;
if (!allow_file_dedupe(dst_file))
- goto out_drop_write;
+ return -EPERM;

- ret = -EXDEV;
if (file_inode(src_file)->i_sb != file_inode(dst_file)->i_sb)
- goto out_drop_write;
+ return -EXDEV;

- ret = -EISDIR;
if (S_ISDIR(file_inode(dst_file)->i_mode))
- goto out_drop_write;
+ return -EISDIR;

- ret = -EINVAL;
if (!dst_file->f_op->remap_file_range)
- goto out_drop_write;
+ return -EINVAL;

- if (len == 0) {
- ret = 0;
- goto out_drop_write;
- }
+ if (len == 0)
+ return 0;
+
+ ret = mnt_want_write_file(dst_file);
+ if (ret)
+ return ret;

ret = dst_file->f_op->remap_file_range(src_file, src_pos, dst_file,
dst_pos, len, remap_flags | REMAP_FILE_DEDUP);
-out_drop_write:
+
mnt_drop_write_file(dst_file);

return ret;
--
2.34.1