|
@@ -1514,38 +1514,49 @@ static void nfs4_fill_super(struct super_block *sb)
|
|
|
/*
|
|
|
* Validate NFSv4 mount options
|
|
|
*/
|
|
|
-static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
|
|
|
- const char *dev_name,
|
|
|
- struct sockaddr_in *addr,
|
|
|
- rpc_authflavor_t *authflavour,
|
|
|
- char **hostname,
|
|
|
- char **mntpath,
|
|
|
- char **ip_addr)
|
|
|
+static int nfs4_validate_mount_data(void *options,
|
|
|
+ struct nfs_parsed_mount_data *args,
|
|
|
+ const char *dev_name)
|
|
|
{
|
|
|
- struct nfs4_mount_data *data = *options;
|
|
|
+ struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
|
|
|
char *c;
|
|
|
|
|
|
if (data == NULL)
|
|
|
goto out_no_data;
|
|
|
|
|
|
+ memset(args, 0, sizeof(*args));
|
|
|
+ args->rsize = NFS_MAX_FILE_IO_SIZE;
|
|
|
+ args->wsize = NFS_MAX_FILE_IO_SIZE;
|
|
|
+ args->timeo = 600;
|
|
|
+ args->retrans = 2;
|
|
|
+ args->acregmin = 3;
|
|
|
+ args->acregmax = 60;
|
|
|
+ args->acdirmin = 30;
|
|
|
+ args->acdirmax = 60;
|
|
|
+ args->nfs_server.protocol = IPPROTO_TCP;
|
|
|
+
|
|
|
switch (data->version) {
|
|
|
case 1:
|
|
|
- if (data->host_addrlen != sizeof(*addr))
|
|
|
+ if (data->host_addrlen != sizeof(args->nfs_server.address))
|
|
|
goto out_no_address;
|
|
|
- if (copy_from_user(addr, data->host_addr, sizeof(*addr)))
|
|
|
+ if (copy_from_user(&args->nfs_server.address,
|
|
|
+ data->host_addr,
|
|
|
+ sizeof(&args->nfs_server.address)))
|
|
|
return -EFAULT;
|
|
|
- if (addr->sin_port == 0)
|
|
|
- addr->sin_port = htons(NFS_PORT);
|
|
|
- if (!nfs_verify_server_address((struct sockaddr *) addr))
|
|
|
+ if (args->nfs_server.address.sin_port == 0)
|
|
|
+ args->nfs_server.address.sin_port = htons(NFS_PORT);
|
|
|
+ if (!nfs_verify_server_address((struct sockaddr *)
|
|
|
+ &args->nfs_server.address))
|
|
|
goto out_no_address;
|
|
|
|
|
|
switch (data->auth_flavourlen) {
|
|
|
case 0:
|
|
|
- *authflavour = RPC_AUTH_UNIX;
|
|
|
+ args->auth_flavors[0] = RPC_AUTH_UNIX;
|
|
|
break;
|
|
|
case 1:
|
|
|
- if (copy_from_user(authflavour, data->auth_flavours,
|
|
|
- sizeof(*authflavour)))
|
|
|
+ if (copy_from_user(args->auth_flavors,
|
|
|
+ data->auth_flavours,
|
|
|
+ sizeof(args->auth_flavors)))
|
|
|
return -EFAULT;
|
|
|
break;
|
|
|
default:
|
|
@@ -1555,74 +1566,56 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
|
|
|
c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
|
|
|
if (IS_ERR(c))
|
|
|
return PTR_ERR(c);
|
|
|
- *hostname = c;
|
|
|
+ args->nfs_server.hostname = c;
|
|
|
|
|
|
c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
|
|
|
if (IS_ERR(c))
|
|
|
return PTR_ERR(c);
|
|
|
- *mntpath = c;
|
|
|
- dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *mntpath);
|
|
|
+ args->nfs_server.export_path = c;
|
|
|
+ dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
|
|
|
|
|
|
c = strndup_user(data->client_addr.data, 16);
|
|
|
if (IS_ERR(c))
|
|
|
return PTR_ERR(c);
|
|
|
- *ip_addr = c;
|
|
|
+ args->client_address = c;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Translate to nfs_parsed_mount_data, which nfs4_fill_super
|
|
|
+ * can deal with.
|
|
|
+ */
|
|
|
+
|
|
|
+ args->flags = data->flags & NFS4_MOUNT_FLAGMASK;
|
|
|
+ args->rsize = data->rsize;
|
|
|
+ args->wsize = data->wsize;
|
|
|
+ args->timeo = data->timeo;
|
|
|
+ args->retrans = data->retrans;
|
|
|
+ args->acregmin = data->acregmin;
|
|
|
+ args->acregmax = data->acregmax;
|
|
|
+ args->acdirmin = data->acdirmin;
|
|
|
+ args->acdirmax = data->acdirmax;
|
|
|
+ args->nfs_server.protocol = data->proto;
|
|
|
|
|
|
break;
|
|
|
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)
|
|
|
+
|
|
|
+ if (nfs_parse_mount_options((char *)options, args) == 0)
|
|
|
return -EINVAL;
|
|
|
|
|
|
if (!nfs_verify_server_address((struct sockaddr *)
|
|
|
- &args.nfs_server.address))
|
|
|
+ &args->nfs_server.address))
|
|
|
return -EINVAL;
|
|
|
- *addr = args.nfs_server.address;
|
|
|
|
|
|
- switch (args.auth_flavor_len) {
|
|
|
+ switch (args->auth_flavor_len) {
|
|
|
case 0:
|
|
|
- *authflavour = RPC_AUTH_UNIX;
|
|
|
+ args->auth_flavors[0] = 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".
|
|
|
*/
|
|
@@ -1633,27 +1626,25 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
|
|
|
len = c - dev_name;
|
|
|
if (len > NFS4_MAXNAMLEN)
|
|
|
return -ENAMETOOLONG;
|
|
|
- *hostname = kzalloc(len, GFP_KERNEL);
|
|
|
- if (*hostname == NULL)
|
|
|
+ args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);
|
|
|
+ if (args->nfs_server.hostname == NULL)
|
|
|
return -ENOMEM;
|
|
|
- strncpy(*hostname, dev_name, len - 1);
|
|
|
+ strncpy(args->nfs_server.hostname, dev_name, len - 1);
|
|
|
|
|
|
c++; /* step over the ':' */
|
|
|
len = strlen(c);
|
|
|
if (len > NFS4_MAXPATHLEN)
|
|
|
return -ENAMETOOLONG;
|
|
|
- *mntpath = kzalloc(len + 1, GFP_KERNEL);
|
|
|
- if (*mntpath == NULL)
|
|
|
+ args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);
|
|
|
+ if (args->nfs_server.export_path == NULL)
|
|
|
return -ENOMEM;
|
|
|
- strncpy(*mntpath, c, len);
|
|
|
+ strncpy(args->nfs_server.export_path, c, len);
|
|
|
|
|
|
- dprintk("MNTPATH: %s\n", *mntpath);
|
|
|
+ dprintk("MNTPATH: %s\n", args->nfs_server.export_path);
|
|
|
|
|
|
- if (args.client_address == NULL)
|
|
|
+ if (args->client_address == NULL)
|
|
|
goto out_no_client_address;
|
|
|
|
|
|
- *ip_addr = args.client_address;
|
|
|
-
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -1684,14 +1675,11 @@ out_no_client_address:
|
|
|
static int nfs4_get_sb(struct file_system_type *fs_type,
|
|
|
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
|
|
|
{
|
|
|
- struct nfs4_mount_data *data = raw_data;
|
|
|
+ struct nfs_parsed_mount_data data;
|
|
|
struct super_block *s;
|
|
|
struct nfs_server *server;
|
|
|
- struct sockaddr_in addr;
|
|
|
- rpc_authflavor_t authflavour;
|
|
|
struct nfs_fh mntfh;
|
|
|
struct dentry *mntroot;
|
|
|
- char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL;
|
|
|
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
|
|
|
struct nfs_sb_mountdata sb_mntdata = {
|
|
|
.mntflags = flags,
|
|
@@ -1699,14 +1687,12 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
|
|
|
int error;
|
|
|
|
|
|
/* Validate the mount data */
|
|
|
- error = nfs4_validate_mount_data(&data, dev_name, &addr, &authflavour,
|
|
|
- &hostname, &mntpath, &ip_addr);
|
|
|
+ error = nfs4_validate_mount_data(raw_data, &data, dev_name);
|
|
|
if (error < 0)
|
|
|
goto out;
|
|
|
|
|
|
/* Get a volume representation */
|
|
|
- server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
|
|
|
- authflavour, &mntfh);
|
|
|
+ server = nfs4_create_server(&data, &mntfh);
|
|
|
if (IS_ERR(server)) {
|
|
|
error = PTR_ERR(server);
|
|
|
goto out;
|
|
@@ -1745,9 +1731,9 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
|
|
|
error = 0;
|
|
|
|
|
|
out:
|
|
|
- kfree(ip_addr);
|
|
|
- kfree(mntpath);
|
|
|
- kfree(hostname);
|
|
|
+ kfree(data.client_address);
|
|
|
+ kfree(data.nfs_server.export_path);
|
|
|
+ kfree(data.nfs_server.hostname);
|
|
|
return error;
|
|
|
|
|
|
out_free:
|