hugetlbfs: support idmapped mounts
authorGiuseppe Scrivano <gscrivan@redhat.com>
Thu, 29 Feb 2024 15:24:05 +0000 (16:24 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 4 Mar 2024 12:54:54 +0000 (13:54 +0100)
pass down the idmapped mount information to the different helper
functions.

Differently, hugetlb_file_setup() will continue to not have any
mapping since it is only used from contexts where idmapped mounts are
not used.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Link: https://lore.kernel.org/r/20240229152405.105031-1-gscrivan@redhat.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/hugetlbfs/inode.c

index ea5b8e57d904e20b964fb5e627c4bae894370401..af82364c84d8d2860aae9fa8cfaf65b5d1f688b2 100644 (file)
@@ -922,7 +922,7 @@ static int hugetlbfs_setattr(struct mnt_idmap *idmap,
        unsigned int ia_valid = attr->ia_valid;
        struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode);
 
-       error = setattr_prepare(&nop_mnt_idmap, dentry, attr);
+       error = setattr_prepare(idmap, dentry, attr);
        if (error)
                return error;
 
@@ -939,7 +939,7 @@ static int hugetlbfs_setattr(struct mnt_idmap *idmap,
                hugetlb_vmtruncate(inode, newsize);
        }
 
-       setattr_copy(&nop_mnt_idmap, inode, attr);
+       setattr_copy(idmap, inode, attr);
        mark_inode_dirty(inode);
        return 0;
 }
@@ -974,6 +974,7 @@ static struct inode *hugetlbfs_get_root(struct super_block *sb,
 static struct lock_class_key hugetlbfs_i_mmap_rwsem_key;
 
 static struct inode *hugetlbfs_get_inode(struct super_block *sb,
+                                       struct mnt_idmap *idmap,
                                        struct inode *dir,
                                        umode_t mode, dev_t dev)
 {
@@ -995,7 +996,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,
                struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode);
 
                inode->i_ino = get_next_ino();
-               inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
+               inode_init_owner(idmap, inode, dir, mode);
                lockdep_set_class(&inode->i_mapping->i_mmap_rwsem,
                                &hugetlbfs_i_mmap_rwsem_key);
                inode->i_mapping->a_ops = &hugetlbfs_aops;
@@ -1039,7 +1040,7 @@ static int hugetlbfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
 {
        struct inode *inode;
 
-       inode = hugetlbfs_get_inode(dir->i_sb, dir, mode, dev);
+       inode = hugetlbfs_get_inode(dir->i_sb, idmap, dir, mode, dev);
        if (!inode)
                return -ENOSPC;
        inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
@@ -1051,7 +1052,7 @@ static int hugetlbfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
 static int hugetlbfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
                           struct dentry *dentry, umode_t mode)
 {
-       int retval = hugetlbfs_mknod(&nop_mnt_idmap, dir, dentry,
+       int retval = hugetlbfs_mknod(idmap, dir, dentry,
                                     mode | S_IFDIR, 0);
        if (!retval)
                inc_nlink(dir);
@@ -1062,7 +1063,7 @@ static int hugetlbfs_create(struct mnt_idmap *idmap,
                            struct inode *dir, struct dentry *dentry,
                            umode_t mode, bool excl)
 {
-       return hugetlbfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFREG, 0);
+       return hugetlbfs_mknod(idmap, dir, dentry, mode | S_IFREG, 0);
 }
 
 static int hugetlbfs_tmpfile(struct mnt_idmap *idmap,
@@ -1071,7 +1072,7 @@ static int hugetlbfs_tmpfile(struct mnt_idmap *idmap,
 {
        struct inode *inode;
 
-       inode = hugetlbfs_get_inode(dir->i_sb, dir, mode | S_IFREG, 0);
+       inode = hugetlbfs_get_inode(dir->i_sb, idmap, dir, mode | S_IFREG, 0);
        if (!inode)
                return -ENOSPC;
        inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
@@ -1083,10 +1084,11 @@ static int hugetlbfs_symlink(struct mnt_idmap *idmap,
                             struct inode *dir, struct dentry *dentry,
                             const char *symname)
 {
+       const umode_t mode = S_IFLNK|S_IRWXUGO;
        struct inode *inode;
        int error = -ENOSPC;
 
-       inode = hugetlbfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0);
+       inode = hugetlbfs_get_inode(dir->i_sb, idmap, dir, mode, 0);
        if (inode) {
                int l = strlen(symname)+1;
                error = page_symlink(inode, symname, l);
@@ -1553,6 +1555,7 @@ static struct file_system_type hugetlbfs_fs_type = {
        .init_fs_context        = hugetlbfs_init_fs_context,
        .parameters             = hugetlb_fs_parameters,
        .kill_sb                = kill_litter_super,
+       .fs_flags               = FS_ALLOW_IDMAP,
 };
 
 static struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE];
@@ -1606,7 +1609,9 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
        }
 
        file = ERR_PTR(-ENOSPC);
-       inode = hugetlbfs_get_inode(mnt->mnt_sb, NULL, S_IFREG | S_IRWXUGO, 0);
+       /* hugetlbfs_vfsmount[] mounts do not use idmapped mounts.  */
+       inode = hugetlbfs_get_inode(mnt->mnt_sb, &nop_mnt_idmap, NULL,
+                                   S_IFREG | S_IRWXUGO, 0);
        if (!inode)
                goto out;
        if (creat_flags == HUGETLB_SHMFS_INODE)