Changeset 87014 in vbox for trunk/src/VBox/Additions/linux
- Timestamp:
- Nov 27, 2020 9:18:18 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 141587
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c
r86897 r87014 58 58 #include <VBox/err.h> 59 59 #include <iprt/path.h> 60 #if RTLNX_VER_MIN(5,1,0) 61 # include <linux/fs_context.h> 62 # include <linux/fs_parser.h> 63 #endif 60 64 61 65 … … 216 220 *sf_gp = NULL; /* (old gcc maybe used initialized) */ 217 221 222 #if RTLNX_VER_MAX(5,1,0) 218 223 /* 219 224 * Validate info. … … 227 232 return -EINVAL; 228 233 } 234 #endif 229 235 name_len = RTStrNLen(info->name, sizeof(info->name)); 230 236 if (name_len >= sizeof(info->name)) { … … 545 551 546 552 /** 547 * This is called by vbsf_read_super_24() and vbsf_read_super_26() when vfs mounts548 * the fs and wants to readsuper_block.553 * This is called by vbsf_read_super_24(), vbsf_read_super_26(), and 554 * vbsf_get_tree() when vfs mounts the fs and wants to read the super_block. 549 555 * 550 556 * Calls vbsf_super_info_alloc_and_map_it() to map the folder and allocate super … … 555 561 * Should respect @a flags. 556 562 */ 563 #if RTLNX_VER_MIN(5,1,0) 564 static int vbsf_read_super_aux(struct super_block *sb, struct fs_context *fc) 565 #else 557 566 static int vbsf_read_super_aux(struct super_block *sb, void *data, int flags) 567 #endif 558 568 { 559 569 int rc; … … 561 571 562 572 TRACE(); 573 #if RTLNX_VER_MAX(5,1,0) 563 574 if (!data) { 564 575 SFLOGRELBOTH(("vboxsf: No mount data. Is mount.vboxsf installed (typically in /sbin)?\n")); … … 570 581 return -ENOSYS; 571 582 } 583 #endif 572 584 573 585 /* 574 586 * Create our super info structure and map the shared folder. 575 587 */ 588 #if RTLNX_VER_MIN(5,1,0) 589 struct vbsf_mount_info_new *info = fc->fs_private; 590 rc = vbsf_super_info_alloc_and_map_it(info, &pSuperInfo); 591 #else 576 592 rc = vbsf_super_info_alloc_and_map_it((struct vbsf_mount_info_new *)data, &pSuperInfo); 593 #endif 577 594 if (rc == 0) { 578 595 /* … … 744 761 } 745 762 763 #if RTLNX_VER_MIN(5,1,0) 764 static int vbsf_remount_fs(struct super_block *sb, 765 struct vbsf_mount_info_new *info) 766 #else 746 767 static int vbsf_remount_fs(struct super_block *sb, int *flags, char *data) 768 #endif 747 769 { 748 770 #if RTLNX_VER_MIN(2,4,23) 749 struct vbsf_super_info *pSuperInfo = pSuperInfo =VBSF_GET_SUPER_INFO(sb);771 struct vbsf_super_info *pSuperInfo = VBSF_GET_SUPER_INFO(sb); 750 772 struct vbsf_inode_info *sf_i; 751 773 struct inode *iroot; … … 754 776 Assert(pSuperInfo); 755 777 778 # if RTLNX_VER_MIN(5,1,0) 779 vbsf_super_info_copy_remount_options(pSuperInfo, info); 780 # else 756 781 if (data && data[0] != 0) { 757 782 struct vbsf_mount_info_new *info = (struct vbsf_mount_info_new *)data; … … 763 788 } 764 789 } 790 # endif 765 791 766 792 /* '.' and '..' entries are st_ino == 0 so root is #1 */ … … 856 882 .put_super = vbsf_put_super, 857 883 .statfs = vbsf_statfs, 884 #if RTLNX_VER_MAX(5,1,0) 858 885 .remount_fs = vbsf_remount_fs, 886 #endif 859 887 .show_options = vbsf_show_options 860 888 }; … … 866 894 *********************************************************************************************************************************/ 867 895 868 #if RTLNX_VER_ MIN(2,5,4)896 #if RTLNX_VER_RANGE(2,5,4, 5,1,0) 869 897 870 898 static int vbsf_read_super_26(struct super_block *sb, void *data, int flags) … … 879 907 return err; 880 908 } 881 882 # if RTLNX_VER_MIN(2,6,39) 909 #endif 910 911 #if RTLNX_VER_RANGE(2,6,39, 5,1,0) 883 912 static struct dentry *sf_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) 884 913 { … … 886 915 return mount_nodev(fs_type, flags, data, vbsf_read_super_26); 887 916 } 888 # elif RTLNX_VER_MIN(2,6,18)917 #elif RTLNX_VER_RANGE(2,6,18, 2,6,39) 889 918 static int vbsf_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) 890 919 { … … 892 921 return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26, mnt); 893 922 } 894 # else/* < 2.6.18 */923 #elif RTLNX_VER_MAX(2,6,18) /* < 2.6.18 */ 895 924 static struct super_block *vbsf_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) 896 925 { … … 898 927 return get_sb_nodev(fs_type, flags, data, vbsf_read_super_26); 899 928 } 929 #endif 930 931 #if RTLNX_VER_MAX(2,5,4) /* < 2.5.4 */ 932 933 static struct super_block *vbsf_read_super_24(struct super_block *sb, void *data, int flags) 934 { 935 int err; 936 937 TRACE(); 938 err = vbsf_read_super_aux(sb, data, flags); 939 if (err) { 940 printk(KERN_DEBUG "vbsf_read_super_aux err=%d\n", err); 941 return NULL; 942 } 943 944 return sb; 945 } 946 947 static DECLARE_FSTYPE(g_vboxsf_fs_type, "vboxsf", vbsf_read_super_24, 0); 948 949 #endif /* < 2.5.4 */ 950 951 #if RTLNX_VER_MIN(5,1,0) 952 953 /** 954 * The following section of code uses the Linux filesystem mount API (also 955 * known as the "filesystem context API") to parse string-based mount options. 956 * The API is described here: 957 * https://www.kernel.org/doc/Documentation/filesystems/mount_api.txt 958 */ 959 enum vbsf_cache_modes { 960 VBSF_CACHE_DEFAULT, 961 VBSF_CACHE_NONE, 962 VBSF_CACHE_STRICT, 963 VBSF_CACHE_READ, 964 VBSF_CACHE_RW 965 }; 966 967 static const struct constant_table vbsf_param_cache_mode[] = { 968 { "default", VBSF_CACHE_DEFAULT }, 969 { "none", VBSF_CACHE_NONE }, 970 { "strict", VBSF_CACHE_STRICT }, 971 { "read", VBSF_CACHE_READ }, 972 { "readwrite", VBSF_CACHE_RW }, 973 {} 974 }; 975 976 enum { 977 Opt_iocharset, /* nls_name[] */ 978 Opt_nls, /* alias for iocharset */ 979 Opt_uid, 980 Opt_gid, 981 Opt_ttl, 982 Opt_dmode, 983 Opt_fmode, 984 Opt_dmask, 985 Opt_fmask, 986 Opt_umask, 987 Opt_maxiopages, 988 Opt_dirbuf, 989 Opt_dcachettl, 990 Opt_inodettl, 991 Opt_cachemode, /* enum vbsf_cache_mode */ 992 Opt_tag 993 }; 994 995 # if RTLNX_VER_MAX(5,6,0) 996 static const struct fs_parameter_spec vbsf_fs_specs[] = { 997 # else 998 static const struct fs_parameter_spec vbsf_fs_parameters[] = { 900 999 # endif 901 1000 fsparam_string("iocharset", Opt_iocharset), 1001 fsparam_string("nls", Opt_nls), 1002 fsparam_u32 ("uid", Opt_uid), 1003 fsparam_u32 ("gid", Opt_gid), 1004 fsparam_u32 ("ttl", Opt_ttl), 1005 fsparam_u32oct("dmode", Opt_dmode), 1006 fsparam_u32oct("fmode", Opt_fmode), 1007 fsparam_u32oct("dmask", Opt_dmask), 1008 fsparam_u32oct("fmask", Opt_fmask), 1009 fsparam_u32oct("umask", Opt_umask), 1010 fsparam_u32 ("maxiopages", Opt_maxiopages), 1011 fsparam_u32 ("dirbuf", Opt_dirbuf), 1012 fsparam_u32 ("dcachettl", Opt_dcachettl), 1013 fsparam_u32 ("inodettl", Opt_inodettl), 1014 # if RTLNX_VER_MAX(5,6,0) 1015 fsparam_enum ("cache", Opt_cachemode), 1016 # else 1017 fsparam_enum ("cache", Opt_cachemode, vbsf_param_cache_mode), 1018 # endif 1019 fsparam_string("tag", Opt_tag), 1020 {} 1021 }; 1022 1023 # if RTLNX_VER_MAX(5,6,0) 1024 static const struct fs_parameter_enum vbsf_fs_enums[] = { 1025 { Opt_cachemode, "default", VBSF_CACHE_DEFAULT }, 1026 { Opt_cachemode, "none", VBSF_CACHE_NONE }, 1027 { Opt_cachemode, "strict", VBSF_CACHE_STRICT }, 1028 { Opt_cachemode, "read", VBSF_CACHE_READ }, 1029 { Opt_cachemode, "readwrite", VBSF_CACHE_RW }, 1030 {} 1031 }; 1032 1033 static const struct fs_parameter_description vbsf_fs_parameters = { 1034 .name = "vboxsf", 1035 .specs = vbsf_fs_specs, 1036 .enums = vbsf_fs_enums 1037 }; 1038 # endif 1039 1040 /** 1041 * Parse the (string-based) mount options passed in as -o foo,bar=123,etc. 1042 */ 1043 static int vbsf_parse_param(struct fs_context *fc, struct fs_parameter *param) 1044 { 1045 struct fs_parse_result result; 1046 struct vbsf_mount_info_new *info = fc->fs_private; 1047 int opt; 1048 1049 # if RTLNX_VER_MAX(5,6,0) 1050 opt = fs_parse(fc, &vbsf_fs_parameters, param, &result); 1051 # else 1052 opt = fs_parse(fc, vbsf_fs_parameters, param, &result); 1053 # endif 1054 if (opt < 0) 1055 return opt; 1056 1057 switch (opt) { 1058 case Opt_iocharset: 1059 case Opt_nls: 1060 strlcpy(info->nls_name, param->string, sizeof(info->nls_name)); 1061 break; 1062 case Opt_uid: 1063 info->uid = result.uint_32; 1064 break; 1065 case Opt_gid: 1066 info->gid = result.uint_32; 1067 break; 1068 case Opt_ttl: 1069 info->ttl = result.uint_32; 1070 break; 1071 case Opt_dmode: 1072 if (result.uint_32 & ~0777) 1073 return invalf(fc, "Invalid dmode specified: '%o'", result.uint_32); 1074 info->dmode = result.uint_32; 1075 break; 1076 case Opt_fmode: 1077 if (result.uint_32 & ~0777) 1078 return invalf(fc, "Invalid fmode specified: '%o'", result.uint_32); 1079 info->fmode = result.uint_32; 1080 break; 1081 case Opt_dmask: 1082 if (result.uint_32 & ~07777) 1083 return invalf(fc, "Invalid dmask specified: '%o'", result.uint_32); 1084 info->dmask = result.uint_32; 1085 break; 1086 case Opt_fmask: 1087 if (result.uint_32 & ~07777) 1088 return invalf(fc, "Invalid fmask specified: '%o'", result.uint_32); 1089 info->fmask = result.uint_32; 1090 break; 1091 case Opt_umask: 1092 if (result.uint_32 & ~07777) 1093 return invalf(fc, "Invalid umask specified: '%o'", result.uint_32); 1094 info->dmask = info->fmask = result.uint_32; 1095 break; 1096 case Opt_maxiopages: 1097 info->cMaxIoPages = result.uint_32; 1098 break; 1099 case Opt_dirbuf: 1100 info->cbDirBuf = result.uint_32; 1101 break; 1102 case Opt_dcachettl: 1103 info->msDirCacheTTL = result.uint_32; 1104 break; 1105 case Opt_inodettl: 1106 info->msInodeTTL = result.uint_32; 1107 break; 1108 case Opt_cachemode: 1109 if (result.uint_32 == VBSF_CACHE_DEFAULT || result.uint_32 == VBSF_CACHE_STRICT) 1110 info->enmCacheMode = kVbsfCacheMode_Strict; 1111 else if (result.uint_32 == VBSF_CACHE_NONE) 1112 info->enmCacheMode = kVbsfCacheMode_None; 1113 else if (result.uint_32 == VBSF_CACHE_READ) 1114 info->enmCacheMode = kVbsfCacheMode_Read; 1115 else if (result.uint_32 == VBSF_CACHE_RW) 1116 info->enmCacheMode = kVbsfCacheMode_ReadWrite; 1117 else 1118 printk(KERN_WARNING "vboxsf: cache mode (%u) is out of range, using default instead.\n", result.uint_32); 1119 break; 1120 case Opt_tag: 1121 strlcpy(info->szTag, param->string, sizeof(info->szTag)); 1122 break; 1123 default: 1124 return invalf(fc, "Invalid mount option: '%s'", param->key); 1125 } 1126 1127 return 0; 1128 } 1129 1130 /** 1131 * Parse the mount options provided whether by the mount.vboxsf utility 1132 * which supplies the mount information as a page of data or else as a 1133 * string in the following format: key[=val][,key[=val]]*. 1134 */ 1135 static int vbsf_parse_monolithic(struct fs_context *fc, void *data) 1136 { 1137 struct vbsf_mount_info_new *info = fc->fs_private; 1138 1139 if (data) { 1140 struct vbsf_mount_info_new *mount_opts = 1141 (struct vbsf_mount_info_new *)data; 1142 if (mount_opts->nullchar == '\0' 1143 && mount_opts->signature[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 1144 && mount_opts->signature[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 1145 && mount_opts->signature[2] == VBSF_MOUNT_SIGNATURE_BYTE_2) { 1146 memcpy(info, mount_opts, sizeof(struct vbsf_mount_info_new)); 1147 } else { 1148 /* this will call vbsf_parse_param() */ 1149 return generic_parse_monolithic(fc, data); 1150 } 1151 } 1152 1153 return 0; 1154 } 1155 1156 /** 1157 * Clean up the filesystem-specific part of the filesystem context. 1158 */ 1159 static void vbsf_free_ctx(struct fs_context *fc) 1160 { 1161 struct vbsf_mount_info_new *info = fc->fs_private; 1162 1163 if (info) { 1164 kfree(info); 1165 fc->fs_private = NULL; 1166 } 1167 } 1168 1169 /** 1170 * Create the mountable root and superblock which can then be used later for 1171 * mounting the shared folder. The superblock is populated by 1172 * vbsf_read_super_aux() which also sets up the shared folder mapping and the 1173 * related paperwork in preparation for mounting the shared folder. 1174 */ 1175 static int vbsf_get_tree(struct fs_context *fc) 1176 { 1177 struct vbsf_mount_info_new *info = fc->fs_private; 1178 1179 if (!fc->source) { 1180 SFLOGRELBOTH(("vboxsf: No shared folder specified\n")); 1181 return invalf(fc, "vboxsf: No shared folder specified"); 1182 } 1183 1184 /* fc->source (the shared folder name) is set after vbsf_init_fs_ctx() */ 1185 strlcpy(info->name, fc->source, sizeof(info->name)); 1186 1187 # if RTLNX_VER_MAX(5,3,0) 1188 return vfs_get_super(fc, vfs_get_independent_super, vbsf_read_super_aux); 1189 # else 1190 return get_tree_nodev(fc, vbsf_read_super_aux); 1191 # endif 1192 } 1193 1194 /** 1195 * Reconfigures the superblock based on the mount information stored in the 1196 * filesystem context. Called via '-o remount' (aka mount(2) with MS_REMOUNT) 1197 * and is the equivalent of .fs_remount. 1198 */ 1199 static int vbsf_reconfigure(struct fs_context *fc) 1200 { 1201 struct vbsf_mount_info_new *info = fc->fs_private; 1202 struct super_block *sb = fc->root->d_sb; 1203 1204 return vbsf_remount_fs(sb, info); 1205 } 1206 1207 static const struct fs_context_operations vbsf_context_ops = { 1208 .parse_param = vbsf_parse_param, 1209 .parse_monolithic = vbsf_parse_monolithic, 1210 .free = vbsf_free_ctx, 1211 .get_tree = vbsf_get_tree, 1212 .reconfigure = vbsf_reconfigure 1213 }; 1214 1215 /** 1216 * Set up the filesystem mount context. 1217 */ 1218 static int vbsf_init_fs_context(struct fs_context *fc) 1219 { 1220 struct vbsf_mount_info_new *info = fc->fs_private; 1221 1222 info = kzalloc(sizeof(*info), GFP_KERNEL); 1223 if (!info) { 1224 SFLOGRELBOTH(("vboxsf: Could not allocate memory for mount options\n")); 1225 return -ENOMEM; 1226 } 1227 1228 /* set default values for the mount information structure */ 1229 info->ttl = info->msDirCacheTTL = info->msInodeTTL = -1; 1230 info->dmode = info->fmode = ~0U; 1231 info->enmCacheMode = kVbsfCacheMode_Strict; 1232 info->length = sizeof(struct vbsf_mount_info_new); 1233 1234 fc->fs_private = info; 1235 fc->ops = &vbsf_context_ops; 1236 1237 return 0; 1238 } 1239 #endif /* >= 5.1.0 */ 1240 1241 1242 #if RTLNX_VER_MIN(2,5,4) 902 1243 /** 903 1244 * File system registration structure. … … 906 1247 .owner = THIS_MODULE, 907 1248 .name = "vboxsf", 908 # if RTLNX_VER_MIN(2,6,39) 1249 # if RTLNX_VER_MIN(5,1,0) 1250 .init_fs_context = vbsf_init_fs_context, 1251 # if RTLNX_VER_MAX(5,6,0) 1252 .parameters = &vbsf_fs_parameters, 1253 # else 1254 .parameters = vbsf_fs_parameters, 1255 # endif 1256 # elif RTLNX_VER_MIN(2,6,39) 909 1257 .mount = sf_mount, 910 1258 # else … … 913 1261 .kill_sb = kill_anon_super 914 1262 }; 915 916 #else /* < 2.5.4 */ 917 918 static struct super_block *vbsf_read_super_24(struct super_block *sb, void *data, int flags) 919 { 920 int err; 921 922 TRACE(); 923 err = vbsf_read_super_aux(sb, data, flags); 924 if (err) { 925 printk(KERN_DEBUG "vbsf_read_super_aux err=%d\n", err); 926 return NULL; 927 } 928 929 return sb; 930 } 931 932 static DECLARE_FSTYPE(g_vboxsf_fs_type, "vboxsf", vbsf_read_super_24, 0); 933 934 #endif /* < 2.5.4 */ 935 1263 #endif /* >= 2.5.4 */ 936 1264 937 1265
Note:
See TracChangeset
for help on using the changeset viewer.