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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-6.11.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs mount API updates from Christian Brauner:

- Add a generic helper to parse uid and gid mount options.

Currently we open-code the same logic in various filesystems which is
error prone, especially since the verification of uid and gid mount
options is a sensitive operation in the face of idmappings.

Add a generic helper and convert all filesystems over to it. Make
sure that filesystems that are mountable in unprivileged containers
verify that the specified uid and gid can be represented in the
owning namespace of the filesystem.

- Convert hostfs to the new mount api.

* tag 'vfs-6.11.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
fuse: Convert to new uid/gid option parsing helpers
fuse: verify {g,u}id mount options correctly
fat: Convert to new uid/gid option parsing helpers
fat: Convert to new mount api
fat: move debug into fat_mount_options
vboxsf: Convert to new uid/gid option parsing helpers
tracefs: Convert to new uid/gid option parsing helpers
smb: client: Convert to new uid/gid option parsing helpers
tmpfs: Convert to new uid/gid option parsing helpers
ntfs3: Convert to new uid/gid option parsing helpers
isofs: Convert to new uid/gid option parsing helpers
hugetlbfs: Convert to new uid/gid option parsing helpers
ext4: Convert to new uid/gid option parsing helpers
exfat: Convert to new uid/gid option parsing helpers
efivarfs: Convert to new uid/gid option parsing helpers
debugfs: Convert to new uid/gid option parsing helpers
autofs: Convert to new uid/gid option parsing helpers
fs_parse: add uid & gid option option parsing helpers
hostfs: Add const qualifier to host_root in hostfs_fill_super()
hostfs: convert hostfs to use the new mount API

+597 -530
+7 -2
Documentation/filesystems/mount_api.rst
··· 645 645 fs_param_is_blockdev Blockdev path * Needs lookup 646 646 fs_param_is_path Path * Needs lookup 647 647 fs_param_is_fd File descriptor result->int_32 648 + fs_param_is_uid User ID (u32) result->uid 649 + fs_param_is_gid Group ID (u32) result->gid 648 650 ======================= ======================= ===================== 649 651 650 652 Note that if the value is of fs_param_is_bool type, fs_parse() will try ··· 680 678 fsparam_bdev() fs_param_is_blockdev 681 679 fsparam_path() fs_param_is_path 682 680 fsparam_fd() fs_param_is_fd 681 + fsparam_uid() fs_param_is_uid 682 + fsparam_gid() fs_param_is_gid 683 683 ======================= =============================================== 684 684 685 685 all of which take two arguments, name string and option number - for ··· 788 784 option number (which it returns). 789 785 790 786 If successful, and if the parameter type indicates the result is a 791 - boolean, integer or enum type, the value is converted by this function and 792 - the result stored in result->{boolean,int_32,uint_32,uint_64}. 787 + boolean, integer, enum, uid, or gid type, the value is converted by this 788 + function and the result stored in 789 + result->{boolean,int_32,uint_32,uint_64,uid,gid}. 793 790 794 791 If a match isn't initially made, the key is prefixed with "no" and no 795 792 value is present then an attempt will be made to look up the key with the
+4 -12
fs/autofs/inode.c
··· 126 126 const struct fs_parameter_spec autofs_param_specs[] = { 127 127 fsparam_flag ("direct", Opt_direct), 128 128 fsparam_fd ("fd", Opt_fd), 129 - fsparam_u32 ("gid", Opt_gid), 129 + fsparam_gid ("gid", Opt_gid), 130 130 fsparam_flag ("ignore", Opt_ignore), 131 131 fsparam_flag ("indirect", Opt_indirect), 132 132 fsparam_u32 ("maxproto", Opt_maxproto), ··· 134 134 fsparam_flag ("offset", Opt_offset), 135 135 fsparam_u32 ("pgrp", Opt_pgrp), 136 136 fsparam_flag ("strictexpire", Opt_strictexpire), 137 - fsparam_u32 ("uid", Opt_uid), 137 + fsparam_uid ("uid", Opt_uid), 138 138 {} 139 139 }; 140 140 ··· 193 193 struct autofs_fs_context *ctx = fc->fs_private; 194 194 struct autofs_sb_info *sbi = fc->s_fs_info; 195 195 struct fs_parse_result result; 196 - kuid_t uid; 197 - kgid_t gid; 198 196 int opt; 199 197 200 198 opt = fs_parse(fc, autofs_param_specs, param, &result); ··· 203 205 case Opt_fd: 204 206 return autofs_parse_fd(fc, sbi, param, &result); 205 207 case Opt_uid: 206 - uid = make_kuid(current_user_ns(), result.uint_32); 207 - if (!uid_valid(uid)) 208 - return invalfc(fc, "Invalid uid"); 209 - ctx->uid = uid; 208 + ctx->uid = result.uid; 210 209 break; 211 210 case Opt_gid: 212 - gid = make_kgid(current_user_ns(), result.uint_32); 213 - if (!gid_valid(gid)) 214 - return invalfc(fc, "Invalid gid"); 215 - ctx->gid = gid; 211 + ctx->gid = result.gid; 216 212 break; 217 213 case Opt_pgrp: 218 214 ctx->pgrp = result.uint_32;
+4 -12
fs/debugfs/inode.c
··· 92 92 }; 93 93 94 94 static const struct fs_parameter_spec debugfs_param_specs[] = { 95 - fsparam_u32 ("gid", Opt_gid), 95 + fsparam_gid ("gid", Opt_gid), 96 96 fsparam_u32oct ("mode", Opt_mode), 97 - fsparam_u32 ("uid", Opt_uid), 97 + fsparam_uid ("uid", Opt_uid), 98 98 {} 99 99 }; 100 100 ··· 102 102 { 103 103 struct debugfs_fs_info *opts = fc->s_fs_info; 104 104 struct fs_parse_result result; 105 - kuid_t uid; 106 - kgid_t gid; 107 105 int opt; 108 106 109 107 opt = fs_parse(fc, debugfs_param_specs, param, &result); ··· 118 120 119 121 switch (opt) { 120 122 case Opt_uid: 121 - uid = make_kuid(current_user_ns(), result.uint_32); 122 - if (!uid_valid(uid)) 123 - return invalf(fc, "Unknown uid"); 124 - opts->uid = uid; 123 + opts->uid = result.uid; 125 124 break; 126 125 case Opt_gid: 127 - gid = make_kgid(current_user_ns(), result.uint_32); 128 - if (!gid_valid(gid)) 129 - return invalf(fc, "Unknown gid"); 130 - opts->gid = gid; 126 + opts->gid = result.gid; 131 127 break; 132 128 case Opt_mode: 133 129 opts->mode = result.uint_32 & S_IALLUGO;
+4 -8
fs/efivarfs/super.c
··· 275 275 }; 276 276 277 277 static const struct fs_parameter_spec efivarfs_parameters[] = { 278 - fsparam_u32("uid", Opt_uid), 279 - fsparam_u32("gid", Opt_gid), 278 + fsparam_uid("uid", Opt_uid), 279 + fsparam_gid("gid", Opt_gid), 280 280 {}, 281 281 }; 282 282 ··· 293 293 294 294 switch (opt) { 295 295 case Opt_uid: 296 - opts->uid = make_kuid(current_user_ns(), result.uint_32); 297 - if (!uid_valid(opts->uid)) 298 - return -EINVAL; 296 + opts->uid = result.uid; 299 297 break; 300 298 case Opt_gid: 301 - opts->gid = make_kgid(current_user_ns(), result.uint_32); 302 - if (!gid_valid(opts->gid)) 303 - return -EINVAL; 299 + opts->gid = result.gid; 304 300 break; 305 301 default: 306 302 return -EINVAL;
+4 -4
fs/exfat/super.c
··· 225 225 }; 226 226 227 227 static const struct fs_parameter_spec exfat_parameters[] = { 228 - fsparam_u32("uid", Opt_uid), 229 - fsparam_u32("gid", Opt_gid), 228 + fsparam_uid("uid", Opt_uid), 229 + fsparam_gid("gid", Opt_gid), 230 230 fsparam_u32oct("umask", Opt_umask), 231 231 fsparam_u32oct("dmask", Opt_dmask), 232 232 fsparam_u32oct("fmask", Opt_fmask), ··· 262 262 263 263 switch (opt) { 264 264 case Opt_uid: 265 - opts->fs_uid = make_kuid(current_user_ns(), result.uint_32); 265 + opts->fs_uid = result.uid; 266 266 break; 267 267 case Opt_gid: 268 - opts->fs_gid = make_kgid(current_user_ns(), result.uint_32); 268 + opts->fs_gid = result.gid; 269 269 break; 270 270 case Opt_umask: 271 271 opts->fs_fmask = result.uint_32;
+4 -18
fs/ext4/super.c
··· 1721 1721 fsparam_flag ("bsdgroups", Opt_grpid), 1722 1722 fsparam_flag ("nogrpid", Opt_nogrpid), 1723 1723 fsparam_flag ("sysvgroups", Opt_nogrpid), 1724 - fsparam_u32 ("resgid", Opt_resgid), 1725 - fsparam_u32 ("resuid", Opt_resuid), 1724 + fsparam_gid ("resgid", Opt_resgid), 1725 + fsparam_uid ("resuid", Opt_resuid), 1726 1726 fsparam_u32 ("sb", Opt_sb), 1727 1727 fsparam_enum ("errors", Opt_errors, ext4_param_errors), 1728 1728 fsparam_flag ("nouid32", Opt_nouid32), ··· 2127 2127 struct fs_parse_result result; 2128 2128 const struct mount_opts *m; 2129 2129 int is_remount; 2130 - kuid_t uid; 2131 - kgid_t gid; 2132 2130 int token; 2133 2131 2134 2132 token = fs_parse(fc, ext4_param_specs, param, &result); ··· 2268 2270 ctx->spec |= EXT4_SPEC_s_stripe; 2269 2271 return 0; 2270 2272 case Opt_resuid: 2271 - uid = make_kuid(current_user_ns(), result.uint_32); 2272 - if (!uid_valid(uid)) { 2273 - ext4_msg(NULL, KERN_ERR, "Invalid uid value %d", 2274 - result.uint_32); 2275 - return -EINVAL; 2276 - } 2277 - ctx->s_resuid = uid; 2273 + ctx->s_resuid = result.uid; 2278 2274 ctx->spec |= EXT4_SPEC_s_resuid; 2279 2275 return 0; 2280 2276 case Opt_resgid: 2281 - gid = make_kgid(current_user_ns(), result.uint_32); 2282 - if (!gid_valid(gid)) { 2283 - ext4_msg(NULL, KERN_ERR, "Invalid gid value %d", 2284 - result.uint_32); 2285 - return -EINVAL; 2286 - } 2287 - ctx->s_resgid = gid; 2277 + ctx->s_resgid = result.gid; 2288 2278 ctx->spec |= EXT4_SPEC_s_resgid; 2289 2279 return 0; 2290 2280 case Opt_journal_dev:
+15 -3
fs/fat/fat.h
··· 7 7 #include <linux/hash.h> 8 8 #include <linux/ratelimit.h> 9 9 #include <linux/msdos_fs.h> 10 + #include <linux/fs_context.h> 11 + #include <linux/fs_parser.h> 10 12 11 13 /* 12 14 * vfat shortname flags ··· 53 51 tz_set:1, /* Filesystem timestamps' offset set */ 54 52 rodir:1, /* allow ATTR_RO for directory */ 55 53 discard:1, /* Issue discard requests on deletions */ 56 - dos1xfloppy:1; /* Assume default BPB for DOS 1.x floppies */ 54 + dos1xfloppy:1, /* Assume default BPB for DOS 1.x floppies */ 55 + debug:1; /* Not currently used */ 57 56 }; 58 57 59 58 #define FAT_HASH_BITS 8 ··· 418 415 extern struct inode *fat_build_inode(struct super_block *sb, 419 416 struct msdos_dir_entry *de, loff_t i_pos); 420 417 extern int fat_sync_inode(struct inode *inode); 421 - extern int fat_fill_super(struct super_block *sb, void *data, int silent, 422 - int isvfat, void (*setup)(struct super_block *)); 418 + extern int fat_fill_super(struct super_block *sb, struct fs_context *fc, 419 + void (*setup)(struct super_block *)); 423 420 extern int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de); 424 421 425 422 extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, 426 423 struct inode *i2); 424 + 425 + extern const struct fs_parameter_spec fat_param_spec[]; 426 + int fat_init_fs_context(struct fs_context *fc, bool is_vfat); 427 + void fat_free_fc(struct fs_context *fc); 428 + 429 + int fat_parse_param(struct fs_context *fc, struct fs_parameter *param, 430 + bool is_vfat); 431 + int fat_reconfigure(struct fs_context *fc); 432 + 427 433 static inline unsigned long fat_dir_hash(int logstart) 428 434 { 429 435 return hash_32(logstart, FAT_HASH_BITS);
+338 -342
fs/fat/inode.c
··· 16 16 #include <linux/mpage.h> 17 17 #include <linux/vfs.h> 18 18 #include <linux/seq_file.h> 19 - #include <linux/parser.h> 20 19 #include <linux/uio.h> 21 20 #include <linux/blkdev.h> 22 21 #include <linux/backing-dev.h> ··· 803 804 kmem_cache_destroy(fat_inode_cachep); 804 805 } 805 806 806 - static int fat_remount(struct super_block *sb, int *flags, char *data) 807 + int fat_reconfigure(struct fs_context *fc) 807 808 { 808 809 bool new_rdonly; 810 + struct super_block *sb = fc->root->d_sb; 809 811 struct msdos_sb_info *sbi = MSDOS_SB(sb); 810 - *flags |= SB_NODIRATIME | (sbi->options.isvfat ? 0 : SB_NOATIME); 812 + fc->sb_flags |= SB_NODIRATIME | (sbi->options.isvfat ? 0 : SB_NOATIME); 811 813 812 814 sync_filesystem(sb); 813 815 814 816 /* make sure we update state on remount. */ 815 - new_rdonly = *flags & SB_RDONLY; 817 + new_rdonly = fc->sb_flags & SB_RDONLY; 816 818 if (new_rdonly != sb_rdonly(sb)) { 817 819 if (new_rdonly) 818 820 fat_set_state(sb, 0, 0); ··· 822 822 } 823 823 return 0; 824 824 } 825 + EXPORT_SYMBOL_GPL(fat_reconfigure); 825 826 826 827 static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) 827 828 { ··· 940 939 .evict_inode = fat_evict_inode, 941 940 .put_super = fat_put_super, 942 941 .statfs = fat_statfs, 943 - .remount_fs = fat_remount, 944 - 945 942 .show_options = fat_show_options, 946 943 }; 947 944 ··· 1036 1037 } 1037 1038 1038 1039 enum { 1039 - Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, 1040 - Opt_umask, Opt_dmask, Opt_fmask, Opt_allow_utime, Opt_codepage, 1041 - Opt_usefree, Opt_nocase, Opt_quiet, Opt_showexec, Opt_debug, 1042 - Opt_immutable, Opt_dots, Opt_nodots, 1043 - Opt_charset, Opt_shortname_lower, Opt_shortname_win95, 1044 - Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, 1045 - Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, 1046 - Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, 1047 - Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, 1048 - Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err, Opt_dos1xfloppy, 1040 + Opt_check, Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask, 1041 + Opt_allow_utime, Opt_codepage, Opt_usefree, Opt_nocase, Opt_quiet, 1042 + Opt_showexec, Opt_debug, Opt_immutable, Opt_dots, Opt_dotsOK, 1043 + Opt_charset, Opt_shortname, Opt_utf8, Opt_utf8_bool, 1044 + Opt_uni_xl, Opt_uni_xl_bool, Opt_nonumtail, Opt_nonumtail_bool, 1045 + Opt_obsolete, Opt_flush, Opt_tz, Opt_rodir, Opt_errors, Opt_discard, 1046 + Opt_nfs, Opt_nfs_enum, Opt_time_offset, Opt_dos1xfloppy, 1049 1047 }; 1050 1048 1051 - static const match_table_t fat_tokens = { 1052 - {Opt_check_r, "check=relaxed"}, 1053 - {Opt_check_s, "check=strict"}, 1054 - {Opt_check_n, "check=normal"}, 1055 - {Opt_check_r, "check=r"}, 1056 - {Opt_check_s, "check=s"}, 1057 - {Opt_check_n, "check=n"}, 1058 - {Opt_uid, "uid=%u"}, 1059 - {Opt_gid, "gid=%u"}, 1060 - {Opt_umask, "umask=%o"}, 1061 - {Opt_dmask, "dmask=%o"}, 1062 - {Opt_fmask, "fmask=%o"}, 1063 - {Opt_allow_utime, "allow_utime=%o"}, 1064 - {Opt_codepage, "codepage=%u"}, 1065 - {Opt_usefree, "usefree"}, 1066 - {Opt_nocase, "nocase"}, 1067 - {Opt_quiet, "quiet"}, 1068 - {Opt_showexec, "showexec"}, 1069 - {Opt_debug, "debug"}, 1070 - {Opt_immutable, "sys_immutable"}, 1071 - {Opt_flush, "flush"}, 1072 - {Opt_tz_utc, "tz=UTC"}, 1073 - {Opt_time_offset, "time_offset=%d"}, 1074 - {Opt_err_cont, "errors=continue"}, 1075 - {Opt_err_panic, "errors=panic"}, 1076 - {Opt_err_ro, "errors=remount-ro"}, 1077 - {Opt_discard, "discard"}, 1078 - {Opt_nfs_stale_rw, "nfs"}, 1079 - {Opt_nfs_stale_rw, "nfs=stale_rw"}, 1080 - {Opt_nfs_nostale_ro, "nfs=nostale_ro"}, 1081 - {Opt_dos1xfloppy, "dos1xfloppy"}, 1082 - {Opt_obsolete, "conv=binary"}, 1083 - {Opt_obsolete, "conv=text"}, 1084 - {Opt_obsolete, "conv=auto"}, 1085 - {Opt_obsolete, "conv=b"}, 1086 - {Opt_obsolete, "conv=t"}, 1087 - {Opt_obsolete, "conv=a"}, 1088 - {Opt_obsolete, "fat=%u"}, 1089 - {Opt_obsolete, "blocksize=%u"}, 1090 - {Opt_obsolete, "cvf_format=%20s"}, 1091 - {Opt_obsolete, "cvf_options=%100s"}, 1092 - {Opt_obsolete, "posix"}, 1093 - {Opt_err, NULL}, 1094 - }; 1095 - static const match_table_t msdos_tokens = { 1096 - {Opt_nodots, "nodots"}, 1097 - {Opt_nodots, "dotsOK=no"}, 1098 - {Opt_dots, "dots"}, 1099 - {Opt_dots, "dotsOK=yes"}, 1100 - {Opt_err, NULL} 1101 - }; 1102 - static const match_table_t vfat_tokens = { 1103 - {Opt_charset, "iocharset=%s"}, 1104 - {Opt_shortname_lower, "shortname=lower"}, 1105 - {Opt_shortname_win95, "shortname=win95"}, 1106 - {Opt_shortname_winnt, "shortname=winnt"}, 1107 - {Opt_shortname_mixed, "shortname=mixed"}, 1108 - {Opt_utf8_no, "utf8=0"}, /* 0 or no or false */ 1109 - {Opt_utf8_no, "utf8=no"}, 1110 - {Opt_utf8_no, "utf8=false"}, 1111 - {Opt_utf8_yes, "utf8=1"}, /* empty or 1 or yes or true */ 1112 - {Opt_utf8_yes, "utf8=yes"}, 1113 - {Opt_utf8_yes, "utf8=true"}, 1114 - {Opt_utf8_yes, "utf8"}, 1115 - {Opt_uni_xl_no, "uni_xlate=0"}, /* 0 or no or false */ 1116 - {Opt_uni_xl_no, "uni_xlate=no"}, 1117 - {Opt_uni_xl_no, "uni_xlate=false"}, 1118 - {Opt_uni_xl_yes, "uni_xlate=1"}, /* empty or 1 or yes or true */ 1119 - {Opt_uni_xl_yes, "uni_xlate=yes"}, 1120 - {Opt_uni_xl_yes, "uni_xlate=true"}, 1121 - {Opt_uni_xl_yes, "uni_xlate"}, 1122 - {Opt_nonumtail_no, "nonumtail=0"}, /* 0 or no or false */ 1123 - {Opt_nonumtail_no, "nonumtail=no"}, 1124 - {Opt_nonumtail_no, "nonumtail=false"}, 1125 - {Opt_nonumtail_yes, "nonumtail=1"}, /* empty or 1 or yes or true */ 1126 - {Opt_nonumtail_yes, "nonumtail=yes"}, 1127 - {Opt_nonumtail_yes, "nonumtail=true"}, 1128 - {Opt_nonumtail_yes, "nonumtail"}, 1129 - {Opt_rodir, "rodir"}, 1130 - {Opt_err, NULL} 1049 + static const struct constant_table fat_param_check[] = { 1050 + {"relaxed", 'r'}, 1051 + {"r", 'r'}, 1052 + {"strict", 's'}, 1053 + {"s", 's'}, 1054 + {"normal", 'n'}, 1055 + {"n", 'n'}, 1056 + {} 1131 1057 }; 1132 1058 1133 - static int parse_options(struct super_block *sb, char *options, int is_vfat, 1134 - int silent, int *debug, struct fat_mount_options *opts) 1059 + static const struct constant_table fat_param_tz[] = { 1060 + {"UTC", 0}, 1061 + {} 1062 + }; 1063 + 1064 + static const struct constant_table fat_param_errors[] = { 1065 + {"continue", FAT_ERRORS_CONT}, 1066 + {"panic", FAT_ERRORS_PANIC}, 1067 + {"remount-ro", FAT_ERRORS_RO}, 1068 + {} 1069 + }; 1070 + 1071 + 1072 + static const struct constant_table fat_param_nfs[] = { 1073 + {"stale_rw", FAT_NFS_STALE_RW}, 1074 + {"nostale_ro", FAT_NFS_NOSTALE_RO}, 1075 + {} 1076 + }; 1077 + 1078 + /* 1079 + * These are all obsolete but we still reject invalid options. 1080 + * The corresponding values are therefore meaningless. 1081 + */ 1082 + static const struct constant_table fat_param_conv[] = { 1083 + {"binary", 0}, 1084 + {"text", 0}, 1085 + {"auto", 0}, 1086 + {"b", 0}, 1087 + {"t", 0}, 1088 + {"a", 0}, 1089 + {} 1090 + }; 1091 + 1092 + /* Core options. See below for vfat and msdos extras */ 1093 + const struct fs_parameter_spec fat_param_spec[] = { 1094 + fsparam_enum ("check", Opt_check, fat_param_check), 1095 + fsparam_uid ("uid", Opt_uid), 1096 + fsparam_gid ("gid", Opt_gid), 1097 + fsparam_u32oct ("umask", Opt_umask), 1098 + fsparam_u32oct ("dmask", Opt_dmask), 1099 + fsparam_u32oct ("fmask", Opt_fmask), 1100 + fsparam_u32oct ("allow_utime", Opt_allow_utime), 1101 + fsparam_u32 ("codepage", Opt_codepage), 1102 + fsparam_flag ("usefree", Opt_usefree), 1103 + fsparam_flag ("nocase", Opt_nocase), 1104 + fsparam_flag ("quiet", Opt_quiet), 1105 + fsparam_flag ("showexec", Opt_showexec), 1106 + fsparam_flag ("debug", Opt_debug), 1107 + fsparam_flag ("sys_immutable", Opt_immutable), 1108 + fsparam_flag ("flush", Opt_flush), 1109 + fsparam_enum ("tz", Opt_tz, fat_param_tz), 1110 + fsparam_s32 ("time_offset", Opt_time_offset), 1111 + fsparam_enum ("errors", Opt_errors, fat_param_errors), 1112 + fsparam_flag ("discard", Opt_discard), 1113 + fsparam_flag ("nfs", Opt_nfs), 1114 + fsparam_enum ("nfs", Opt_nfs_enum, fat_param_nfs), 1115 + fsparam_flag ("dos1xfloppy", Opt_dos1xfloppy), 1116 + __fsparam(fs_param_is_enum, "conv", 1117 + Opt_obsolete, fs_param_deprecated, fat_param_conv), 1118 + __fsparam(fs_param_is_u32, "fat", 1119 + Opt_obsolete, fs_param_deprecated, NULL), 1120 + __fsparam(fs_param_is_u32, "blocksize", 1121 + Opt_obsolete, fs_param_deprecated, NULL), 1122 + __fsparam(fs_param_is_string, "cvf_format", 1123 + Opt_obsolete, fs_param_deprecated, NULL), 1124 + __fsparam(fs_param_is_string, "cvf_options", 1125 + Opt_obsolete, fs_param_deprecated, NULL), 1126 + __fsparam(NULL, "posix", 1127 + Opt_obsolete, fs_param_deprecated, NULL), 1128 + {} 1129 + }; 1130 + EXPORT_SYMBOL_GPL(fat_param_spec); 1131 + 1132 + static const struct fs_parameter_spec msdos_param_spec[] = { 1133 + fsparam_flag_no ("dots", Opt_dots), 1134 + fsparam_bool ("dotsOK", Opt_dotsOK), 1135 + {} 1136 + }; 1137 + 1138 + static const struct constant_table fat_param_shortname[] = { 1139 + {"lower", VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95}, 1140 + {"win95", VFAT_SFN_DISPLAY_WIN95 | VFAT_SFN_CREATE_WIN95}, 1141 + {"winnt", VFAT_SFN_DISPLAY_WINNT | VFAT_SFN_CREATE_WINNT}, 1142 + {"mixed", VFAT_SFN_DISPLAY_WINNT | VFAT_SFN_CREATE_WIN95}, 1143 + {} 1144 + }; 1145 + 1146 + static const struct fs_parameter_spec vfat_param_spec[] = { 1147 + fsparam_string ("iocharset", Opt_charset), 1148 + fsparam_enum ("shortname", Opt_shortname, fat_param_shortname), 1149 + fsparam_flag ("utf8", Opt_utf8), 1150 + fsparam_bool ("utf8", Opt_utf8_bool), 1151 + fsparam_flag ("uni_xlate", Opt_uni_xl), 1152 + fsparam_bool ("uni_xlate", Opt_uni_xl_bool), 1153 + fsparam_flag ("nonumtail", Opt_nonumtail), 1154 + fsparam_bool ("nonumtail", Opt_nonumtail_bool), 1155 + fsparam_flag ("rodir", Opt_rodir), 1156 + {} 1157 + }; 1158 + 1159 + int fat_parse_param(struct fs_context *fc, struct fs_parameter *param, 1160 + bool is_vfat) 1135 1161 { 1136 - char *p; 1137 - substring_t args[MAX_OPT_ARGS]; 1138 - int option; 1139 - char *iocharset; 1162 + struct fat_mount_options *opts = fc->fs_private; 1163 + struct fs_parse_result result; 1164 + int opt; 1140 1165 1141 - opts->isvfat = is_vfat; 1166 + /* remount options have traditionally been ignored */ 1167 + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) 1168 + return 0; 1142 1169 1143 - opts->fs_uid = current_uid(); 1144 - opts->fs_gid = current_gid(); 1145 - opts->fs_fmask = opts->fs_dmask = current_umask(); 1146 - opts->allow_utime = -1; 1147 - opts->codepage = fat_default_codepage; 1148 - fat_reset_iocharset(opts); 1149 - if (is_vfat) { 1150 - opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95; 1151 - opts->rodir = 0; 1152 - } else { 1153 - opts->shortname = 0; 1154 - opts->rodir = 1; 1170 + opt = fs_parse(fc, fat_param_spec, param, &result); 1171 + /* If option not found in fat_param_spec, try vfat/msdos options */ 1172 + if (opt == -ENOPARAM) { 1173 + if (is_vfat) 1174 + opt = fs_parse(fc, vfat_param_spec, param, &result); 1175 + else 1176 + opt = fs_parse(fc, msdos_param_spec, param, &result); 1155 1177 } 1156 - opts->name_check = 'n'; 1157 - opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0; 1158 - opts->unicode_xlate = 0; 1159 - opts->numtail = 1; 1160 - opts->usefree = opts->nocase = 0; 1161 - opts->tz_set = 0; 1162 - opts->nfs = 0; 1163 - opts->errors = FAT_ERRORS_RO; 1164 - *debug = 0; 1165 1178 1166 - opts->utf8 = IS_ENABLED(CONFIG_FAT_DEFAULT_UTF8) && is_vfat; 1179 + if (opt < 0) 1180 + return opt; 1167 1181 1168 - if (!options) 1169 - goto out; 1170 - 1171 - while ((p = strsep(&options, ",")) != NULL) { 1172 - int token; 1173 - if (!*p) 1174 - continue; 1175 - 1176 - token = match_token(p, fat_tokens, args); 1177 - if (token == Opt_err) { 1178 - if (is_vfat) 1179 - token = match_token(p, vfat_tokens, args); 1180 - else 1181 - token = match_token(p, msdos_tokens, args); 1182 - } 1183 - switch (token) { 1184 - case Opt_check_s: 1185 - opts->name_check = 's'; 1186 - break; 1187 - case Opt_check_r: 1188 - opts->name_check = 'r'; 1189 - break; 1190 - case Opt_check_n: 1191 - opts->name_check = 'n'; 1192 - break; 1193 - case Opt_usefree: 1194 - opts->usefree = 1; 1195 - break; 1196 - case Opt_nocase: 1197 - if (!is_vfat) 1198 - opts->nocase = 1; 1199 - else { 1200 - /* for backward compatibility */ 1201 - opts->shortname = VFAT_SFN_DISPLAY_WIN95 1202 - | VFAT_SFN_CREATE_WIN95; 1203 - } 1204 - break; 1205 - case Opt_quiet: 1206 - opts->quiet = 1; 1207 - break; 1208 - case Opt_showexec: 1209 - opts->showexec = 1; 1210 - break; 1211 - case Opt_debug: 1212 - *debug = 1; 1213 - break; 1214 - case Opt_immutable: 1215 - opts->sys_immutable = 1; 1216 - break; 1217 - case Opt_uid: 1218 - if (match_int(&args[0], &option)) 1219 - return -EINVAL; 1220 - opts->fs_uid = make_kuid(current_user_ns(), option); 1221 - if (!uid_valid(opts->fs_uid)) 1222 - return -EINVAL; 1223 - break; 1224 - case Opt_gid: 1225 - if (match_int(&args[0], &option)) 1226 - return -EINVAL; 1227 - opts->fs_gid = make_kgid(current_user_ns(), option); 1228 - if (!gid_valid(opts->fs_gid)) 1229 - return -EINVAL; 1230 - break; 1231 - case Opt_umask: 1232 - if (match_octal(&args[0], &option)) 1233 - return -EINVAL; 1234 - opts->fs_fmask = opts->fs_dmask = option; 1235 - break; 1236 - case Opt_dmask: 1237 - if (match_octal(&args[0], &option)) 1238 - return -EINVAL; 1239 - opts->fs_dmask = option; 1240 - break; 1241 - case Opt_fmask: 1242 - if (match_octal(&args[0], &option)) 1243 - return -EINVAL; 1244 - opts->fs_fmask = option; 1245 - break; 1246 - case Opt_allow_utime: 1247 - if (match_octal(&args[0], &option)) 1248 - return -EINVAL; 1249 - opts->allow_utime = option & (S_IWGRP | S_IWOTH); 1250 - break; 1251 - case Opt_codepage: 1252 - if (match_int(&args[0], &option)) 1253 - return -EINVAL; 1254 - opts->codepage = option; 1255 - break; 1256 - case Opt_flush: 1257 - opts->flush = 1; 1258 - break; 1259 - case Opt_time_offset: 1260 - if (match_int(&args[0], &option)) 1261 - return -EINVAL; 1262 - /* 1263 - * GMT+-12 zones may have DST corrections so at least 1264 - * 13 hours difference is needed. Make the limit 24 1265 - * just in case someone invents something unusual. 1266 - */ 1267 - if (option < -24 * 60 || option > 24 * 60) 1268 - return -EINVAL; 1269 - opts->tz_set = 1; 1270 - opts->time_offset = option; 1271 - break; 1272 - case Opt_tz_utc: 1273 - opts->tz_set = 1; 1274 - opts->time_offset = 0; 1275 - break; 1276 - case Opt_err_cont: 1277 - opts->errors = FAT_ERRORS_CONT; 1278 - break; 1279 - case Opt_err_panic: 1280 - opts->errors = FAT_ERRORS_PANIC; 1281 - break; 1282 - case Opt_err_ro: 1283 - opts->errors = FAT_ERRORS_RO; 1284 - break; 1285 - case Opt_nfs_stale_rw: 1286 - opts->nfs = FAT_NFS_STALE_RW; 1287 - break; 1288 - case Opt_nfs_nostale_ro: 1289 - opts->nfs = FAT_NFS_NOSTALE_RO; 1290 - break; 1291 - case Opt_dos1xfloppy: 1292 - opts->dos1xfloppy = 1; 1293 - break; 1294 - 1295 - /* msdos specific */ 1296 - case Opt_dots: 1297 - opts->dotsOK = 1; 1298 - break; 1299 - case Opt_nodots: 1300 - opts->dotsOK = 0; 1301 - break; 1302 - 1303 - /* vfat specific */ 1304 - case Opt_charset: 1305 - fat_reset_iocharset(opts); 1306 - iocharset = match_strdup(&args[0]); 1307 - if (!iocharset) 1308 - return -ENOMEM; 1309 - opts->iocharset = iocharset; 1310 - break; 1311 - case Opt_shortname_lower: 1312 - opts->shortname = VFAT_SFN_DISPLAY_LOWER 1313 - | VFAT_SFN_CREATE_WIN95; 1314 - break; 1315 - case Opt_shortname_win95: 1182 + switch (opt) { 1183 + case Opt_check: 1184 + opts->name_check = result.uint_32; 1185 + break; 1186 + case Opt_usefree: 1187 + opts->usefree = 1; 1188 + break; 1189 + case Opt_nocase: 1190 + if (!is_vfat) 1191 + opts->nocase = 1; 1192 + else { 1193 + /* for backward compatibility */ 1316 1194 opts->shortname = VFAT_SFN_DISPLAY_WIN95 1317 - | VFAT_SFN_CREATE_WIN95; 1318 - break; 1319 - case Opt_shortname_winnt: 1320 - opts->shortname = VFAT_SFN_DISPLAY_WINNT 1321 - | VFAT_SFN_CREATE_WINNT; 1322 - break; 1323 - case Opt_shortname_mixed: 1324 - opts->shortname = VFAT_SFN_DISPLAY_WINNT 1325 - | VFAT_SFN_CREATE_WIN95; 1326 - break; 1327 - case Opt_utf8_no: /* 0 or no or false */ 1328 - opts->utf8 = 0; 1329 - break; 1330 - case Opt_utf8_yes: /* empty or 1 or yes or true */ 1331 - opts->utf8 = 1; 1332 - break; 1333 - case Opt_uni_xl_no: /* 0 or no or false */ 1334 - opts->unicode_xlate = 0; 1335 - break; 1336 - case Opt_uni_xl_yes: /* empty or 1 or yes or true */ 1337 - opts->unicode_xlate = 1; 1338 - break; 1339 - case Opt_nonumtail_no: /* 0 or no or false */ 1340 - opts->numtail = 1; /* negated option */ 1341 - break; 1342 - case Opt_nonumtail_yes: /* empty or 1 or yes or true */ 1343 - opts->numtail = 0; /* negated option */ 1344 - break; 1345 - case Opt_rodir: 1346 - opts->rodir = 1; 1347 - break; 1348 - case Opt_discard: 1349 - opts->discard = 1; 1350 - break; 1351 - 1352 - /* obsolete mount options */ 1353 - case Opt_obsolete: 1354 - fat_msg(sb, KERN_INFO, "\"%s\" option is obsolete, " 1355 - "not supported now", p); 1356 - break; 1357 - /* unknown option */ 1358 - default: 1359 - if (!silent) { 1360 - fat_msg(sb, KERN_ERR, 1361 - "Unrecognized mount option \"%s\" " 1362 - "or missing value", p); 1363 - } 1364 - return -EINVAL; 1195 + | VFAT_SFN_CREATE_WIN95; 1365 1196 } 1366 - } 1197 + break; 1198 + case Opt_quiet: 1199 + opts->quiet = 1; 1200 + break; 1201 + case Opt_showexec: 1202 + opts->showexec = 1; 1203 + break; 1204 + case Opt_debug: 1205 + opts->debug = 1; 1206 + break; 1207 + case Opt_immutable: 1208 + opts->sys_immutable = 1; 1209 + break; 1210 + case Opt_uid: 1211 + opts->fs_uid = result.uid; 1212 + break; 1213 + case Opt_gid: 1214 + opts->fs_gid = result.gid; 1215 + break; 1216 + case Opt_umask: 1217 + opts->fs_fmask = opts->fs_dmask = result.uint_32; 1218 + break; 1219 + case Opt_dmask: 1220 + opts->fs_dmask = result.uint_32; 1221 + break; 1222 + case Opt_fmask: 1223 + opts->fs_fmask = result.uint_32; 1224 + break; 1225 + case Opt_allow_utime: 1226 + opts->allow_utime = result.uint_32 & (S_IWGRP | S_IWOTH); 1227 + break; 1228 + case Opt_codepage: 1229 + opts->codepage = result.uint_32; 1230 + break; 1231 + case Opt_flush: 1232 + opts->flush = 1; 1233 + break; 1234 + case Opt_time_offset: 1235 + /* 1236 + * GMT+-12 zones may have DST corrections so at least 1237 + * 13 hours difference is needed. Make the limit 24 1238 + * just in case someone invents something unusual. 1239 + */ 1240 + if (result.int_32 < -24 * 60 || result.int_32 > 24 * 60) 1241 + return -EINVAL; 1242 + opts->tz_set = 1; 1243 + opts->time_offset = result.int_32; 1244 + break; 1245 + case Opt_tz: 1246 + opts->tz_set = 1; 1247 + opts->time_offset = result.uint_32; 1248 + break; 1249 + case Opt_errors: 1250 + opts->errors = result.uint_32; 1251 + break; 1252 + case Opt_nfs: 1253 + opts->nfs = FAT_NFS_STALE_RW; 1254 + break; 1255 + case Opt_nfs_enum: 1256 + opts->nfs = result.uint_32; 1257 + break; 1258 + case Opt_dos1xfloppy: 1259 + opts->dos1xfloppy = 1; 1260 + break; 1367 1261 1368 - out: 1369 - /* UTF-8 doesn't provide FAT semantics */ 1370 - if (!strcmp(opts->iocharset, "utf8")) { 1371 - fat_msg(sb, KERN_WARNING, "utf8 is not a recommended IO charset" 1372 - " for FAT filesystems, filesystem will be " 1373 - "case sensitive!"); 1374 - } 1262 + /* msdos specific */ 1263 + case Opt_dots: /* dots / nodots */ 1264 + opts->dotsOK = !result.negated; 1265 + break; 1266 + case Opt_dotsOK: /* dotsOK = yes/no */ 1267 + opts->dotsOK = result.boolean; 1268 + break; 1375 1269 1376 - /* If user doesn't specify allow_utime, it's initialized from dmask. */ 1377 - if (opts->allow_utime == (unsigned short)-1) 1378 - opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); 1379 - if (opts->unicode_xlate) 1380 - opts->utf8 = 0; 1381 - if (opts->nfs == FAT_NFS_NOSTALE_RO) { 1382 - sb->s_flags |= SB_RDONLY; 1383 - sb->s_export_op = &fat_export_ops_nostale; 1270 + /* vfat specific */ 1271 + case Opt_charset: 1272 + fat_reset_iocharset(opts); 1273 + opts->iocharset = param->string; 1274 + param->string = NULL; /* Steal string */ 1275 + break; 1276 + case Opt_shortname: 1277 + opts->shortname = result.uint_32; 1278 + break; 1279 + case Opt_utf8: 1280 + opts->utf8 = 1; 1281 + break; 1282 + case Opt_utf8_bool: 1283 + opts->utf8 = result.boolean; 1284 + break; 1285 + case Opt_uni_xl: 1286 + opts->unicode_xlate = 1; 1287 + break; 1288 + case Opt_uni_xl_bool: 1289 + opts->unicode_xlate = result.boolean; 1290 + break; 1291 + case Opt_nonumtail: 1292 + opts->numtail = 0; /* negated option */ 1293 + break; 1294 + case Opt_nonumtail_bool: 1295 + opts->numtail = !result.boolean; /* negated option */ 1296 + break; 1297 + case Opt_rodir: 1298 + opts->rodir = 1; 1299 + break; 1300 + case Opt_discard: 1301 + opts->discard = 1; 1302 + break; 1303 + 1304 + /* obsolete mount options */ 1305 + case Opt_obsolete: 1306 + printk(KERN_INFO "FAT-fs: \"%s\" option is obsolete, " 1307 + "not supported now", param->key); 1308 + break; 1309 + default: 1310 + return -EINVAL; 1384 1311 } 1385 1312 1386 1313 return 0; 1387 1314 } 1315 + EXPORT_SYMBOL_GPL(fat_parse_param); 1388 1316 1389 1317 static int fat_read_root(struct inode *inode) 1390 1318 { ··· 1530 1604 /* 1531 1605 * Read the super block of an MS-DOS FS. 1532 1606 */ 1533 - int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, 1607 + int fat_fill_super(struct super_block *sb, struct fs_context *fc, 1534 1608 void (*setup)(struct super_block *)) 1535 1609 { 1610 + struct fat_mount_options *opts = fc->fs_private; 1611 + int silent = fc->sb_flags & SB_SILENT; 1536 1612 struct inode *root_inode = NULL, *fat_inode = NULL; 1537 1613 struct inode *fsinfo_inode = NULL; 1538 1614 struct buffer_head *bh; ··· 1542 1614 struct msdos_sb_info *sbi; 1543 1615 u16 logical_sector_size; 1544 1616 u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors; 1545 - int debug; 1546 1617 long error; 1547 1618 char buf[50]; 1548 1619 struct timespec64 ts; ··· 1570 1643 ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, 1571 1644 DEFAULT_RATELIMIT_BURST); 1572 1645 1573 - error = parse_options(sb, data, isvfat, silent, &debug, &sbi->options); 1574 - if (error) 1575 - goto out_fail; 1646 + /* UTF-8 doesn't provide FAT semantics */ 1647 + if (!strcmp(opts->iocharset, "utf8")) { 1648 + fat_msg(sb, KERN_WARNING, "utf8 is not a recommended IO charset" 1649 + " for FAT filesystems, filesystem will be" 1650 + " case sensitive!"); 1651 + } 1652 + 1653 + /* If user doesn't specify allow_utime, it's initialized from dmask. */ 1654 + if (opts->allow_utime == (unsigned short)-1) 1655 + opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); 1656 + if (opts->unicode_xlate) 1657 + opts->utf8 = 0; 1658 + if (opts->nfs == FAT_NFS_NOSTALE_RO) { 1659 + sb->s_flags |= SB_RDONLY; 1660 + sb->s_export_op = &fat_export_ops_nostale; 1661 + } 1662 + 1663 + /* Apply parsed options to sbi (structure copy) */ 1664 + sbi->options = *opts; 1665 + /* Transfer ownership of iocharset to sbi->options */ 1666 + opts->iocharset = NULL; 1576 1667 1577 1668 setup(sb); /* flavour-specific stuff that needs options */ 1578 1669 ··· 1894 1949 return ret; 1895 1950 } 1896 1951 EXPORT_SYMBOL_GPL(fat_flush_inodes); 1952 + 1953 + int fat_init_fs_context(struct fs_context *fc, bool is_vfat) 1954 + { 1955 + struct fat_mount_options *opts; 1956 + 1957 + opts = kzalloc(sizeof(*opts), GFP_KERNEL); 1958 + if (!opts) 1959 + return -ENOMEM; 1960 + 1961 + opts->isvfat = is_vfat; 1962 + opts->fs_uid = current_uid(); 1963 + opts->fs_gid = current_gid(); 1964 + opts->fs_fmask = opts->fs_dmask = current_umask(); 1965 + opts->allow_utime = -1; 1966 + opts->codepage = fat_default_codepage; 1967 + fat_reset_iocharset(opts); 1968 + if (is_vfat) { 1969 + opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95; 1970 + opts->rodir = 0; 1971 + } else { 1972 + opts->shortname = 0; 1973 + opts->rodir = 1; 1974 + } 1975 + opts->name_check = 'n'; 1976 + opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0; 1977 + opts->unicode_xlate = 0; 1978 + opts->numtail = 1; 1979 + opts->usefree = opts->nocase = 0; 1980 + opts->tz_set = 0; 1981 + opts->nfs = 0; 1982 + opts->errors = FAT_ERRORS_RO; 1983 + opts->debug = 0; 1984 + 1985 + opts->utf8 = IS_ENABLED(CONFIG_FAT_DEFAULT_UTF8) && is_vfat; 1986 + 1987 + fc->fs_private = opts; 1988 + /* fc->ops assigned by caller */ 1989 + 1990 + return 0; 1991 + } 1992 + EXPORT_SYMBOL_GPL(fat_init_fs_context); 1993 + 1994 + void fat_free_fc(struct fs_context *fc) 1995 + { 1996 + struct fat_mount_options *opts = fc->fs_private; 1997 + 1998 + if (opts->iocharset != fat_default_iocharset) 1999 + kfree(opts->iocharset); 2000 + kfree(fc->fs_private); 2001 + } 2002 + EXPORT_SYMBOL_GPL(fat_free_fc); 1897 2003 1898 2004 static int __init init_fat_fs(void) 1899 2005 {
+31 -7
fs/fat/namei_msdos.c
··· 650 650 sb->s_flags |= SB_NOATIME; 651 651 } 652 652 653 - static int msdos_fill_super(struct super_block *sb, void *data, int silent) 653 + static int msdos_fill_super(struct super_block *sb, struct fs_context *fc) 654 654 { 655 - return fat_fill_super(sb, data, silent, 0, setup); 655 + return fat_fill_super(sb, fc, setup); 656 656 } 657 657 658 - static struct dentry *msdos_mount(struct file_system_type *fs_type, 659 - int flags, const char *dev_name, 660 - void *data) 658 + static int msdos_get_tree(struct fs_context *fc) 661 659 { 662 - return mount_bdev(fs_type, flags, dev_name, data, msdos_fill_super); 660 + return get_tree_bdev(fc, msdos_fill_super); 661 + } 662 + 663 + static int msdos_parse_param(struct fs_context *fc, struct fs_parameter *param) 664 + { 665 + return fat_parse_param(fc, param, false); 666 + } 667 + 668 + static const struct fs_context_operations msdos_context_ops = { 669 + .parse_param = msdos_parse_param, 670 + .get_tree = msdos_get_tree, 671 + .reconfigure = fat_reconfigure, 672 + .free = fat_free_fc, 673 + }; 674 + 675 + static int msdos_init_fs_context(struct fs_context *fc) 676 + { 677 + int err; 678 + 679 + /* Initialize with is_vfat == false */ 680 + err = fat_init_fs_context(fc, false); 681 + if (err) 682 + return err; 683 + 684 + fc->ops = &msdos_context_ops; 685 + return 0; 663 686 } 664 687 665 688 static struct file_system_type msdos_fs_type = { 666 689 .owner = THIS_MODULE, 667 690 .name = "msdos", 668 - .mount = msdos_mount, 669 691 .kill_sb = kill_block_super, 670 692 .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP, 693 + .init_fs_context = msdos_init_fs_context, 694 + .parameters = fat_param_spec, 671 695 }; 672 696 MODULE_ALIAS_FS("msdos"); 673 697
+31 -7
fs/fat/namei_vfat.c
··· 1195 1195 sb->s_d_op = &vfat_dentry_ops; 1196 1196 } 1197 1197 1198 - static int vfat_fill_super(struct super_block *sb, void *data, int silent) 1198 + static int vfat_fill_super(struct super_block *sb, struct fs_context *fc) 1199 1199 { 1200 - return fat_fill_super(sb, data, silent, 1, setup); 1200 + return fat_fill_super(sb, fc, setup); 1201 1201 } 1202 1202 1203 - static struct dentry *vfat_mount(struct file_system_type *fs_type, 1204 - int flags, const char *dev_name, 1205 - void *data) 1203 + static int vfat_get_tree(struct fs_context *fc) 1206 1204 { 1207 - return mount_bdev(fs_type, flags, dev_name, data, vfat_fill_super); 1205 + return get_tree_bdev(fc, vfat_fill_super); 1206 + } 1207 + 1208 + static int vfat_parse_param(struct fs_context *fc, struct fs_parameter *param) 1209 + { 1210 + return fat_parse_param(fc, param, true); 1211 + } 1212 + 1213 + static const struct fs_context_operations vfat_context_ops = { 1214 + .parse_param = vfat_parse_param, 1215 + .get_tree = vfat_get_tree, 1216 + .reconfigure = fat_reconfigure, 1217 + .free = fat_free_fc, 1218 + }; 1219 + 1220 + static int vfat_init_fs_context(struct fs_context *fc) 1221 + { 1222 + int err; 1223 + 1224 + /* Initialize with is_vfat == true */ 1225 + err = fat_init_fs_context(fc, true); 1226 + if (err) 1227 + return err; 1228 + 1229 + fc->ops = &vfat_context_ops; 1230 + return 0; 1208 1231 } 1209 1232 1210 1233 static struct file_system_type vfat_fs_type = { 1211 1234 .owner = THIS_MODULE, 1212 1235 .name = "vfat", 1213 - .mount = vfat_mount, 1214 1236 .kill_sb = kill_block_super, 1215 1237 .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP, 1238 + .init_fs_context = vfat_init_fs_context, 1239 + .parameters = fat_param_spec, 1216 1240 }; 1217 1241 MODULE_ALIAS_FS("vfat"); 1218 1242
+34
fs/fs_parser.c
··· 308 308 } 309 309 EXPORT_SYMBOL(fs_param_is_fd); 310 310 311 + int fs_param_is_uid(struct p_log *log, const struct fs_parameter_spec *p, 312 + struct fs_parameter *param, struct fs_parse_result *result) 313 + { 314 + kuid_t uid; 315 + 316 + if (fs_param_is_u32(log, p, param, result) != 0) 317 + return fs_param_bad_value(log, param); 318 + 319 + uid = make_kuid(current_user_ns(), result->uint_32); 320 + if (!uid_valid(uid)) 321 + return inval_plog(log, "Invalid uid '%s'", param->string); 322 + 323 + result->uid = uid; 324 + return 0; 325 + } 326 + EXPORT_SYMBOL(fs_param_is_uid); 327 + 328 + int fs_param_is_gid(struct p_log *log, const struct fs_parameter_spec *p, 329 + struct fs_parameter *param, struct fs_parse_result *result) 330 + { 331 + kgid_t gid; 332 + 333 + if (fs_param_is_u32(log, p, param, result) != 0) 334 + return fs_param_bad_value(log, param); 335 + 336 + gid = make_kgid(current_user_ns(), result->uint_32); 337 + if (!gid_valid(gid)) 338 + return inval_plog(log, "Invalid gid '%s'", param->string); 339 + 340 + result->gid = gid; 341 + return 0; 342 + } 343 + EXPORT_SYMBOL(fs_param_is_gid); 344 + 311 345 int fs_param_is_blockdev(struct p_log *log, const struct fs_parameter_spec *p, 312 346 struct fs_parameter *param, struct fs_parse_result *result) 313 347 {
+18 -6
fs/fuse/inode.c
··· 740 740 fsparam_string ("source", OPT_SOURCE), 741 741 fsparam_u32 ("fd", OPT_FD), 742 742 fsparam_u32oct ("rootmode", OPT_ROOTMODE), 743 - fsparam_u32 ("user_id", OPT_USER_ID), 744 - fsparam_u32 ("group_id", OPT_GROUP_ID), 743 + fsparam_uid ("user_id", OPT_USER_ID), 744 + fsparam_gid ("group_id", OPT_GROUP_ID), 745 745 fsparam_flag ("default_permissions", OPT_DEFAULT_PERMISSIONS), 746 746 fsparam_flag ("allow_other", OPT_ALLOW_OTHER), 747 747 fsparam_u32 ("max_read", OPT_MAX_READ), ··· 755 755 struct fs_parse_result result; 756 756 struct fuse_fs_context *ctx = fsc->fs_private; 757 757 int opt; 758 + kuid_t kuid; 759 + kgid_t kgid; 758 760 759 761 if (fsc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { 760 762 /* ··· 801 799 break; 802 800 803 801 case OPT_USER_ID: 804 - ctx->user_id = make_kuid(fsc->user_ns, result.uint_32); 805 - if (!uid_valid(ctx->user_id)) 802 + kuid = result.uid; 803 + /* 804 + * The requested uid must be representable in the 805 + * filesystem's idmapping. 806 + */ 807 + if (!kuid_has_mapping(fsc->user_ns, kuid)) 806 808 return invalfc(fsc, "Invalid user_id"); 809 + ctx->user_id = kuid; 807 810 ctx->user_id_present = true; 808 811 break; 809 812 810 813 case OPT_GROUP_ID: 811 - ctx->group_id = make_kgid(fsc->user_ns, result.uint_32); 812 - if (!gid_valid(ctx->group_id)) 814 + kgid = result.gid; 815 + /* 816 + * The requested gid must be representable in the 817 + * filesystem's idmapping. 818 + */ 819 + if (!kgid_has_mapping(fsc->user_ns, kgid)) 813 820 return invalfc(fsc, "Invalid group_id"); 821 + ctx->group_id = kgid; 814 822 ctx->group_id_present = true; 815 823 break; 816 824
+62 -21
fs/hostfs/hostfs_kern.c
··· 16 16 #include <linux/seq_file.h> 17 17 #include <linux/writeback.h> 18 18 #include <linux/mount.h> 19 + #include <linux/fs_context.h> 19 20 #include <linux/namei.h> 20 21 #include "hostfs.h" 21 22 #include <init.h> 22 23 #include <kern.h> 24 + 25 + struct hostfs_fs_info { 26 + char *host_root_path; 27 + }; 23 28 24 29 struct hostfs_inode_info { 25 30 int fd; ··· 95 90 char *p = dentry_path_raw(dentry, name, PATH_MAX); 96 91 char *root; 97 92 size_t len; 93 + struct hostfs_fs_info *fsi; 98 94 99 - root = dentry->d_sb->s_fs_info; 95 + fsi = dentry->d_sb->s_fs_info; 96 + root = fsi->host_root_path; 100 97 len = strlen(root); 101 98 if (IS_ERR(p)) { 102 99 __putname(name); ··· 203 196 long long f_bavail; 204 197 long long f_files; 205 198 long long f_ffree; 199 + struct hostfs_fs_info *fsi; 206 200 207 - err = do_statfs(dentry->d_sb->s_fs_info, 201 + fsi = dentry->d_sb->s_fs_info; 202 + err = do_statfs(fsi->host_root_path, 208 203 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, 209 204 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 210 205 &sf->f_namelen); ··· 254 245 255 246 static int hostfs_show_options(struct seq_file *seq, struct dentry *root) 256 247 { 257 - const char *root_path = root->d_sb->s_fs_info; 248 + struct hostfs_fs_info *fsi; 249 + const char *root_path; 250 + 251 + fsi = root->d_sb->s_fs_info; 252 + root_path = fsi->host_root_path; 258 253 size_t offset = strlen(root_ino) + 1; 259 254 260 255 if (strlen(root_path) > offset) ··· 924 911 .get_link = hostfs_get_link, 925 912 }; 926 913 927 - static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) 914 + static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) 928 915 { 916 + struct hostfs_fs_info *fsi = sb->s_fs_info; 917 + const char *host_root = fc->source; 929 918 struct inode *root_inode; 930 - char *host_root_path, *req_root = d; 931 919 int err; 932 920 933 921 sb->s_blocksize = 1024; ··· 942 928 return err; 943 929 944 930 /* NULL is printed as '(null)' by printf(): avoid that. */ 945 - if (req_root == NULL) 946 - req_root = ""; 931 + if (fc->source == NULL) 932 + host_root = ""; 947 933 948 - sb->s_fs_info = host_root_path = 949 - kasprintf(GFP_KERNEL, "%s/%s", root_ino, req_root); 950 - if (host_root_path == NULL) 934 + fsi->host_root_path = 935 + kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); 936 + if (fsi->host_root_path == NULL) 951 937 return -ENOMEM; 952 938 953 - root_inode = hostfs_iget(sb, host_root_path); 939 + root_inode = hostfs_iget(sb, fsi->host_root_path); 954 940 if (IS_ERR(root_inode)) 955 941 return PTR_ERR(root_inode); 956 942 ··· 958 944 char *name; 959 945 960 946 iput(root_inode); 961 - name = follow_link(host_root_path); 947 + name = follow_link(fsi->host_root_path); 962 948 if (IS_ERR(name)) 963 949 return PTR_ERR(name); 964 950 ··· 975 961 return 0; 976 962 } 977 963 978 - static struct dentry *hostfs_read_sb(struct file_system_type *type, 979 - int flags, const char *dev_name, 980 - void *data) 964 + static int hostfs_fc_get_tree(struct fs_context *fc) 981 965 { 982 - return mount_nodev(type, flags, data, hostfs_fill_sb_common); 966 + return get_tree_nodev(fc, hostfs_fill_super); 967 + } 968 + 969 + static void hostfs_fc_free(struct fs_context *fc) 970 + { 971 + struct hostfs_fs_info *fsi = fc->s_fs_info; 972 + 973 + if (!fsi) 974 + return; 975 + 976 + kfree(fsi->host_root_path); 977 + kfree(fsi); 978 + } 979 + 980 + static const struct fs_context_operations hostfs_context_ops = { 981 + .get_tree = hostfs_fc_get_tree, 982 + .free = hostfs_fc_free, 983 + }; 984 + 985 + static int hostfs_init_fs_context(struct fs_context *fc) 986 + { 987 + struct hostfs_fs_info *fsi; 988 + 989 + fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); 990 + if (!fsi) 991 + return -ENOMEM; 992 + 993 + fc->s_fs_info = fsi; 994 + fc->ops = &hostfs_context_ops; 995 + return 0; 983 996 } 984 997 985 998 static void hostfs_kill_sb(struct super_block *s) ··· 1016 975 } 1017 976 1018 977 static struct file_system_type hostfs_type = { 1019 - .owner = THIS_MODULE, 1020 - .name = "hostfs", 1021 - .mount = hostfs_read_sb, 1022 - .kill_sb = hostfs_kill_sb, 1023 - .fs_flags = 0, 978 + .owner = THIS_MODULE, 979 + .name = "hostfs", 980 + .init_fs_context = hostfs_init_fs_context, 981 + .kill_sb = hostfs_kill_sb, 982 + .fs_flags = 0, 1024 983 }; 1025 984 MODULE_ALIAS_FS("hostfs"); 1026 985
+4 -8
fs/hugetlbfs/inode.c
··· 73 73 }; 74 74 75 75 static const struct fs_parameter_spec hugetlb_fs_parameters[] = { 76 - fsparam_u32 ("gid", Opt_gid), 76 + fsparam_gid ("gid", Opt_gid), 77 77 fsparam_string("min_size", Opt_min_size), 78 78 fsparam_u32oct("mode", Opt_mode), 79 79 fsparam_string("nr_inodes", Opt_nr_inodes), 80 80 fsparam_string("pagesize", Opt_pagesize), 81 81 fsparam_string("size", Opt_size), 82 - fsparam_u32 ("uid", Opt_uid), 82 + fsparam_uid ("uid", Opt_uid), 83 83 {} 84 84 }; 85 85 ··· 1376 1376 1377 1377 switch (opt) { 1378 1378 case Opt_uid: 1379 - ctx->uid = make_kuid(current_user_ns(), result.uint_32); 1380 - if (!uid_valid(ctx->uid)) 1381 - goto bad_val; 1379 + ctx->uid = result.uid; 1382 1380 return 0; 1383 1381 1384 1382 case Opt_gid: 1385 - ctx->gid = make_kgid(current_user_ns(), result.uint_32); 1386 - if (!gid_valid(ctx->gid)) 1387 - goto bad_val; 1383 + ctx->gid = result.gid; 1388 1384 return 0; 1389 1385 1390 1386 case Opt_mode:
+4 -12
fs/isofs/inode.c
··· 326 326 fsparam_u32 ("session", Opt_session), 327 327 fsparam_u32 ("sbsector", Opt_sb), 328 328 fsparam_enum ("check", Opt_check, isofs_param_check), 329 - fsparam_u32 ("uid", Opt_uid), 330 - fsparam_u32 ("gid", Opt_gid), 329 + fsparam_uid ("uid", Opt_uid), 330 + fsparam_gid ("gid", Opt_gid), 331 331 /* Note: mode/dmode historically accepted %u not strictly %o */ 332 332 fsparam_u32 ("mode", Opt_mode), 333 333 fsparam_u32 ("dmode", Opt_dmode), ··· 344 344 struct isofs_options *popt = fc->fs_private; 345 345 struct fs_parse_result result; 346 346 int opt; 347 - kuid_t uid; 348 - kgid_t gid; 349 347 unsigned int n; 350 348 351 349 /* There are no remountable options */ ··· 407 409 case Opt_ignore: 408 410 break; 409 411 case Opt_uid: 410 - uid = make_kuid(current_user_ns(), result.uint_32); 411 - if (!uid_valid(uid)) 412 - return -EINVAL; 413 - popt->uid = uid; 412 + popt->uid = result.uid; 414 413 popt->uid_set = 1; 415 414 break; 416 415 case Opt_gid: 417 - gid = make_kgid(current_user_ns(), result.uint_32); 418 - if (!gid_valid(gid)) 419 - return -EINVAL; 420 - popt->gid = gid; 416 + popt->gid = result.gid; 421 417 popt->gid_set = 1; 422 418 break; 423 419 case Opt_mode:
+4 -8
fs/ntfs3/super.c
··· 259 259 260 260 // clang-format off 261 261 static const struct fs_parameter_spec ntfs_fs_parameters[] = { 262 - fsparam_u32("uid", Opt_uid), 263 - fsparam_u32("gid", Opt_gid), 262 + fsparam_uid("uid", Opt_uid), 263 + fsparam_gid("gid", Opt_gid), 264 264 fsparam_u32oct("umask", Opt_umask), 265 265 fsparam_u32oct("dmask", Opt_dmask), 266 266 fsparam_u32oct("fmask", Opt_fmask), ··· 319 319 320 320 switch (opt) { 321 321 case Opt_uid: 322 - opts->fs_uid = make_kuid(current_user_ns(), result.uint_32); 323 - if (!uid_valid(opts->fs_uid)) 324 - return invalf(fc, "ntfs3: Invalid value for uid."); 322 + opts->fs_uid = result.uid; 325 323 break; 326 324 case Opt_gid: 327 - opts->fs_gid = make_kgid(current_user_ns(), result.uint_32); 328 - if (!gid_valid(opts->fs_gid)) 329 - return invalf(fc, "ntfs3: Invalid value for gid."); 325 + opts->fs_gid = result.gid; 330 326 break; 331 327 case Opt_umask: 332 328 if (result.uint_32 & ~07777)
+12 -27
fs/smb/client/fs_context.c
··· 128 128 fsparam_flag("compress", Opt_compress), 129 129 fsparam_flag("witness", Opt_witness), 130 130 131 + /* Mount options which take uid or gid */ 132 + fsparam_uid("backupuid", Opt_backupuid), 133 + fsparam_gid("backupgid", Opt_backupgid), 134 + fsparam_uid("uid", Opt_uid), 135 + fsparam_uid("cruid", Opt_cruid), 136 + fsparam_gid("gid", Opt_gid), 137 + 131 138 /* Mount options which take numeric value */ 132 - fsparam_u32("backupuid", Opt_backupuid), 133 - fsparam_u32("backupgid", Opt_backupgid), 134 - fsparam_u32("uid", Opt_uid), 135 - fsparam_u32("cruid", Opt_cruid), 136 - fsparam_u32("gid", Opt_gid), 137 139 fsparam_u32("file_mode", Opt_file_mode), 138 140 fsparam_u32("dirmode", Opt_dirmode), 139 141 fsparam_u32("dir_mode", Opt_dirmode), ··· 953 951 int i, opt; 954 952 bool is_smb3 = !strcmp(fc->fs_type->name, "smb3"); 955 953 bool skip_parsing = false; 956 - kuid_t uid; 957 - kgid_t gid; 958 954 959 955 cifs_dbg(FYI, "CIFS: parsing cifs mount option '%s'\n", param->key); 960 956 ··· 1083 1083 } 1084 1084 break; 1085 1085 case Opt_uid: 1086 - uid = make_kuid(current_user_ns(), result.uint_32); 1087 - if (!uid_valid(uid)) 1088 - goto cifs_parse_mount_err; 1089 - ctx->linux_uid = uid; 1086 + ctx->linux_uid = result.uid; 1090 1087 ctx->uid_specified = true; 1091 1088 break; 1092 1089 case Opt_cruid: 1093 - uid = make_kuid(current_user_ns(), result.uint_32); 1094 - if (!uid_valid(uid)) 1095 - goto cifs_parse_mount_err; 1096 - ctx->cred_uid = uid; 1090 + ctx->cred_uid = result.uid; 1097 1091 ctx->cruid_specified = true; 1098 1092 break; 1099 1093 case Opt_backupuid: 1100 - uid = make_kuid(current_user_ns(), result.uint_32); 1101 - if (!uid_valid(uid)) 1102 - goto cifs_parse_mount_err; 1103 - ctx->backupuid = uid; 1094 + ctx->backupuid = result.uid; 1104 1095 ctx->backupuid_specified = true; 1105 1096 break; 1106 1097 case Opt_backupgid: 1107 - gid = make_kgid(current_user_ns(), result.uint_32); 1108 - if (!gid_valid(gid)) 1109 - goto cifs_parse_mount_err; 1110 - ctx->backupgid = gid; 1098 + ctx->backupgid = result.gid; 1111 1099 ctx->backupgid_specified = true; 1112 1100 break; 1113 1101 case Opt_gid: 1114 - gid = make_kgid(current_user_ns(), result.uint_32); 1115 - if (!gid_valid(gid)) 1116 - goto cifs_parse_mount_err; 1117 - ctx->linux_gid = gid; 1102 + ctx->linux_gid = result.gid; 1118 1103 ctx->gid_specified = true; 1119 1104 break; 1120 1105 case Opt_port:
+4 -12
fs/tracefs/inode.c
··· 296 296 }; 297 297 298 298 static const struct fs_parameter_spec tracefs_param_specs[] = { 299 - fsparam_u32 ("gid", Opt_gid), 299 + fsparam_gid ("gid", Opt_gid), 300 300 fsparam_u32oct ("mode", Opt_mode), 301 - fsparam_u32 ("uid", Opt_uid), 301 + fsparam_uid ("uid", Opt_uid), 302 302 {} 303 303 }; 304 304 ··· 306 306 { 307 307 struct tracefs_fs_info *opts = fc->s_fs_info; 308 308 struct fs_parse_result result; 309 - kuid_t uid; 310 - kgid_t gid; 311 309 int opt; 312 310 313 311 opt = fs_parse(fc, tracefs_param_specs, param, &result); ··· 314 316 315 317 switch (opt) { 316 318 case Opt_uid: 317 - uid = make_kuid(current_user_ns(), result.uint_32); 318 - if (!uid_valid(uid)) 319 - return invalf(fc, "Unknown uid"); 320 - opts->uid = uid; 319 + opts->uid = result.uid; 321 320 break; 322 321 case Opt_gid: 323 - gid = make_kgid(current_user_ns(), result.uint_32); 324 - if (!gid_valid(gid)) 325 - return invalf(fc, "Unknown gid"); 326 - opts->gid = gid; 322 + opts->gid = result.gid; 327 323 break; 328 324 case Opt_mode: 329 325 opts->mode = result.uint_32 & S_IALLUGO;
+4 -12
fs/vboxsf/super.c
··· 41 41 42 42 static const struct fs_parameter_spec vboxsf_fs_parameters[] = { 43 43 fsparam_string ("nls", opt_nls), 44 - fsparam_u32 ("uid", opt_uid), 45 - fsparam_u32 ("gid", opt_gid), 44 + fsparam_uid ("uid", opt_uid), 45 + fsparam_gid ("gid", opt_gid), 46 46 fsparam_u32 ("ttl", opt_ttl), 47 47 fsparam_u32oct ("dmode", opt_dmode), 48 48 fsparam_u32oct ("fmode", opt_fmode), ··· 55 55 { 56 56 struct vboxsf_fs_context *ctx = fc->fs_private; 57 57 struct fs_parse_result result; 58 - kuid_t uid; 59 - kgid_t gid; 60 58 int opt; 61 59 62 60 opt = fs_parse(fc, vboxsf_fs_parameters, param, &result); ··· 71 73 param->string = NULL; 72 74 break; 73 75 case opt_uid: 74 - uid = make_kuid(current_user_ns(), result.uint_32); 75 - if (!uid_valid(uid)) 76 - return -EINVAL; 77 - ctx->o.uid = uid; 76 + ctx->o.uid = result.uid; 78 77 break; 79 78 case opt_gid: 80 - gid = make_kgid(current_user_ns(), result.uint_32); 81 - if (!gid_valid(gid)) 82 - return -EINVAL; 83 - ctx->o.gid = gid; 79 + ctx->o.gid = result.gid; 84 80 break; 85 81 case opt_ttl: 86 82 ctx->o.ttl = msecs_to_jiffies(result.uint_32);
+5 -1
include/linux/fs_parser.h
··· 28 28 */ 29 29 fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64, 30 30 fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev, 31 - fs_param_is_path, fs_param_is_fd; 31 + fs_param_is_path, fs_param_is_fd, fs_param_is_uid, fs_param_is_gid; 32 32 33 33 /* 34 34 * Specification of the type of value a parameter wants. ··· 57 57 int int_32; /* For spec_s32/spec_enum */ 58 58 unsigned int uint_32; /* For spec_u32{,_octal,_hex}/spec_enum */ 59 59 u64 uint_64; /* For spec_u64 */ 60 + kuid_t uid; 61 + kgid_t gid; 60 62 }; 61 63 }; 62 64 ··· 133 131 #define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL) 134 132 #define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL) 135 133 #define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL) 134 + #define fsparam_uid(NAME, OPT) __fsparam(fs_param_is_uid, NAME, OPT, 0, NULL) 135 + #define fsparam_gid(NAME, OPT) __fsparam(fs_param_is_gid, NAME, OPT, 0, NULL) 136 136 137 137 /* String parameter that allows empty argument */ 138 138 #define fsparam_string_empty(NAME, OPT) \
+4 -8
mm/shmem.c
··· 3917 3917 }; 3918 3918 3919 3919 const struct fs_parameter_spec shmem_fs_parameters[] = { 3920 - fsparam_u32 ("gid", Opt_gid), 3920 + fsparam_gid ("gid", Opt_gid), 3921 3921 fsparam_enum ("huge", Opt_huge, shmem_param_enums_huge), 3922 3922 fsparam_u32oct("mode", Opt_mode), 3923 3923 fsparam_string("mpol", Opt_mpol), 3924 3924 fsparam_string("nr_blocks", Opt_nr_blocks), 3925 3925 fsparam_string("nr_inodes", Opt_nr_inodes), 3926 3926 fsparam_string("size", Opt_size), 3927 - fsparam_u32 ("uid", Opt_uid), 3927 + fsparam_uid ("uid", Opt_uid), 3928 3928 fsparam_flag ("inode32", Opt_inode32), 3929 3929 fsparam_flag ("inode64", Opt_inode64), 3930 3930 fsparam_flag ("noswap", Opt_noswap), ··· 3984 3984 ctx->mode = result.uint_32 & 07777; 3985 3985 break; 3986 3986 case Opt_uid: 3987 - kuid = make_kuid(current_user_ns(), result.uint_32); 3988 - if (!uid_valid(kuid)) 3989 - goto bad_value; 3987 + kuid = result.uid; 3990 3988 3991 3989 /* 3992 3990 * The requested uid must be representable in the ··· 3996 3998 ctx->uid = kuid; 3997 3999 break; 3998 4000 case Opt_gid: 3999 - kgid = make_kgid(current_user_ns(), result.uint_32); 4000 - if (!gid_valid(kgid)) 4001 - goto bad_value; 4001 + kgid = result.gid; 4002 4002 4003 4003 /* 4004 4004 * The requested gid must be representable in the