aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author\"Talpey, Thomas\ <Thomas.Talpey@netapp.com>2007-09-10 13:43:56 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-09 17:17:26 -0400
commit2283f8d6ed21ea2221df4cc329314b93f35351b0 (patch)
treedbf8b87e45b4fa76d50c0fd7ec0b3d4f1afd94ca
parent6b18eaa0821a559c5e2b7ed4b90f8aca5a8e6228 (diff)
NFS: use in-kernel mount argument structure for nfsv[23] mounts
The user-visible nfs_mount_data does not contain sufficient data to describe new mount options, and also is now a legacy structure. Replace it with the internal nfs_parsed_mount_data for nfsv[23] in-kernel use. Signed-off-by: Tom Talpey <tmt@netapp.com> Acked-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/client.c18
-rw-r--r--fs/nfs/internal.h6
-rw-r--r--fs/nfs/super.c121
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 */
504static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data) 504static 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 */
541static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data) 541static 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 */
763struct nfs_server *nfs_create_server(const struct nfs_mount_data *data, 765struct 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
7struct nfs_string; 7struct nfs_string;
8struct nfs_mount_data;
9struct nfs4_mount_data; 8struct 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
66extern void nfs_put_client(struct nfs_client *); 65extern void nfs_put_client(struct nfs_client *);
67extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); 66extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
68extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *, 67extern struct nfs_server *nfs_create_server(
69 struct nfs_fh *); 68 const struct nfs_parsed_mount_data *,
69 struct nfs_fh *);
70extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, 70extern 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 */
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: