Merge tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt
[sfrench/cifs-2.6.git] / fs / f2fs / file.c
index 6a7349f9ac15ec7fcbc72966d6a4d7f95ee4d557..39fffc19e00c910a2b6218d14fd213aa75c0db47 100644 (file)
@@ -493,6 +493,10 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
 {
        int err = fscrypt_file_open(inode, filp);
 
+       if (err)
+               return err;
+
+       err = fsverity_file_open(inode, filp);
        if (err)
                return err;
 
@@ -778,6 +782,10 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
        if (err)
                return err;
 
+       err = fsverity_prepare_setattr(dentry, attr);
+       if (err)
+               return err;
+
        if (is_quota_modification(inode, attr)) {
                err = dquot_initialize(inode);
                if (err)
@@ -1705,7 +1713,8 @@ static const struct {
                FS_PROJINHERIT_FL |     \
                FS_ENCRYPT_FL |         \
                FS_INLINE_DATA_FL |     \
-               FS_NOCOW_FL)
+               FS_NOCOW_FL |           \
+               FS_VERITY_FL)
 
 #define F2FS_SETTABLE_FS_FL (          \
                FS_SYNC_FL |            \
@@ -1750,6 +1759,8 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
 
        if (IS_ENCRYPTED(inode))
                fsflags |= FS_ENCRYPT_FL;
+       if (IS_VERITY(inode))
+               fsflags |= FS_VERITY_FL;
        if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
                fsflags |= FS_INLINE_DATA_FL;
        if (is_inode_flag_set(inode, FI_PIN_FILE))
@@ -3103,6 +3114,30 @@ static int f2fs_ioc_resize_fs(struct file *filp, unsigned long arg)
        return ret;
 }
 
+static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg)
+{
+       struct inode *inode = file_inode(filp);
+
+       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+
+       if (!f2fs_sb_has_verity(F2FS_I_SB(inode))) {
+               f2fs_warn(F2FS_I_SB(inode),
+                         "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem.\n",
+                         inode->i_ino);
+               return -EOPNOTSUPP;
+       }
+
+       return fsverity_ioctl_enable(filp, (const void __user *)arg);
+}
+
+static int f2fs_ioc_measure_verity(struct file *filp, unsigned long arg)
+{
+       if (!f2fs_sb_has_verity(F2FS_I_SB(file_inode(filp))))
+               return -EOPNOTSUPP;
+
+       return fsverity_ioctl_measure(filp, (void __user *)arg);
+}
+
 long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp)))))
@@ -3171,6 +3206,10 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                return f2fs_ioc_precache_extents(filp, arg);
        case F2FS_IOC_RESIZE_FS:
                return f2fs_ioc_resize_fs(filp, arg);
+       case FS_IOC_ENABLE_VERITY:
+               return f2fs_ioc_enable_verity(filp, arg);
+       case FS_IOC_MEASURE_VERITY:
+               return f2fs_ioc_measure_verity(filp, arg);
        default:
                return -ENOTTY;
        }
@@ -3290,6 +3329,8 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case F2FS_IOC_SET_PIN_FILE:
        case F2FS_IOC_PRECACHE_EXTENTS:
        case F2FS_IOC_RESIZE_FS:
+       case FS_IOC_ENABLE_VERITY:
+       case FS_IOC_MEASURE_VERITY:
                break;
        default:
                return -ENOIOCTLCMD;