[f2fs-dev] [PATCH 3/6] fs, fsverity: handle fsverity in generic_file_open

Christoph Hellwig
2026-01-19T06:23:31Z

Call into fsverity_file_open from generic_file_open instead of requiring
the file system to handle it explicitly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/btrfs/file.c | 6 ------
fs/ext4/file.c | 4 ----
fs/f2fs/file.c | 4 ----
fs/open.c | 8 +++++++-
fs/verity/open.c | 10 ++++++++--
include/linux/fsverity.h | 32 +-------------------------------
6 files changed, 16 insertions(+), 48 deletions(-)

diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 1abc7ed2990e..4b3a31b2b52e 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -3808,16 +3808,10 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)

static int btrfs_file_open(struct inode *inode, struct file *filp)
{
- int ret;
-
if (unlikely(btrfs_is_shutdown(inode_to_fs_info(inode))))
return -EIO;

filp->f_mode |= FMODE_NOWAIT | FMODE_CAN_ODIRECT;
-
- ret = fsverity_file_open(inode, filp);
- if (ret)
- return ret;
return generic_file_open(inode, filp);
}

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 7a8b30932189..a7dc8c10273e 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -906,10 +906,6 @@ static int ext4_file_open(struct inode *inode, struct file *filp)
if (ret)
return ret;

- ret = fsverity_file_open(inode, filp);
- if (ret)
- return ret;
-
/*
* Set up the jbd2_inode if we are opening the inode for
* writing and the journal is present
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index da029fed4e5a..f1510ab657b6 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -624,10 +624,6 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
if (!f2fs_is_compress_backend_ready(inode))
return -EOPNOTSUPP;

- err = fsverity_file_open(inode, filp);
- if (err)
- return err;
-
filp->f_mode |= FMODE_NOWAIT;
filp->f_mode |= FMODE_CAN_ODIRECT;

diff --git a/fs/open.c b/fs/open.c
index f328622061c5..dea93bab8795 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -10,6 +10,7 @@
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/fsnotify.h>
+#include <linux/fsverity.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/namei.h>
@@ -1604,10 +1605,15 @@ SYSCALL_DEFINE0(vhangup)
* the caller didn't specify O_LARGEFILE. On 64bit systems we force
* on this flag in sys_open.
*/
-int generic_file_open(struct inode * inode, struct file * filp)
+int generic_file_open(struct inode *inode, struct file *filp)
{
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
return -EOVERFLOW;
+ if (IS_ENABLED(CONFIG_FS_VERITY) && IS_VERITY(inode)) {
+ if (filp->f_mode & FMODE_WRITE)
+ return -EPERM;
+ return fsverity_file_open(inode, filp);
+ }
return 0;
}

diff --git a/fs/verity/open.c b/fs/verity/open.c
index 090cb77326ee..8ed915be9c91 100644
--- a/fs/verity/open.c
+++ b/fs/verity/open.c
@@ -376,13 +376,19 @@ static int ensure_verity_info(struct inode *inode)
return err;
}

-int __fsverity_file_open(struct inode *inode, struct file *filp)
+/*
+ * When opening a verity file, deny the open if it is for writing. Otherwise,
+ * set up the inode's verity info if not already done.
+ *
+ * When combined with fscrypt, this must be called after fscrypt_file_open().
+ * Otherwise, we won't have the key set up to decrypt the verity metadata.
+ */
+int fsverity_file_open(struct inode *inode, struct file *filp)
{
if (filp->f_mode & FMODE_WRITE)
return -EPERM;
return ensure_verity_info(inode);
}
-EXPORT_SYMBOL_GPL(__fsverity_file_open);

void fsverity_cleanup_inode(struct inode *inode)
{
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index b7bf2401c574..4980ea55cdaa 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -130,6 +130,7 @@ struct fsverity_operations {
u64 pos, unsigned int size);
};

+int fsverity_file_open(struct inode *inode, struct file *filp);
void fsverity_cleanup_inode(struct inode *inode);

#ifdef CONFIG_FS_VERITY
@@ -178,10 +179,6 @@ int fsverity_get_digest(struct inode *inode,
u8 raw_digest[FS_VERITY_MAX_DIGEST_SIZE],
u8 *alg, enum hash_algo *halg);

-/* open.c */
-
-int __fsverity_file_open(struct inode *inode, struct file *filp);
-
/* read_metadata.c */

int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg);
@@ -225,13 +222,6 @@ static inline int fsverity_get_digest(struct inode *inode,
return 0;
}

-/* open.c */
-
-static inline int __fsverity_file_open(struct inode *inode, struct file *filp)
-{
- return -EOPNOTSUPP;
-}
-
/* read_metadata.c */

static inline int fsverity_ioctl_read_metadata(struct file *filp,
@@ -289,24 +279,4 @@ static inline bool fsverity_active(const struct inode *inode)
return fsverity_get_info(inode) != NULL;
}

-/**
- * fsverity_file_open() - prepare to open a verity file
- * @inode: the inode being opened
- * @filp: the struct file being set up
- *
- * When opening a verity file, deny the open if it is for writing. Otherwise,
- * set up the inode's verity info if not already done.
- *
- * When combined with fscrypt, this must be called after fscrypt_file_open().
- * Otherwise, we won't have the key set up to decrypt the verity metadata.
- *
- * Return: 0 on success, -errno on failure
- */
-static inline int fsverity_file_open(struct inode *inode, struct file *filp)
-{
- if (IS_VERITY(inode))
- return __fsverity_file_open(inode, filp);
- return 0;
-}
-
#endif /* _LINUX_FSVERITY_H */
--
2.47.3