提交 91ea40b9 编写于 作者: \ \"Talpey, Thomas\ 提交者: Trond Myklebust

NFS: use in-kernel mount argument structure for nfsv4 mounts

The user-visible nfs4_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 nfsv4 in-kernel use.
Signed-off-by: NTom Talpey <tmt@netapp.com>
Acked-by: NChuck Lever <chuck.lever@oracle.com>
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 2283f8d6
...@@ -908,7 +908,7 @@ static int nfs4_set_client(struct nfs_server *server, ...@@ -908,7 +908,7 @@ static int nfs4_set_client(struct nfs_server *server,
* Create a version 4 volume record * Create a version 4 volume record
*/ */
static int nfs4_init_server(struct nfs_server *server, static int nfs4_init_server(struct nfs_server *server,
const struct nfs4_mount_data *data, rpc_authflavor_t authflavour) const struct nfs_parsed_mount_data *data)
{ {
int error; int error;
...@@ -928,7 +928,7 @@ static int nfs4_init_server(struct nfs_server *server, ...@@ -928,7 +928,7 @@ static int nfs4_init_server(struct nfs_server *server,
server->acdirmin = data->acdirmin * HZ; server->acdirmin = data->acdirmin * HZ;
server->acdirmax = data->acdirmax * HZ; server->acdirmax = data->acdirmax * HZ;
error = nfs_init_server_rpcclient(server, authflavour); error = nfs_init_server_rpcclient(server, data->auth_flavors[0]);
/* Done */ /* Done */
dprintk("<-- nfs4_init_server() = %d\n", error); dprintk("<-- nfs4_init_server() = %d\n", error);
...@@ -939,12 +939,7 @@ static int nfs4_init_server(struct nfs_server *server, ...@@ -939,12 +939,7 @@ static int nfs4_init_server(struct nfs_server *server,
* Create a version 4 volume record * Create a version 4 volume record
* - keyed on server and FSID * - keyed on server and FSID
*/ */
struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
const char *hostname,
const struct sockaddr_in *addr,
const char *mntpath,
const char *ip_addr,
rpc_authflavor_t authflavour,
struct nfs_fh *mntfh) struct nfs_fh *mntfh)
{ {
struct nfs_fattr fattr; struct nfs_fattr fattr;
...@@ -958,13 +953,18 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, ...@@ -958,13 +953,18 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
/* Get a client record */ /* Get a client record */
error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour, error = nfs4_set_client(server,
data->proto, data->timeo, data->retrans); data->nfs_server.hostname,
&data->nfs_server.address,
data->client_address,
data->auth_flavors[0],
data->nfs_server.protocol,
data->timeo, data->retrans);
if (error < 0) if (error < 0)
goto error; goto error;
/* set up the general RPC client */ /* set up the general RPC client */
error = nfs4_init_server(server, data, authflavour); error = nfs4_init_server(server, data);
if (error < 0) if (error < 0)
goto error; goto error;
...@@ -973,7 +973,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, ...@@ -973,7 +973,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
/* Probe the root fh to retrieve its FSID */ /* Probe the root fh to retrieve its FSID */
error = nfs4_path_walk(server, mntfh, mntpath); error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
if (error < 0) if (error < 0)
goto error; goto error;
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <linux/mount.h> #include <linux/mount.h>
struct nfs_string; struct nfs_string;
struct nfs4_mount_data;
/* Maximum number of readahead requests /* Maximum number of readahead requests
* FIXME: this should really be a sysctl so that users may tune it to suit * FIXME: this should really be a sysctl so that users may tune it to suit
...@@ -67,13 +66,9 @@ extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); ...@@ -67,13 +66,9 @@ extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
extern struct nfs_server *nfs_create_server( extern struct nfs_server *nfs_create_server(
const struct nfs_parsed_mount_data *, const struct nfs_parsed_mount_data *,
struct nfs_fh *); struct nfs_fh *);
extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, extern struct nfs_server *nfs4_create_server(
const char *, const struct nfs_parsed_mount_data *,
const struct sockaddr_in *, struct nfs_fh *);
const char *,
const char *,
rpc_authflavor_t,
struct nfs_fh *);
extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
struct nfs_fh *); struct nfs_fh *);
extern void nfs_free_server(struct nfs_server *server); extern void nfs_free_server(struct nfs_server *server);
......
...@@ -1514,38 +1514,49 @@ static void nfs4_fill_super(struct super_block *sb) ...@@ -1514,38 +1514,49 @@ static void nfs4_fill_super(struct super_block *sb)
/* /*
* Validate NFSv4 mount options * Validate NFSv4 mount options
*/ */
static int nfs4_validate_mount_data(struct nfs4_mount_data **options, static int nfs4_validate_mount_data(void *options,
const char *dev_name, struct nfs_parsed_mount_data *args,
struct sockaddr_in *addr, const char *dev_name)
rpc_authflavor_t *authflavour,
char **hostname,
char **mntpath,
char **ip_addr)
{ {
struct nfs4_mount_data *data = *options; struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
char *c; char *c;
if (data == NULL) if (data == NULL)
goto out_no_data; 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) { switch (data->version) {
case 1: case 1:
if (data->host_addrlen != sizeof(*addr)) if (data->host_addrlen != sizeof(args->nfs_server.address))
goto out_no_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; return -EFAULT;
if (addr->sin_port == 0) if (args->nfs_server.address.sin_port == 0)
addr->sin_port = htons(NFS_PORT); args->nfs_server.address.sin_port = htons(NFS_PORT);
if (!nfs_verify_server_address((struct sockaddr *) addr)) if (!nfs_verify_server_address((struct sockaddr *)
&args->nfs_server.address))
goto out_no_address; goto out_no_address;
switch (data->auth_flavourlen) { switch (data->auth_flavourlen) {
case 0: case 0:
*authflavour = RPC_AUTH_UNIX; args->auth_flavors[0] = RPC_AUTH_UNIX;
break; break;
case 1: case 1:
if (copy_from_user(authflavour, data->auth_flavours, if (copy_from_user(args->auth_flavors,
sizeof(*authflavour))) data->auth_flavours,
sizeof(args->auth_flavors)))
return -EFAULT; return -EFAULT;
break; break;
default: default:
...@@ -1555,74 +1566,56 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options, ...@@ -1555,74 +1566,56 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
if (IS_ERR(c)) if (IS_ERR(c))
return PTR_ERR(c); return PTR_ERR(c);
*hostname = c; args->nfs_server.hostname = c;
c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
if (IS_ERR(c)) if (IS_ERR(c))
return PTR_ERR(c); return PTR_ERR(c);
*mntpath = c; args->nfs_server.export_path = c;
dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *mntpath); dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
c = strndup_user(data->client_addr.data, 16); c = strndup_user(data->client_addr.data, 16);
if (IS_ERR(c)) if (IS_ERR(c))
return PTR_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; break;
default: { default: {
unsigned int len; unsigned int len;
struct nfs_parsed_mount_data args = {
.rsize = NFS_MAX_FILE_IO_SIZE, if (nfs_parse_mount_options((char *)options, args) == 0)
.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; return -EINVAL;
if (!nfs_verify_server_address((struct sockaddr *) if (!nfs_verify_server_address((struct sockaddr *)
&args.nfs_server.address)) &args->nfs_server.address))
return -EINVAL; return -EINVAL;
*addr = args.nfs_server.address;
switch (args.auth_flavor_len) { switch (args->auth_flavor_len) {
case 0: case 0:
*authflavour = RPC_AUTH_UNIX; args->auth_flavors[0] = RPC_AUTH_UNIX;
break; break;
case 1: case 1:
*authflavour = (rpc_authflavor_t) args.auth_flavors[0];
break; break;
default: default:
goto out_inval_auth; 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". * Split "dev_name" into "hostname:mntpath".
*/ */
...@@ -1633,27 +1626,25 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options, ...@@ -1633,27 +1626,25 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
len = c - dev_name; len = c - dev_name;
if (len > NFS4_MAXNAMLEN) if (len > NFS4_MAXNAMLEN)
return -ENAMETOOLONG; return -ENAMETOOLONG;
*hostname = kzalloc(len, GFP_KERNEL); args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);
if (*hostname == NULL) if (args->nfs_server.hostname == NULL)
return -ENOMEM; return -ENOMEM;
strncpy(*hostname, dev_name, len - 1); strncpy(args->nfs_server.hostname, dev_name, len - 1);
c++; /* step over the ':' */ c++; /* step over the ':' */
len = strlen(c); len = strlen(c);
if (len > NFS4_MAXPATHLEN) if (len > NFS4_MAXPATHLEN)
return -ENAMETOOLONG; return -ENAMETOOLONG;
*mntpath = kzalloc(len + 1, GFP_KERNEL); args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);
if (*mntpath == NULL) if (args->nfs_server.export_path == NULL)
return -ENOMEM; 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; goto out_no_client_address;
*ip_addr = args.client_address;
break; break;
} }
} }
...@@ -1684,14 +1675,11 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options, ...@@ -1684,14 +1675,11 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
static int nfs4_get_sb(struct file_system_type *fs_type, static int nfs4_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 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 super_block *s;
struct nfs_server *server; struct nfs_server *server;
struct sockaddr_in addr;
rpc_authflavor_t authflavour;
struct nfs_fh mntfh; struct nfs_fh mntfh;
struct dentry *mntroot; struct dentry *mntroot;
char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL;
int (*compare_super)(struct super_block *, void *) = nfs_compare_super; int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
struct nfs_sb_mountdata sb_mntdata = { struct nfs_sb_mountdata sb_mntdata = {
.mntflags = flags, .mntflags = flags,
...@@ -1699,14 +1687,12 @@ static int nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1699,14 +1687,12 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
int error; int error;
/* Validate the mount data */ /* Validate the mount data */
error = nfs4_validate_mount_data(&data, dev_name, &addr, &authflavour, error = nfs4_validate_mount_data(raw_data, &data, dev_name);
&hostname, &mntpath, &ip_addr);
if (error < 0) if (error < 0)
goto out; goto out;
/* Get a volume representation */ /* Get a volume representation */
server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr, server = nfs4_create_server(&data, &mntfh);
authflavour, &mntfh);
if (IS_ERR(server)) { if (IS_ERR(server)) {
error = PTR_ERR(server); error = PTR_ERR(server);
goto out; goto out;
...@@ -1745,9 +1731,9 @@ static int nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1745,9 +1731,9 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
error = 0; error = 0;
out: out:
kfree(ip_addr); kfree(data.client_address);
kfree(mntpath); kfree(data.nfs_server.export_path);
kfree(hostname); kfree(data.nfs_server.hostname);
return error; return error;
out_free: out_free:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册