[PATCH 13/13] NFS: Integrate support for processing nfs4 mount options in fs/nfs/super.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Finally, hook in the new mount option parsing logic.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---

 fs/nfs/super.c |   87 ++++++++++++--------------------------------------------
 1 files changed, 19 insertions(+), 68 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index e0acd08..222bb49 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -13,6 +13,8 @@
  *
  *  Split from inode.c by David Howells <dhowells@xxxxxxxxxx>
  *
+ *  In-kernel mount option parsing by Chuck Lever <chuck.lever@xxxxxxxxxx>
+ *
  * - superblocks are indexed on server only - all inodes, dentries, etc. associated with a
  *   particular server are held in the same superblock
  * - NFS superblocks can have several effective roots to the dentry tree
@@ -1532,7 +1534,6 @@ static int nfs4_parse_options(char *raw, struct nfs4_mount_args *mnt)
 			if (len > 80)
 				goto out_clntaddr_long;
 			match_strcpy(mnt->clientaddr, args);
-			mnt->nmd.client_addr.data = mnt->clientaddr;
 			mnt->nmd.client_addr.len = len;
 			break;
 		}
@@ -1605,10 +1606,8 @@ static struct nfs4_mount_data *nfs4_convert_mount_opts(const char *options)
 	args->nmd.acdirmax = 60;
 
 	args->nmd.auth_flavourlen = 0;
-	args->nmd.auth_flavours = &args->authflavor;
 
 	args->nmd.host_addrlen = sizeof(args->addr);
-	args->nmd.host_addr = (struct sockaddr *) &args->addr;
 
 	args->addr.sin_port = htons(NFS_PORT);
 
@@ -1652,6 +1651,7 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
 				    char *ip_addr)
 {
 	struct nfs4_mount_data *data = *options;
+	struct nfs4_mount_args *args;
 	char *c;
 	unsigned len;
 
@@ -1707,25 +1707,26 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
 		if (IS_ERR(data))
 			return PTR_ERR(data);
 		*options = data;
+		args = (struct nfs4_mount_args *) data;
 
-		memcpy(addr, data->host_addr, sizeof(*addr));
-		if (!nfs_verify_server_address((struct sockaddr *) addr,
+		if (!nfs_verify_server_address((struct sockaddr *) &args->addr,
 						data->host_addrlen))
 			return -EINVAL;
+		memcpy(addr, &args->addr, sizeof(*addr));
 
 		switch (data->auth_flavourlen) {
 		case 0:
 			*authflavour = RPC_AUTH_UNIX;
 			break;
 		case 1:
-			*authflavour = (rpc_authflavor_t) data->auth_flavours[0];
+			*authflavour = (rpc_authflavor_t) args->authflavor;
 			break;
 		default:
 			goto out_inval_auth;
 		}
 
 		memset(ip_addr, '\0', data->client_addr.len + 1);
-		strncpy(ip_addr, data->client_addr.data, data->client_addr.len);
+		strncpy(ip_addr, args->clientaddr, data->client_addr.len);
 
 		/*
 		 * Split "dev_name" into "hostname:mntpath".
@@ -1804,67 +1805,17 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
 	struct nfs_fh mntfh;
 	struct dentry *mntroot;
 	char *mntpath = NULL, *hostname = NULL, ip_addr[16];
-	void *p;
 	int error;
 
-	if (data == NULL) {
-		dprintk("%s: missing data argument\n", __FUNCTION__);
-		return -EINVAL;
-	}
-	if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
-		dprintk("%s: bad mount version\n", __FUNCTION__);
-		return -EINVAL;
-	}
-
-	/* We now require that the mount process passes the remote address */
-	if (data->host_addrlen != sizeof(addr))
-		return -EINVAL;
-
-	if (copy_from_user(&addr, data->host_addr, sizeof(addr)))
-		return -EFAULT;
-
-	if (!nfs_verify_server_address((struct sockaddr *) &addr,
-					data->host_addrlen))
-		return -EINVAL;
-
-	/* RFC3530: The default port for NFS is 2049 */
-	if (addr.sin_port == 0)
-		addr.sin_port = htons(NFS_PORT);
-
-	/* Grab the authentication type */
-	authflavour = RPC_AUTH_UNIX;
-	if (data->auth_flavourlen != 0) {
-		if (data->auth_flavourlen != 1) {
-			dprintk("%s: Invalid number of RPC auth flavours %d.\n",
-					__FUNCTION__, data->auth_flavourlen);
-			error = -EINVAL;
-			goto out_err_noserver;
-		}
-
-		if (copy_from_user(&authflavour, data->auth_flavours,
-				   sizeof(authflavour))) {
-			error = -EFAULT;
-			goto out_err_noserver;
-		}
+ 	error = nfs4_validate_mount_data(&data, dev_name, &addr,
+ 					 &authflavour, &hostname,
+ 					 &mntpath, ip_addr);
+	if (error < 0) {
+		if (data != raw_data)
+			kfree(data);
+		return error;
 	}
 
-	p = nfs_copy_user_string(NULL, &data->hostname, 256);
-	if (IS_ERR(p))
-		goto out_err;
-	hostname = p;
-
-	p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
-	if (IS_ERR(p))
-		goto out_err;
-	mntpath = p;
-
-	dprintk("MNTPATH: %s\n", mntpath);
-
-	p = nfs_copy_user_string(ip_addr, &data->client_addr,
-				 sizeof(ip_addr) - 1);
-	if (IS_ERR(p))
-		goto out_err;
-
 	/* Get a volume representation */
 	server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
 				    authflavour, &mntfh);
@@ -1902,17 +1853,17 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
 	mnt->mnt_root = mntroot;
 	kfree(mntpath);
 	kfree(hostname);
+	if (data != raw_data)
+		kfree(data);
 	return 0;
 
-out_err:
-	error = PTR_ERR(p);
-	goto out_err_noserver;
-
 out_free:
 	nfs_free_server(server);
 out_err_noserver:
 	kfree(mntpath);
 	kfree(hostname);
+	if (data != raw_data)
+		kfree(data);
 	return error;
 
 error_splat_super:

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux