Commit 01d90c07 authored by Eric Biggers's avatar Eric Biggers
Browse files

fsverity: optimize fsverity_prepare_setattr() on non-verity files



Make fsverity_prepare_setattr() an inline function that does the
IS_VERITY() check, then (if needed) calls __fsverity_prepare_setattr()
to do the real work.  This reduces the overhead on non-verity files.

Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Acked-by: default avatarDave Chinner <dchinner@redhat.com>
Link: https://lore.kernel.org/r/20221214224304.145712-3-ebiggers@kernel.org
parent a6528a96
Loading
Loading
Loading
Loading
+3 −13
Original line number Diff line number Diff line
@@ -337,26 +337,16 @@ int __fsverity_file_open(struct inode *inode, struct file *filp)
}
EXPORT_SYMBOL_GPL(__fsverity_file_open);

/**
 * fsverity_prepare_setattr() - prepare to change a verity inode's attributes
 * @dentry: dentry through which the inode is being changed
 * @attr: attributes to change
 *
 * Verity files are immutable, so deny truncates.  This isn't covered by the
 * open-time check because sys_truncate() takes a path, not a file descriptor.
 *
 * Return: 0 on success, -errno on failure
 */
int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
int __fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
{
	if (IS_VERITY(d_inode(dentry)) && (attr->ia_valid & ATTR_SIZE)) {
	if (attr->ia_valid & ATTR_SIZE) {
		pr_debug("Denying truncate of verity file (ino %lu)\n",
			 d_inode(dentry)->i_ino);
		return -EPERM;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(fsverity_prepare_setattr);
EXPORT_SYMBOL_GPL(__fsverity_prepare_setattr);

/**
 * fsverity_cleanup_inode() - free the inode's verity info, if present
+22 −4
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ int fsverity_get_digest(struct inode *inode,
/* open.c */

int __fsverity_file_open(struct inode *inode, struct file *filp);
int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr);
int __fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr);
void fsverity_cleanup_inode(struct inode *inode);

/* read_metadata.c */
@@ -198,10 +198,10 @@ static inline int __fsverity_file_open(struct inode *inode, struct file *filp)
	return -EOPNOTSUPP;
}

static inline int fsverity_prepare_setattr(struct dentry *dentry,
static inline int __fsverity_prepare_setattr(struct dentry *dentry,
					     struct iattr *attr)
{
	return IS_VERITY(d_inode(dentry)) ? -EOPNOTSUPP : 0;
	return -EOPNOTSUPP;
}

static inline void fsverity_cleanup_inode(struct inode *inode)
@@ -274,4 +274,22 @@ static inline int fsverity_file_open(struct inode *inode, struct file *filp)
	return 0;
}

/**
 * fsverity_prepare_setattr() - prepare to change a verity inode's attributes
 * @dentry: dentry through which the inode is being changed
 * @attr: attributes to change
 *
 * Verity files are immutable, so deny truncates.  This isn't covered by the
 * open-time check because sys_truncate() takes a path, not a file descriptor.
 *
 * Return: 0 on success, -errno on failure
 */
static inline int fsverity_prepare_setattr(struct dentry *dentry,
					   struct iattr *attr)
{
	if (IS_VERITY(d_inode(dentry)))
		return __fsverity_prepare_setattr(dentry, attr);
	return 0;
}

#endif	/* _LINUX_FSVERITY_H */