summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-07-01 12:13:59 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:48 -0400
commit8007122520f0a3599bdc4df47358a5d83b2574aa (patch)
treed2d0def406e081ac32f487b54d2ad347f4f28e81
parent136d558ce766967fe3cbf54c3351aba261b5d53b (diff)
downloadlinux-8007122520f0a3599bdc4df47358a5d83b2574aa.tar.gz
linux-8007122520f0a3599bdc4df47358a5d83b2574aa.tar.bz2
linux-8007122520f0a3599bdc4df47358a5d83b2574aa.zip
NFS: Add support for mounting NFSv4 file systems with string options
Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/super.c91
-rw-r--r--include/linux/nfs4_mount.h2
2 files changed, 85 insertions, 8 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 757aa3b7e64b..064e69d2fdde 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1541,8 +1541,90 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
*ip_addr = c;
break;
- default:
- goto out_bad_version;
+ default: {
+ unsigned int len;
+ struct nfs_parsed_mount_data args = {
+ .rsize = NFS_MAX_FILE_IO_SIZE,
+ .wsize = NFS_MAX_FILE_IO_SIZE,
+ .timeo = 600,
+ .retrans = 2,
+ .acregmin = 3,
+ .acregmax = 60,
+ .acdirmin = 30,
+ .acdirmax = 60,
+ .nfs_server.protocol = IPPROTO_TCP,
+ };
+
+ if (nfs_parse_mount_options((char *) *options, &args) == 0)
+ return -EINVAL;
+
+ if (!nfs_verify_server_address((struct sockaddr *)
+ &args.nfs_server.address))
+ return -EINVAL;
+ *addr = args.nfs_server.address;
+
+ switch (args.auth_flavor_len) {
+ case 0:
+ *authflavour = RPC_AUTH_UNIX;
+ break;
+ case 1:
+ *authflavour = (rpc_authflavor_t) args.auth_flavors[0];
+ break;
+ default:
+ goto out_inval_auth;
+ }
+
+ /*
+ * Translate to nfs4_mount_data, which nfs4_fill_super
+ * can deal with.
+ */
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+ *options = data;
+
+ data->version = 1;
+ data->flags = args.flags & NFS4_MOUNT_FLAGMASK;
+ data->rsize = args.rsize;
+ data->wsize = args.wsize;
+ data->timeo = args.timeo;
+ data->retrans = args.retrans;
+ data->acregmin = args.acregmin;
+ data->acregmax = args.acregmax;
+ data->acdirmin = args.acdirmin;
+ data->acdirmax = args.acdirmax;
+ data->proto = args.nfs_server.protocol;
+
+ /*
+ * Split "dev_name" into "hostname:mntpath".
+ */
+ c = strchr(dev_name, ':');
+ if (c == NULL)
+ return -EINVAL;
+ /* while calculating len, pretend ':' is '\0' */
+ len = c - dev_name;
+ if (len > NFS4_MAXNAMLEN)
+ return -EINVAL;
+ *hostname = kzalloc(len, GFP_KERNEL);
+ if (*hostname == NULL)
+ return -ENOMEM;
+ strncpy(*hostname, dev_name, len - 1);
+
+ c++; /* step over the ':' */
+ len = strlen(c);
+ if (len > NFS4_MAXPATHLEN)
+ return -EINVAL;
+ *mntpath = kzalloc(len + 1, GFP_KERNEL);
+ if (*mntpath == NULL)
+ return -ENOMEM;
+ strncpy(*mntpath, c, len);
+
+ dprintk("MNTPATH: %s\n", *mntpath);
+
+ *ip_addr = args.client_address;
+
+ break;
+ }
}
return 0;
@@ -1559,11 +1641,6 @@ out_inval_auth:
out_no_address:
dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
return -EINVAL;
-
-out_bad_version:
- dfprintk(MOUNT, "NFS4: bad nfs_mount_data version %d\n",
- data->version);
- return -EINVAL;
}
/*
diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h
index 26b4c83f831d..d8d7480e5a47 100644
--- a/include/linux/nfs4_mount.h
+++ b/include/linux/nfs4_mount.h
@@ -65,6 +65,6 @@ struct nfs4_mount_data {
#define NFS4_MOUNT_NOCTO 0x0010 /* 1 */
#define NFS4_MOUNT_NOAC 0x0020 /* 1 */
#define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */
-#define NFS4_MOUNT_FLAGMASK 0xFFFF
+#define NFS4_MOUNT_FLAGMASK 0x1033
#endif