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