Commit 2283f8d6 authored by Talpey, Thomas's avatar Talpey, Thomas Committed by Trond Myklebust

NFS: use in-kernel mount argument structure for nfsv[23] mounts

The user-visible nfs_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 nfsv[23] in-kernel use.
Signed-off-by: default avatarTom Talpey <tmt@netapp.com>
Acked-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 6b18eaa0
...@@ -501,9 +501,9 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t ...@@ -501,9 +501,9 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t
/* /*
* Initialise an NFS2 or NFS3 client * Initialise an NFS2 or NFS3 client
*/ */
static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data) static int nfs_init_client(struct nfs_client *clp,
const struct nfs_parsed_mount_data *data)
{ {
int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
int error; int error;
if (clp->cl_cons_state == NFS_CS_READY) { if (clp->cl_cons_state == NFS_CS_READY) {
...@@ -522,8 +522,8 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data * ...@@ -522,8 +522,8 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *
* Create a client RPC handle for doing FSSTAT with UNIX auth only * Create a client RPC handle for doing FSSTAT with UNIX auth only
* - RFC 2623, sec 2.3.2 * - RFC 2623, sec 2.3.2
*/ */
error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans, error = nfs_create_rpc_client(clp, data->nfs_server.protocol,
RPC_AUTH_UNIX, 0); data->timeo, data->retrans, RPC_AUTH_UNIX, 0);
if (error < 0) if (error < 0)
goto error; goto error;
nfs_mark_client_ready(clp, NFS_CS_READY); nfs_mark_client_ready(clp, NFS_CS_READY);
...@@ -538,7 +538,8 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data * ...@@ -538,7 +538,8 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *
/* /*
* Create a version 2 or 3 client * Create a version 2 or 3 client
*/ */
static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data) static int nfs_init_server(struct nfs_server *server,
const struct nfs_parsed_mount_data *data)
{ {
struct nfs_client *clp; struct nfs_client *clp;
int error, nfsvers = 2; int error, nfsvers = 2;
...@@ -551,7 +552,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat ...@@ -551,7 +552,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
#endif #endif
/* Allocate or find a client reference we can use */ /* Allocate or find a client reference we can use */
clp = nfs_get_client(data->hostname, &data->addr, nfsvers); clp = nfs_get_client(data->nfs_server.hostname,
&data->nfs_server.address, nfsvers);
if (IS_ERR(clp)) { if (IS_ERR(clp)) {
dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
return PTR_ERR(clp); return PTR_ERR(clp);
...@@ -581,7 +583,7 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat ...@@ -581,7 +583,7 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
if (error < 0) if (error < 0)
goto error; goto error;
error = nfs_init_server_rpcclient(server, data->pseudoflavor); error = nfs_init_server_rpcclient(server, data->auth_flavors[0]);
if (error < 0) if (error < 0)
goto error; goto error;
...@@ -760,7 +762,7 @@ void nfs_free_server(struct nfs_server *server) ...@@ -760,7 +762,7 @@ void nfs_free_server(struct nfs_server *server)
* Create a version 2 or 3 volume record * Create a version 2 or 3 volume record
* - keyed on server and FSID * - keyed on server and FSID
*/ */
struct nfs_server *nfs_create_server(const struct nfs_mount_data *data, struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
struct nfs_fh *mntfh) struct nfs_fh *mntfh)
{ {
struct nfs_server *server; struct nfs_server *server;
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <linux/mount.h> #include <linux/mount.h>
struct nfs_string; struct nfs_string;
struct nfs_mount_data;
struct nfs4_mount_data; struct nfs4_mount_data;
/* Maximum number of readahead requests /* Maximum number of readahead requests
...@@ -65,7 +64,8 @@ extern struct rpc_program nfs_program; ...@@ -65,7 +64,8 @@ extern struct rpc_program nfs_program;
extern void nfs_put_client(struct nfs_client *); extern void nfs_put_client(struct nfs_client *);
extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *, extern struct nfs_server *nfs_create_server(
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 struct nfs4_mount_data *,
const char *, const char *,
......
...@@ -1041,15 +1041,31 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, ...@@ -1041,15 +1041,31 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
* XXX: as far as I can tell, changing the NFS program number is not * XXX: as far as I can tell, changing the NFS program number is not
* supported in the NFS client. * supported in the NFS client.
*/ */
static int nfs_validate_mount_data(struct nfs_mount_data **options, static int nfs_validate_mount_data(void *options,
struct nfs_parsed_mount_data *args,
struct nfs_fh *mntfh, struct nfs_fh *mntfh,
const char *dev_name) const char *dev_name)
{ {
struct nfs_mount_data *data = *options; struct nfs_mount_data *data = (struct nfs_mount_data *)options;
if (data == NULL) if (data == NULL)
goto out_no_data; goto out_no_data;
memset(args, 0, sizeof(*args));
args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
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->mount_server.protocol = IPPROTO_UDP;
args->mount_server.program = NFS_MNT_PROGRAM;
args->nfs_server.protocol = IPPROTO_TCP;
args->nfs_server.program = NFS_PROGRAM;
switch (data->version) { switch (data->version) {
case 1: case 1:
data->namlen = 0; data->namlen = 0;
...@@ -1078,90 +1094,67 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options, ...@@ -1078,90 +1094,67 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options,
if (mntfh->size < sizeof(mntfh->data)) if (mntfh->size < sizeof(mntfh->data))
memset(mntfh->data + mntfh->size, 0, memset(mntfh->data + mntfh->size, 0,
sizeof(mntfh->data) - mntfh->size); sizeof(mntfh->data) - mntfh->size);
/*
* Translate to nfs_parsed_mount_data, which nfs_fill_super
* can deal with.
*/
args->flags = data->flags;
args->rsize = data->rsize;
args->wsize = data->wsize;
args->flags = data->flags;
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.address = data->addr;
if (!(data->flags & NFS_MOUNT_TCP))
args->nfs_server.protocol = IPPROTO_UDP;
/* N.B. caller will free nfs_server.hostname in all cases */
args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
args->namlen = data->namlen;
args->bsize = data->bsize;
args->auth_flavors[0] = data->pseudoflavor;
break; break;
default: { default: {
unsigned int len; unsigned int len;
char *c; char *c;
int status; int status;
struct nfs_parsed_mount_data args = {
.flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP),
.rsize = NFS_MAX_FILE_IO_SIZE,
.wsize = NFS_MAX_FILE_IO_SIZE,
.timeo = 600,
.retrans = 2,
.acregmin = 3,
.acregmax = 60,
.acdirmin = 30,
.acdirmax = 60,
.mount_server.protocol = IPPROTO_UDP,
.mount_server.program = NFS_MNT_PROGRAM,
.nfs_server.protocol = IPPROTO_TCP,
.nfs_server.program = NFS_PROGRAM,
};
if (nfs_parse_mount_options((char *) *options, &args) == 0) if (nfs_parse_mount_options((char *)options, args) == 0)
return -EINVAL; return -EINVAL;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
/*
* NB: after this point, caller will free "data"
* if we return an error
*/
*options = data;
c = strchr(dev_name, ':'); c = strchr(dev_name, ':');
if (c == NULL) if (c == NULL)
return -EINVAL; return -EINVAL;
len = c - dev_name; len = c - dev_name;
if (len > sizeof(data->hostname)) /* N.B. caller will free nfs_server.hostname in all cases */
return -ENAMETOOLONG; args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
strncpy(data->hostname, dev_name, len);
args.nfs_server.hostname = data->hostname;
c++; c++;
if (strlen(c) > NFS_MAXPATHLEN) if (strlen(c) > NFS_MAXPATHLEN)
return -ENAMETOOLONG; return -ENAMETOOLONG;
args.nfs_server.export_path = c; args->nfs_server.export_path = c;
status = nfs_try_mount(&args, mntfh); status = nfs_try_mount(args, mntfh);
if (status) if (status)
return status; return status;
/*
* Translate to nfs_mount_data, which nfs_fill_super
* can deal with.
*/
data->version = 6;
data->flags = args.flags;
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->addr = args.nfs_server.address;
data->namlen = args.namlen;
data->bsize = args.bsize;
data->pseudoflavor = args.auth_flavors[0];
break; break;
} }
} }
if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) if (!(args->flags & NFS_MOUNT_SECFLAVOUR))
data->pseudoflavor = RPC_AUTH_UNIX; args->auth_flavors[0] = RPC_AUTH_UNIX;
#ifndef CONFIG_NFS_V3 #ifndef CONFIG_NFS_V3
if (data->flags & NFS_MOUNT_VER3) if (args->flags & NFS_MOUNT_VER3)
goto out_v3_not_compiled; goto out_v3_not_compiled;
#endif /* !CONFIG_NFS_V3 */ #endif /* !CONFIG_NFS_V3 */
if (!nfs_verify_server_address((struct sockaddr *) &data->addr)) if (!nfs_verify_server_address((struct sockaddr *)
&args->nfs_server.address))
goto out_no_address; goto out_no_address;
return 0; return 0;
...@@ -1220,7 +1213,8 @@ static inline void nfs_initialise_sb(struct super_block *sb) ...@@ -1220,7 +1213,8 @@ static inline void nfs_initialise_sb(struct super_block *sb)
/* /*
* Finish setting up an NFS2/3 superblock * Finish setting up an NFS2/3 superblock
*/ */
static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data) static void nfs_fill_super(struct super_block *sb,
struct nfs_parsed_mount_data *data)
{ {
struct nfs_server *server = NFS_SB(sb); struct nfs_server *server = NFS_SB(sb);
...@@ -1341,7 +1335,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, ...@@ -1341,7 +1335,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
struct nfs_server *server = NULL; struct nfs_server *server = NULL;
struct super_block *s; struct super_block *s;
struct nfs_fh mntfh; struct nfs_fh mntfh;
struct nfs_mount_data *data = raw_data; struct nfs_parsed_mount_data data;
struct dentry *mntroot; struct dentry *mntroot;
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 = {
...@@ -1350,12 +1344,12 @@ static int nfs_get_sb(struct file_system_type *fs_type, ...@@ -1350,12 +1344,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
int error; int error;
/* Validate the mount data */ /* Validate the mount data */
error = nfs_validate_mount_data(&data, &mntfh, dev_name); error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
if (error < 0) if (error < 0)
goto out; goto out;
/* Get a volume representation */ /* Get a volume representation */
server = nfs_create_server(data, &mntfh); server = nfs_create_server(&data, &mntfh);
if (IS_ERR(server)) { if (IS_ERR(server)) {
error = PTR_ERR(server); error = PTR_ERR(server);
goto out; goto out;
...@@ -1379,7 +1373,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, ...@@ -1379,7 +1373,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
if (!s->s_root) { if (!s->s_root) {
/* initial superblock/root creation */ /* initial superblock/root creation */
nfs_fill_super(s, data); nfs_fill_super(s, &data);
} }
mntroot = nfs_get_root(s, &mntfh); mntroot = nfs_get_root(s, &mntfh);
...@@ -1394,8 +1388,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, ...@@ -1394,8 +1388,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
error = 0; error = 0;
out: out:
if (data != raw_data) kfree(data.nfs_server.hostname);
kfree(data);
return error; return error;
out_err_nosb: out_err_nosb:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment