From e85103e27b7591337d3240cf0ab2670d0ab73d52 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Wed, 7 Jan 2009 00:59:33 -0500 Subject: [PATCH] NFS: allow nfs root mount to use alternate rpc ports Allow an nfs root mount to use alternate RPC ports for mountd and nfsd. Signed-off-by: Jason Wessel [forward port to 2.6.33+] Signed-off-by: Bruce Ashfield --- fs/nfs/client.c | 10 ++++++++++ fs/nfs/internal.h | 4 +++- fs/nfs/mount_clnt.c | 3 ++- fs/nfs/super.c | 33 ++++++++++++++++++++++++++++++++- include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_mount.h | 4 +++- 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index d25b525..b706c02 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -105,6 +105,7 @@ struct nfs_client_initdata { const struct nfs_rpc_ops *rpc_ops; int proto; u32 minorversion; + int nfs_prog; }; /* @@ -123,6 +124,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ goto error_0; clp->rpc_ops = cl_init->rpc_ops; + clp->nfs_prog = cl_init->nfs_prog; atomic_set(&clp->cl_count, 1); clp->cl_cons_state = NFS_CS_INITING; @@ -448,6 +450,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat /* Match nfsv4 minorversion */ if (clp->cl_minorversion != data->minorversion) continue; + if (clp->nfs_prog != data->nfs_prog) + continue; + /* Match the full socket address */ if (!nfs_sockaddr_cmp(sap, clap)) continue; @@ -618,6 +623,10 @@ static int nfs_create_rpc_client(struct nfs_client *clp, if (!IS_ERR(clp->cl_rpcclient)) return 0; + if (clp->nfs_prog) + nfs_program.number = clp->nfs_prog; + else + nfs_program.number = NFS_PROGRAM; clnt = rpc_create(&args); if (IS_ERR(clnt)) { dprintk("%s: cannot create RPC client. Error = %ld\n", @@ -786,6 +795,7 @@ static int nfs_init_server(struct nfs_server *server, .addrlen = data->nfs_server.addrlen, .rpc_ops = &nfs_v2_clientops, .proto = data->nfs_server.protocol, + .nfs_prog = data->nfs_prog, }; struct rpc_timeout timeparms; struct nfs_client *clp; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index e70f44b..3e2649f 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -71,6 +71,8 @@ struct nfs_parsed_mount_data { int timeo, retrans; int acregmin, acregmax, acdirmin, acdirmax; + int nfs_prog; + int mount_prog; int namlen; unsigned int options; unsigned int bsize; @@ -116,7 +118,7 @@ struct nfs_mount_request { rpc_authflavor_t *auth_flavs; }; -extern int nfs_mount(struct nfs_mount_request *info); +extern int nfs_mount(struct nfs_mount_request *info, int prog); extern void nfs_umount(const struct nfs_mount_request *info); /* client.c */ diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 59047f8..0a2bd63 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -141,7 +141,7 @@ struct mnt_fhstatus { * * Uses default timeout parameters specified by underlying transport. */ -int nfs_mount(struct nfs_mount_request *info) +int nfs_mount(struct nfs_mount_request *info, int m_prog) { struct mountres result = { .fh = info->fh, @@ -171,6 +171,7 @@ int nfs_mount(struct nfs_mount_request *info) if (info->noresvport) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; + mnt_program.number = m_prog; mnt_clnt = rpc_create(&args); if (IS_ERR(mnt_clnt)) goto out_clnt_err; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f9df16d..0b3bbf8 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -94,6 +94,8 @@ enum { Opt_mountvers, Opt_nfsvers, Opt_minorversion, + Opt_mountprog, + Opt_nfsprog, /* Mount options that take string arguments */ Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, @@ -160,6 +162,8 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_nfsvers, "nfsvers=%s" }, { Opt_nfsvers, "vers=%s" }, { Opt_minorversion, "minorversion=%s" }, + { Opt_mountprog, "mountprog=%s" }, + { Opt_nfsprog, "nfsprog=%s" }, { Opt_sec, "sec=%s" }, { Opt_proto, "proto=%s" }, @@ -787,6 +791,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve data->acregmax = NFS_DEF_ACREGMAX; data->acdirmin = NFS_DEF_ACDIRMIN; data->acdirmax = NFS_DEF_ACDIRMAX; + data->nfs_prog = NFS_PROGRAM; + data->mount_prog = NFS_MNT_PROGRAM; data->mount_server.port = NFS_UNSPEC_PORT; data->nfs_server.port = NFS_UNSPEC_PORT; data->nfs_server.protocol = XPRT_TRANSPORT_TCP; @@ -1168,6 +1174,26 @@ static int nfs_parse_mount_options(char *raw, goto out_invalid_value; mnt->acdirmax = option; break; + case Opt_mountprog: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + rc = strict_strtoul(string, 10, &option); + kfree(string); + if (rc != 0) + goto out_invalid_value; + mnt->mount_prog = option; + break; + case Opt_nfsprog: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + rc = strict_strtoul(string, 10, &option); + kfree(string); + if (rc != 0) + goto out_invalid_value; + mnt->nfs_prog = option; + break; case Opt_actimeo: string = match_strdup(args); if (string == NULL) @@ -1566,7 +1592,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, * Now ask the mount server to map our export path * to a file handle. */ - status = nfs_mount(&request); + status = nfs_mount(&request,args->mount_prog); if (status != 0) { dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", request.hostname, status); @@ -1739,6 +1765,7 @@ static int nfs_validate_mount_data(void *options, { struct nfs_mount_data *data = (struct nfs_mount_data *)options; struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + args->nfs_prog = NFS_PROGRAM; if (data == NULL) goto out_no_data; @@ -1758,6 +1785,8 @@ static int nfs_validate_mount_data(void *options, goto out_no_sec; case 5: memset(data->context, 0, sizeof(data->context)); + case 7: + args->nfs_prog = (data->version >= 7) ? data->nfs_prog : NFS_PROGRAM; case 6: if (data->flags & NFS_MOUNT_VER3) { if (data->root.size > NFS3_FHSIZE || data->root.size == 0) @@ -2476,6 +2505,8 @@ static int nfs4_validate_mount_data(void *options, if (data == NULL) goto out_no_data; + args->nfs_prog = NFS_PROGRAM; + switch (data->version) { case 1: if (data->host_addrlen > sizeof(args->nfs_server.address)) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index d6e10a4..585cba4 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -41,6 +41,7 @@ struct nfs_client { u32 cl_minorversion;/* NFSv4 minorversion */ struct rpc_cred *cl_machine_cred; + int nfs_prog; #ifdef CONFIG_NFS_V4 u64 cl_clientid; /* constant */ diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h index 4499016..86beb0c 100644 --- a/include/linux/nfs_mount.h +++ b/include/linux/nfs_mount.h @@ -20,7 +20,7 @@ * mount-to-kernel version compatibility. Some of these aren't used yet * but here they are anyway. */ -#define NFS_MOUNT_VERSION 6 +#define NFS_MOUNT_VERSION 7 #define NFS_MAX_CONTEXT_LEN 256 struct nfs_mount_data { @@ -43,6 +43,8 @@ struct nfs_mount_data { struct nfs3_fh root; /* 4 */ int pseudoflavor; /* 5 */ char context[NFS_MAX_CONTEXT_LEN + 1]; /* 6 */ + int nfs_prog; /* 7 */ + int mount_prog; /* 7 */ }; /* bits in the flags field visible to user space */ -- 1.7.9.1