aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c121
1 files changed, 57 insertions, 64 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2fd28c4df1d4..36a595a63536 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1041,15 +1041,31 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1041 * XXX: as far as I can tell, changing the NFS program number is not 1041 * XXX: as far as I can tell, changing the NFS program number is not
1042 * supported in the NFS client. 1042 * supported in the NFS client.
1043 */ 1043 */
1044static int nfs_validate_mount_data(struct nfs_mount_data **options, 1044static int nfs_validate_mount_data(void *options,
1045 struct nfs_parsed_mount_data *args,
1045 struct nfs_fh *mntfh, 1046 struct nfs_fh *mntfh,
1046 const char *dev_name) 1047 const char *dev_name)
1047{ 1048{
1048 struct nfs_mount_data *data = *options; 1049 struct nfs_mount_data *data = (struct nfs_mount_data *)options;
1049 1050
1050 if (data == NULL) 1051 if (data == NULL)
1051 goto out_no_data; 1052 goto out_no_data;
1052 1053
1054 memset(args, 0, sizeof(*args));
1055 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
1056 args->rsize = NFS_MAX_FILE_IO_SIZE;
1057 args->wsize = NFS_MAX_FILE_IO_SIZE;
1058 args->timeo = 600;
1059 args->retrans = 2;
1060 args->acregmin = 3;
1061 args->acregmax = 60;
1062 args->acdirmin = 30;
1063 args->acdirmax = 60;
1064 args->mount_server.protocol = IPPROTO_UDP;
1065 args->mount_server.program = NFS_MNT_PROGRAM;
1066 args->nfs_server.protocol = IPPROTO_TCP;
1067 args->nfs_server.program = NFS_PROGRAM;
1068
1053 switch (data->version) { 1069 switch (data->version) {
1054 case 1: 1070 case 1:
1055 data->namlen = 0; 1071 data->namlen = 0;
@@ -1078,90 +1094,67 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options,
1078 if (mntfh->size < sizeof(mntfh->data)) 1094 if (mntfh->size < sizeof(mntfh->data))
1079 memset(mntfh->data + mntfh->size, 0, 1095 memset(mntfh->data + mntfh->size, 0,
1080 sizeof(mntfh->data) - mntfh->size); 1096 sizeof(mntfh->data) - mntfh->size);
1097 /*
1098 * Translate to nfs_parsed_mount_data, which nfs_fill_super
1099 * can deal with.
1100 */
1101 args->flags = data->flags;
1102 args->rsize = data->rsize;
1103 args->wsize = data->wsize;
1104 args->flags = data->flags;
1105 args->timeo = data->timeo;
1106 args->retrans = data->retrans;
1107 args->acregmin = data->acregmin;
1108 args->acregmax = data->acregmax;
1109 args->acdirmin = data->acdirmin;
1110 args->acdirmax = data->acdirmax;
1111 args->nfs_server.address = data->addr;
1112 if (!(data->flags & NFS_MOUNT_TCP))
1113 args->nfs_server.protocol = IPPROTO_UDP;
1114 /* N.B. caller will free nfs_server.hostname in all cases */
1115 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
1116 args->namlen = data->namlen;
1117 args->bsize = data->bsize;
1118 args->auth_flavors[0] = data->pseudoflavor;
1081 break; 1119 break;
1082 default: { 1120 default: {
1083 unsigned int len; 1121 unsigned int len;
1084 char *c; 1122 char *c;
1085 int status; 1123 int status;
1086 struct nfs_parsed_mount_data args = {
1087 .flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP),
1088 .rsize = NFS_MAX_FILE_IO_SIZE,
1089 .wsize = NFS_MAX_FILE_IO_SIZE,
1090 .timeo = 600,
1091 .retrans = 2,
1092 .acregmin = 3,
1093 .acregmax = 60,
1094 .acdirmin = 30,
1095 .acdirmax = 60,
1096 .mount_server.protocol = IPPROTO_UDP,
1097 .mount_server.program = NFS_MNT_PROGRAM,
1098 .nfs_server.protocol = IPPROTO_TCP,
1099 .nfs_server.program = NFS_PROGRAM,
1100 };
1101 1124
1102 if (nfs_parse_mount_options((char *) *options, &args) == 0) 1125 if (nfs_parse_mount_options((char *)options, args) == 0)
1103 return -EINVAL; 1126 return -EINVAL;
1104 1127
1105 data = kzalloc(sizeof(*data), GFP_KERNEL);
1106 if (data == NULL)
1107 return -ENOMEM;
1108
1109 /*
1110 * NB: after this point, caller will free "data"
1111 * if we return an error
1112 */
1113 *options = data;
1114
1115 c = strchr(dev_name, ':'); 1128 c = strchr(dev_name, ':');
1116 if (c == NULL) 1129 if (c == NULL)
1117 return -EINVAL; 1130 return -EINVAL;
1118 len = c - dev_name; 1131 len = c - dev_name;
1119 if (len > sizeof(data->hostname)) 1132 /* N.B. caller will free nfs_server.hostname in all cases */
1120 return -ENAMETOOLONG; 1133 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
1121 strncpy(data->hostname, dev_name, len);
1122 args.nfs_server.hostname = data->hostname;
1123 1134
1124 c++; 1135 c++;
1125 if (strlen(c) > NFS_MAXPATHLEN) 1136 if (strlen(c) > NFS_MAXPATHLEN)
1126 return -ENAMETOOLONG; 1137 return -ENAMETOOLONG;
1127 args.nfs_server.export_path = c; 1138 args->nfs_server.export_path = c;
1128 1139
1129 status = nfs_try_mount(&args, mntfh); 1140 status = nfs_try_mount(args, mntfh);
1130 if (status) 1141 if (status)
1131 return status; 1142 return status;
1132 1143
1133 /*
1134 * Translate to nfs_mount_data, which nfs_fill_super
1135 * can deal with.
1136 */
1137 data->version = 6;
1138 data->flags = args.flags;
1139 data->rsize = args.rsize;
1140 data->wsize = args.wsize;
1141 data->timeo = args.timeo;
1142 data->retrans = args.retrans;
1143 data->acregmin = args.acregmin;
1144 data->acregmax = args.acregmax;
1145 data->acdirmin = args.acdirmin;
1146 data->acdirmax = args.acdirmax;
1147 data->addr = args.nfs_server.address;
1148 data->namlen = args.namlen;
1149 data->bsize = args.bsize;
1150 data->pseudoflavor = args.auth_flavors[0];
1151
1152 break; 1144 break;
1153 } 1145 }
1154 } 1146 }
1155 1147
1156 if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) 1148 if (!(args->flags & NFS_MOUNT_SECFLAVOUR))
1157 data->pseudoflavor = RPC_AUTH_UNIX; 1149 args->auth_flavors[0] = RPC_AUTH_UNIX;
1158 1150
1159#ifndef CONFIG_NFS_V3 1151#ifndef CONFIG_NFS_V3
1160 if (data->flags & NFS_MOUNT_VER3) 1152 if (args->flags & NFS_MOUNT_VER3)
1161 goto out_v3_not_compiled; 1153 goto out_v3_not_compiled;
1162#endif /* !CONFIG_NFS_V3 */ 1154#endif /* !CONFIG_NFS_V3 */
1163 1155
1164 if (!nfs_verify_server_address((struct sockaddr *) &data->addr)) 1156 if (!nfs_verify_server_address((struct sockaddr *)
1157 &args->nfs_server.address))
1165 goto out_no_address; 1158 goto out_no_address;
1166 1159
1167 return 0; 1160 return 0;
@@ -1220,7 +1213,8 @@ static inline void nfs_initialise_sb(struct super_block *sb)
1220/* 1213/*
1221 * Finish setting up an NFS2/3 superblock 1214 * Finish setting up an NFS2/3 superblock
1222 */ 1215 */
1223static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data) 1216static void nfs_fill_super(struct super_block *sb,
1217 struct nfs_parsed_mount_data *data)
1224{ 1218{
1225 struct nfs_server *server = NFS_SB(sb); 1219 struct nfs_server *server = NFS_SB(sb);
1226 1220
@@ -1341,7 +1335,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1341 struct nfs_server *server = NULL; 1335 struct nfs_server *server = NULL;
1342 struct super_block *s; 1336 struct super_block *s;
1343 struct nfs_fh mntfh; 1337 struct nfs_fh mntfh;
1344 struct nfs_mount_data *data = raw_data; 1338 struct nfs_parsed_mount_data data;
1345 struct dentry *mntroot; 1339 struct dentry *mntroot;
1346 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1340 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1347 struct nfs_sb_mountdata sb_mntdata = { 1341 struct nfs_sb_mountdata sb_mntdata = {
@@ -1350,12 +1344,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1350 int error; 1344 int error;
1351 1345
1352 /* Validate the mount data */ 1346 /* Validate the mount data */
1353 error = nfs_validate_mount_data(&data, &mntfh, dev_name); 1347 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
1354 if (error < 0) 1348 if (error < 0)
1355 goto out; 1349 goto out;
1356 1350
1357 /* Get a volume representation */ 1351 /* Get a volume representation */
1358 server = nfs_create_server(data, &mntfh); 1352 server = nfs_create_server(&data, &mntfh);
1359 if (IS_ERR(server)) { 1353 if (IS_ERR(server)) {
1360 error = PTR_ERR(server); 1354 error = PTR_ERR(server);
1361 goto out; 1355 goto out;
@@ -1379,7 +1373,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1379 1373
1380 if (!s->s_root) { 1374 if (!s->s_root) {
1381 /* initial superblock/root creation */ 1375 /* initial superblock/root creation */
1382 nfs_fill_super(s, data); 1376 nfs_fill_super(s, &data);
1383 } 1377 }
1384 1378
1385 mntroot = nfs_get_root(s, &mntfh); 1379 mntroot = nfs_get_root(s, &mntfh);
@@ -1394,8 +1388,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1394 error = 0; 1388 error = 0;
1395 1389
1396out: 1390out:
1397 if (data != raw_data) 1391 kfree(data.nfs_server.hostname);
1398 kfree(data);
1399 return error; 1392 return error;
1400 1393
1401out_err_nosb: 1394out_err_nosb: