diff options
-rw-r--r-- | fs/nfs/client.c | 18 | ||||
-rw-r--r-- | fs/nfs/internal.h | 6 | ||||
-rw-r--r-- | fs/nfs/super.c | 121 |
3 files changed, 70 insertions, 75 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index a204484072f3..f51eabff3cd0 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -501,9 +501,9 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t | |||
501 | /* | 501 | /* |
502 | * Initialise an NFS2 or NFS3 client | 502 | * Initialise an NFS2 or NFS3 client |
503 | */ | 503 | */ |
504 | static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data) | 504 | static int nfs_init_client(struct nfs_client *clp, |
505 | const struct nfs_parsed_mount_data *data) | ||
505 | { | 506 | { |
506 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; | ||
507 | int error; | 507 | int error; |
508 | 508 | ||
509 | if (clp->cl_cons_state == NFS_CS_READY) { | 509 | if (clp->cl_cons_state == NFS_CS_READY) { |
@@ -522,8 +522,8 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data * | |||
522 | * Create a client RPC handle for doing FSSTAT with UNIX auth only | 522 | * Create a client RPC handle for doing FSSTAT with UNIX auth only |
523 | * - RFC 2623, sec 2.3.2 | 523 | * - RFC 2623, sec 2.3.2 |
524 | */ | 524 | */ |
525 | error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans, | 525 | error = nfs_create_rpc_client(clp, data->nfs_server.protocol, |
526 | RPC_AUTH_UNIX, 0); | 526 | data->timeo, data->retrans, RPC_AUTH_UNIX, 0); |
527 | if (error < 0) | 527 | if (error < 0) |
528 | goto error; | 528 | goto error; |
529 | nfs_mark_client_ready(clp, NFS_CS_READY); | 529 | nfs_mark_client_ready(clp, NFS_CS_READY); |
@@ -538,7 +538,8 @@ error: | |||
538 | /* | 538 | /* |
539 | * Create a version 2 or 3 client | 539 | * Create a version 2 or 3 client |
540 | */ | 540 | */ |
541 | static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data) | 541 | static int nfs_init_server(struct nfs_server *server, |
542 | const struct nfs_parsed_mount_data *data) | ||
542 | { | 543 | { |
543 | struct nfs_client *clp; | 544 | struct nfs_client *clp; |
544 | int error, nfsvers = 2; | 545 | int error, nfsvers = 2; |
@@ -551,7 +552,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat | |||
551 | #endif | 552 | #endif |
552 | 553 | ||
553 | /* Allocate or find a client reference we can use */ | 554 | /* Allocate or find a client reference we can use */ |
554 | clp = nfs_get_client(data->hostname, &data->addr, nfsvers); | 555 | clp = nfs_get_client(data->nfs_server.hostname, |
556 | &data->nfs_server.address, nfsvers); | ||
555 | if (IS_ERR(clp)) { | 557 | if (IS_ERR(clp)) { |
556 | dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); | 558 | dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); |
557 | return PTR_ERR(clp); | 559 | return PTR_ERR(clp); |
@@ -581,7 +583,7 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat | |||
581 | if (error < 0) | 583 | if (error < 0) |
582 | goto error; | 584 | goto error; |
583 | 585 | ||
584 | error = nfs_init_server_rpcclient(server, data->pseudoflavor); | 586 | error = nfs_init_server_rpcclient(server, data->auth_flavors[0]); |
585 | if (error < 0) | 587 | if (error < 0) |
586 | goto error; | 588 | goto error; |
587 | 589 | ||
@@ -760,7 +762,7 @@ void nfs_free_server(struct nfs_server *server) | |||
760 | * Create a version 2 or 3 volume record | 762 | * Create a version 2 or 3 volume record |
761 | * - keyed on server and FSID | 763 | * - keyed on server and FSID |
762 | */ | 764 | */ |
763 | struct nfs_server *nfs_create_server(const struct nfs_mount_data *data, | 765 | struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, |
764 | struct nfs_fh *mntfh) | 766 | struct nfs_fh *mntfh) |
765 | { | 767 | { |
766 | struct nfs_server *server; | 768 | struct nfs_server *server; |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 9c2d0fbb9f89..d28e54e4dee4 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/mount.h> | 5 | #include <linux/mount.h> |
6 | 6 | ||
7 | struct nfs_string; | 7 | struct nfs_string; |
8 | struct nfs_mount_data; | ||
9 | struct nfs4_mount_data; | 8 | struct nfs4_mount_data; |
10 | 9 | ||
11 | /* Maximum number of readahead requests | 10 | /* Maximum number of readahead requests |
@@ -65,8 +64,9 @@ extern struct rpc_program nfs_program; | |||
65 | 64 | ||
66 | extern void nfs_put_client(struct nfs_client *); | 65 | extern void nfs_put_client(struct nfs_client *); |
67 | extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); | 66 | extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); |
68 | extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *, | 67 | extern struct nfs_server *nfs_create_server( |
69 | struct nfs_fh *); | 68 | const struct nfs_parsed_mount_data *, |
69 | struct nfs_fh *); | ||
70 | extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, | 70 | extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, |
71 | const char *, | 71 | const char *, |
72 | const struct sockaddr_in *, | 72 | const struct sockaddr_in *, |
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 | */ |
1044 | static int nfs_validate_mount_data(struct nfs_mount_data **options, | 1044 | static 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 | */ |
1223 | static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data) | 1216 | static 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 | ||
1396 | out: | 1390 | out: |
1397 | if (data != raw_data) | 1391 | kfree(data.nfs_server.hostname); |
1398 | kfree(data); | ||
1399 | return error; | 1392 | return error; |
1400 | 1393 | ||
1401 | out_err_nosb: | 1394 | out_err_nosb: |