[PATCH RFC DRAFT v2 04/13] ubifs: move fscrypt to filesystem inode

Christian Brauner
2025-07-22T12:57:58Z

Move fscrypt data pointer into the filesystem's private inode and record
the offset from the embedded struct inode.

This will allow us to drop the fscrypt data pointer from struct inode
itself and move it into the filesystem's inode.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
fs/ubifs/dir.c | 52 ++++++++++++++++++++++++++++------------------------
fs/ubifs/file.c | 8 ++++++++
fs/ubifs/super.c | 8 ++++++++
fs/ubifs/ubifs.h | 3 +++
4 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 3c3d3ad4fa6c..7d3c70c057c2 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -104,14 +104,6 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
simple_inode_init_ts(inode);
inode->i_mapping->nrpages = 0;

- if (!is_xattr) {
- err = fscrypt_prepare_new_inode(dir, inode, &encrypted);
- if (err) {
- ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err);
- goto out_iput;
- }
- }
-
switch (mode & S_IFMT) {
case S_IFREG:
inode->i_mapping->a_ops = &ubifs_file_address_operations;
@@ -136,6 +128,14 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
BUG();
}

+ if (!is_xattr) {
+ err = fscrypt_prepare_new_inode(dir, inode, &encrypted);
+ if (err) {
+ ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err);
+ goto out_iput;
+ }
+ }
+
ui->flags = inherit_flags(dir, mode);
ubifs_set_inode_flags(inode);
if (S_ISREG(mode))
@@ -1740,22 +1740,26 @@ static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
}

const struct inode_operations ubifs_dir_inode_operations = {
- .lookup = ubifs_lookup,
- .create = ubifs_create,
- .link = ubifs_link,
- .symlink = ubifs_symlink,
- .unlink = ubifs_unlink,
- .mkdir = ubifs_mkdir,
- .rmdir = ubifs_rmdir,
- .mknod = ubifs_mknod,
- .rename = ubifs_rename,
- .setattr = ubifs_setattr,
- .getattr = ubifs_getattr,
- .listxattr = ubifs_listxattr,
- .update_time = ubifs_update_time,
- .tmpfile = ubifs_tmpfile,
- .fileattr_get = ubifs_fileattr_get,
- .fileattr_set = ubifs_fileattr_set,
+#ifdef CONFIG_FS_ENCRYPTION
+ .i_fscrypt = offsetof(struct ubifs_inode, i_fscrypt_info) -
+ offsetof(struct ubifs_inode, vfs_inode),
+#endif
+ .lookup = ubifs_lookup,
+ .create = ubifs_create,
+ .link = ubifs_link,
+ .symlink = ubifs_symlink,
+ .unlink = ubifs_unlink,
+ .mkdir = ubifs_mkdir,
+ .rmdir = ubifs_rmdir,
+ .mknod = ubifs_mknod,
+ .rename = ubifs_rename,
+ .setattr = ubifs_setattr,
+ .getattr = ubifs_getattr,
+ .listxattr = ubifs_listxattr,
+ .update_time = ubifs_update_time,
+ .tmpfile = ubifs_tmpfile,
+ .fileattr_get = ubifs_fileattr_get,
+ .fileattr_set = ubifs_fileattr_set,
};

const struct file_operations ubifs_dir_operations = {
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index bf311c38d9a8..93ab562f7107 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1632,6 +1632,10 @@ const struct address_space_operations ubifs_file_address_operations = {
};

const struct inode_operations ubifs_file_inode_operations = {
+#ifdef CONFIG_FS_ENCRYPTION
+ .i_fscrypt = offsetof(struct ubifs_inode, i_fscrypt_info) -
+ offsetof(struct ubifs_inode, vfs_inode),
+#endif
.setattr = ubifs_setattr,
.getattr = ubifs_getattr,
.listxattr = ubifs_listxattr,
@@ -1641,6 +1645,10 @@ const struct inode_operations ubifs_file_inode_operations = {
};

const struct inode_operations ubifs_symlink_inode_operations = {
+#ifdef CONFIG_FS_ENCRYPTION
+ .i_fscrypt = offsetof(struct ubifs_inode, i_fscrypt_info) -
+ offsetof(struct ubifs_inode, vfs_inode),
+#endif
.get_link = ubifs_get_link,
.setattr = ubifs_setattr,
.getattr = ubifs_symlink_getattr,
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index f3e3b2068608..f18b38ee5c0c 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -100,6 +100,13 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
return err;
}

+static const struct inode_operations ubifs_encrypted_nop_inode_operations = {
+#ifdef CONFIG_FS_ENCRYPTION
+ .i_fscrypt = offsetof(struct ubifs_inode, i_fscrypt_info) -
+ offsetof(struct ubifs_inode, vfs_inode),
+#endif
+};
+
struct inode *ubifs_iget(struct super_block *sb, unsigned long inum)
{
int err;
@@ -118,6 +125,7 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum)
return inode;
ui = ubifs_inode(inode);

+ inode->i_op = &ubifs_encrypted_nop_inode_operations;
ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS);
if (!ino) {
err = -ENOMEM;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 256dbaeeb0de..0442782a54ab 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -416,6 +416,9 @@ struct ubifs_inode {
pgoff_t read_in_a_row;
int data_len;
void *data;
+#ifdef CONFIG_FS_ENCRYPTION
+ struct fscrypt_inode_info *i_fscrypt_info;
+#endif
};

/**

--
2.47.2