Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

f2fs: support idmapped mounts

This patch enables idmapped mounts for f2fs, since all dedicated helpers
for this functionality existsm, so, in this patch we just pass down the
user_namespace argument from the VFS methods to the relevant helpers.

Simple idmap example on f2fs image:

1. truncate -s 128M f2fs.img
2. mkfs.f2fs f2fs.img
3. mount f2fs.img /mnt/f2fs/
4. touch /mnt/f2fs/file

5. ls -ln /mnt/f2fs/
total 0
-rw-r--r-- 1 0 0 0 2月 4 13:17 file

6. ./mount-idmapped --map-mount b:0:1001:1 /mnt/f2fs/ /mnt/scratch_f2fs/

7. ls -ln /mnt/scratch_f2fs/
total 0
-rw-r--r-- 1 1001 1001 0 2月 4 13:17 file

Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Chao Yu and committed by
Jaegeuk Kim
984fc4e7 47c8ebcc

+50 -37
+12 -9
fs/f2fs/acl.c
··· 204 204 return __f2fs_get_acl(inode, type, NULL); 205 205 } 206 206 207 - static int f2fs_acl_update_mode(struct inode *inode, umode_t *mode_p, 208 - struct posix_acl **acl) 207 + static int f2fs_acl_update_mode(struct user_namespace *mnt_userns, 208 + struct inode *inode, umode_t *mode_p, 209 + struct posix_acl **acl) 209 210 { 210 211 umode_t mode = inode->i_mode; 211 212 int error; ··· 219 218 return error; 220 219 if (error == 0) 221 220 *acl = NULL; 222 - if (!in_group_p(i_gid_into_mnt(&init_user_ns, inode)) && 223 - !capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_FSETID)) 221 + if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) && 222 + !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) 224 223 mode &= ~S_ISGID; 225 224 *mode_p = mode; 226 225 return 0; 227 226 } 228 227 229 - static int __f2fs_set_acl(struct inode *inode, int type, 228 + static int __f2fs_set_acl(struct user_namespace *mnt_userns, 229 + struct inode *inode, int type, 230 230 struct posix_acl *acl, struct page *ipage) 231 231 { 232 232 int name_index; ··· 240 238 case ACL_TYPE_ACCESS: 241 239 name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; 242 240 if (acl && !ipage) { 243 - error = f2fs_acl_update_mode(inode, &mode, &acl); 241 + error = f2fs_acl_update_mode(mnt_userns, inode, 242 + &mode, &acl); 244 243 if (error) 245 244 return error; 246 245 set_acl_inode(inode, mode); ··· 282 279 if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) 283 280 return -EIO; 284 281 285 - return __f2fs_set_acl(inode, type, acl, NULL); 282 + return __f2fs_set_acl(mnt_userns, inode, type, acl, NULL); 286 283 } 287 284 288 285 /* ··· 422 419 f2fs_mark_inode_dirty_sync(inode, true); 423 420 424 421 if (default_acl) { 425 - error = __f2fs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl, 422 + error = __f2fs_set_acl(NULL, inode, ACL_TYPE_DEFAULT, default_acl, 426 423 ipage); 427 424 posix_acl_release(default_acl); 428 425 } else { ··· 430 427 } 431 428 if (acl) { 432 429 if (!error) 433 - error = __f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, 430 + error = __f2fs_set_acl(NULL, inode, ACL_TYPE_ACCESS, acl, 434 431 ipage); 435 432 posix_acl_release(acl); 436 433 } else {
+14 -9
fs/f2fs/file.c
··· 844 844 STATX_ATTR_NODUMP | 845 845 STATX_ATTR_VERITY); 846 846 847 - generic_fillattr(&init_user_ns, inode, stat); 847 + generic_fillattr(mnt_userns, inode, stat); 848 848 849 849 /* we need to show initial sectors used for inline_data/dentries */ 850 850 if ((S_ISREG(inode->i_mode) && f2fs_has_inline_data(inode)) || ··· 904 904 !f2fs_is_compress_backend_ready(inode)) 905 905 return -EOPNOTSUPP; 906 906 907 - err = setattr_prepare(&init_user_ns, dentry, attr); 907 + err = setattr_prepare(mnt_userns, dentry, attr); 908 908 if (err) 909 909 return err; 910 910 ··· 980 980 spin_unlock(&F2FS_I(inode)->i_size_lock); 981 981 } 982 982 983 - __setattr_copy(&init_user_ns, inode, attr); 983 + __setattr_copy(mnt_userns, inode, attr); 984 984 985 985 if (attr->ia_valid & ATTR_MODE) { 986 - err = posix_acl_chmod(&init_user_ns, inode, f2fs_get_inode_mode(inode)); 986 + err = posix_acl_chmod(mnt_userns, inode, f2fs_get_inode_mode(inode)); 987 987 988 988 if (is_inode_flag_set(inode, FI_ACL_MODE)) { 989 989 if (!err) ··· 1989 1989 static int f2fs_ioc_start_atomic_write(struct file *filp) 1990 1990 { 1991 1991 struct inode *inode = file_inode(filp); 1992 + struct user_namespace *mnt_userns = file_mnt_user_ns(filp); 1992 1993 struct f2fs_inode_info *fi = F2FS_I(inode); 1993 1994 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 1994 1995 int ret; 1995 1996 1996 - if (!inode_owner_or_capable(&init_user_ns, inode)) 1997 + if (!inode_owner_or_capable(mnt_userns, inode)) 1997 1998 return -EACCES; 1998 1999 1999 2000 if (!S_ISREG(inode->i_mode)) ··· 2059 2058 static int f2fs_ioc_commit_atomic_write(struct file *filp) 2060 2059 { 2061 2060 struct inode *inode = file_inode(filp); 2061 + struct user_namespace *mnt_userns = file_mnt_user_ns(filp); 2062 2062 int ret; 2063 2063 2064 - if (!inode_owner_or_capable(&init_user_ns, inode)) 2064 + if (!inode_owner_or_capable(mnt_userns, inode)) 2065 2065 return -EACCES; 2066 2066 2067 2067 ret = mnt_want_write_file(filp); ··· 2102 2100 static int f2fs_ioc_start_volatile_write(struct file *filp) 2103 2101 { 2104 2102 struct inode *inode = file_inode(filp); 2103 + struct user_namespace *mnt_userns = file_mnt_user_ns(filp); 2105 2104 int ret; 2106 2105 2107 - if (!inode_owner_or_capable(&init_user_ns, inode)) 2106 + if (!inode_owner_or_capable(mnt_userns, inode)) 2108 2107 return -EACCES; 2109 2108 2110 2109 if (!S_ISREG(inode->i_mode)) ··· 2138 2135 static int f2fs_ioc_release_volatile_write(struct file *filp) 2139 2136 { 2140 2137 struct inode *inode = file_inode(filp); 2138 + struct user_namespace *mnt_userns = file_mnt_user_ns(filp); 2141 2139 int ret; 2142 2140 2143 - if (!inode_owner_or_capable(&init_user_ns, inode)) 2141 + if (!inode_owner_or_capable(mnt_userns, inode)) 2144 2142 return -EACCES; 2145 2143 2146 2144 ret = mnt_want_write_file(filp); ··· 2168 2164 static int f2fs_ioc_abort_volatile_write(struct file *filp) 2169 2165 { 2170 2166 struct inode *inode = file_inode(filp); 2167 + struct user_namespace *mnt_userns = file_mnt_user_ns(filp); 2171 2168 int ret; 2172 2169 2173 - if (!inode_owner_or_capable(&init_user_ns, inode)) 2170 + if (!inode_owner_or_capable(mnt_userns, inode)) 2174 2171 return -EACCES; 2175 2172 2176 2173 ret = mnt_want_write_file(filp);
+23 -18
fs/f2fs/namei.c
··· 22 22 #include "acl.h" 23 23 #include <trace/events/f2fs.h> 24 24 25 - static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) 25 + static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, 26 + struct inode *dir, umode_t mode) 26 27 { 27 28 struct f2fs_sb_info *sbi = F2FS_I_SB(dir); 28 29 nid_t ino; ··· 47 46 48 47 nid_free = true; 49 48 50 - inode_init_owner(&init_user_ns, inode, dir, mode); 49 + inode_init_owner(mnt_userns, inode, dir, mode); 51 50 52 51 inode->i_ino = ino; 53 52 inode->i_blocks = 0; ··· 68 67 (F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL)) 69 68 F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid; 70 69 else 71 - F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns, 70 + F2FS_I(inode)->i_projid = make_kprojid(mnt_userns, 72 71 F2FS_DEF_PROJID); 73 72 74 73 err = fscrypt_prepare_new_inode(dir, inode, &encrypt); ··· 350 349 if (err) 351 350 return err; 352 351 353 - inode = f2fs_new_inode(dir, mode); 352 + inode = f2fs_new_inode(mnt_userns, dir, mode); 354 353 if (IS_ERR(inode)) 355 354 return PTR_ERR(inode); 356 355 ··· 680 679 if (err) 681 680 return err; 682 681 683 - inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); 682 + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); 684 683 if (IS_ERR(inode)) 685 684 return PTR_ERR(inode); 686 685 ··· 751 750 if (err) 752 751 return err; 753 752 754 - inode = f2fs_new_inode(dir, S_IFDIR | mode); 753 + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); 755 754 if (IS_ERR(inode)) 756 755 return PTR_ERR(inode); 757 756 ··· 808 807 if (err) 809 808 return err; 810 809 811 - inode = f2fs_new_inode(dir, mode); 810 + inode = f2fs_new_inode(mnt_userns, dir, mode); 812 811 if (IS_ERR(inode)) 813 812 return PTR_ERR(inode); 814 813 ··· 835 834 return err; 836 835 } 837 836 838 - static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, 839 - umode_t mode, struct inode **whiteout) 837 + static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, 838 + struct dentry *dentry, umode_t mode, 839 + struct inode **whiteout) 840 840 { 841 841 struct f2fs_sb_info *sbi = F2FS_I_SB(dir); 842 842 struct inode *inode; ··· 847 845 if (err) 848 846 return err; 849 847 850 - inode = f2fs_new_inode(dir, mode); 848 + inode = f2fs_new_inode(mnt_userns, dir, mode); 851 849 if (IS_ERR(inode)) 852 850 return PTR_ERR(inode); 853 851 ··· 911 909 if (!f2fs_is_checkpoint_ready(sbi)) 912 910 return -ENOSPC; 913 911 914 - return __f2fs_tmpfile(dir, dentry, mode, NULL); 912 + return __f2fs_tmpfile(mnt_userns, dir, dentry, mode, NULL); 915 913 } 916 914 917 - static int f2fs_create_whiteout(struct inode *dir, struct inode **whiteout) 915 + static int f2fs_create_whiteout(struct user_namespace *mnt_userns, 916 + struct inode *dir, struct inode **whiteout) 918 917 { 919 918 if (unlikely(f2fs_cp_error(F2FS_I_SB(dir)))) 920 919 return -EIO; 921 920 922 - return __f2fs_tmpfile(dir, NULL, S_IFCHR | WHITEOUT_MODE, whiteout); 921 + return __f2fs_tmpfile(mnt_userns, dir, NULL, 922 + S_IFCHR | WHITEOUT_MODE, whiteout); 923 923 } 924 924 925 - static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, 926 - struct inode *new_dir, struct dentry *new_dentry, 927 - unsigned int flags) 925 + static int f2fs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, 926 + struct dentry *old_dentry, struct inode *new_dir, 927 + struct dentry *new_dentry, unsigned int flags) 928 928 { 929 929 struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir); 930 930 struct inode *old_inode = d_inode(old_dentry); ··· 964 960 } 965 961 966 962 if (flags & RENAME_WHITEOUT) { 967 - err = f2fs_create_whiteout(old_dir, &whiteout); 963 + err = f2fs_create_whiteout(mnt_userns, old_dir, &whiteout); 968 964 if (err) 969 965 return err; 970 966 } ··· 1304 1300 * VFS has already handled the new dentry existence case, 1305 1301 * here, we just deal with "RENAME_NOREPLACE" as regular rename. 1306 1302 */ 1307 - return f2fs_rename(old_dir, old_dentry, new_dir, new_dentry, flags); 1303 + return f2fs_rename(mnt_userns, old_dir, old_dentry, 1304 + new_dir, new_dentry, flags); 1308 1305 } 1309 1306 1310 1307 static const char *f2fs_encrypted_get_link(struct dentry *dentry,
+1 -1
fs/f2fs/super.c
··· 4539 4539 .name = "f2fs", 4540 4540 .mount = f2fs_mount, 4541 4541 .kill_sb = kill_f2fs_super, 4542 - .fs_flags = FS_REQUIRES_DEV, 4542 + .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP, 4543 4543 }; 4544 4544 MODULE_ALIAS_FS("f2fs"); 4545 4545