From 0c834c586066af4c804c38d23b9763d818105f64 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 | 12 ++++++++++-- fs/nfs/internal.h | 7 +++++-- fs/nfs/mount_clnt.c | 7 ++++--- fs/nfs/fs_context.c | 34 +++++++++++++++++++++++++++++++++- include/linux/nfs_fs_sb.h | 2 ++ include/uapi/linux/nfs_mount.h | 4 +++- 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 02110a30a49e..a0f0a7d6208a 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -5,7 +5,6 @@ * Written by David Howells (dhowells@redhat.com) */ - #include #include #include @@ -67,7 +66,7 @@ static const struct rpc_version *nfs_version[5] = { [4] = NULL, }; -const struct rpc_program nfs_program = { +struct rpc_program nfs_program = { .name = "nfs", .number = NFS_PROGRAM, .nrvers = ARRAY_SIZE(nfs_version), @@ -158,6 +157,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) goto error_dealloc; clp->rpc_ops = clp->cl_nfs_mod->rpc_ops; + clp->nfs_prog = cl_init->nfs_prog; refcount_set(&clp->cl_count, 1); clp->cl_cons_state = NFS_CS_INITING; @@ -318,6 +318,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat test_bit(NFS_CS_DS, &clp->cl_flags)) continue; + if (clp->nfs_prog != data->nfs_prog) + continue; + /* Match the full socket address */ if (!rpc_cmp_addr_port(sap, clap)) /* Match all xprt_switch full socket addresses */ @@ -529,6 +532,10 @@ 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", @@ -673,6 +680,7 @@ static int nfs_init_server(struct nfs_server *server, .cred = server->cred, .nconnect = data->nfs_server.nconnect, .init_flags = (1UL << NFS_CS_REUSEPORT), + .nfs_prog = data->nfs_prog, }; struct nfs_client *clp; int error; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 24a65da58aa9..0961649ec4dc 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -77,6 +77,7 @@ struct nfs_client_initdata { struct net *net; const struct rpc_timeout *timeparms; const struct cred *cred; + int nfs_prog; }; /* @@ -88,6 +89,8 @@ struct nfs_parsed_mount_data { unsigned int timeo, retrans; unsigned int acregmin, acregmax, acdirmin, acdirmax; + int nfs_prog; + int mount_prog; unsigned int namlen; unsigned int options; unsigned int bsize; @@ -145,11 +148,11 @@ struct nfs_mount_info { struct nfs_fh *mntfh; }; -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 */ -extern const struct rpc_program nfs_program; +extern struct rpc_program nfs_program; extern void nfs_clients_init(struct net *net); extern void nfs_clients_exit(struct net *net); extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *); diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index cb7c10e9721e..266da4cac411 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -66,7 +66,7 @@ enum { MOUNTPROC3_EXPORT = 5, }; -static const struct rpc_program mnt_program; +static struct rpc_program mnt_program; /* * Defined by OpenGroup XNFS Version 3W, chapter 8 @@ -143,7 +143,7 @@ struct mnt_fhstatus { * with the list from the server or a faked-up list if the server didn't * provide one. */ -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, @@ -178,6 +178,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; @@ -532,7 +533,7 @@ static const struct rpc_version *mnt_version[] = { static struct rpc_stat mnt_stats; -static const struct rpc_program mnt_program = { +static struct rpc_program mnt_program = { .name = "mount", .number = NFS_MNT_PROGRAM, .nrvers = ARRAY_SIZE(mnt_version), diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 8d8d04bb9d64..e09f468bcf18 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -105,6 +105,8 @@ enum { Opt_mountport, Opt_mountvers, Opt_minorversion, + Opt_mountprog, + Opt_nfsprog, /* Mount options that take string arguments */ Opt_nfsvers, @@ -172,6 +174,8 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_mountport, "mountport=%s" }, { Opt_mountvers, "mountvers=%s" }, { Opt_minorversion, "minorversion=%s" }, + { Opt_mountprog, "mountprog=%s" }, + { Opt_nfsprog, "nfsprog=%s" }, { Opt_nfsvers, "nfsvers=%s" }, { Opt_nfsvers, "vers=%s" }, @@ -943,6 +947,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) 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; @@ -1405,6 +1411,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 = kstrtoul(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 = kstrtoul(string, 10, &option); + kfree(string); + if (rc != 0) + goto out_invalid_value; + mnt->nfs_prog = option; + break; case Opt_actimeo: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; @@ -1809,7 +1835,7 @@ static int nfs_request_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); @@ -2117,6 +2143,9 @@ static int nfs23_validate_mount_data(void *options, #endif } + break; + case 7: + args->nfs_prog = (data->version >= 7) ? data->nfs_prog : NFS_PROGRAM; break; default: return NFS_TEXT_DATA; @@ -2180,6 +2209,7 @@ static int nfs_validate_text_mount_data(void *options, int max_namelen = PAGE_SIZE; int max_pathlen = NFS_MAXPATHLEN; struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + args->nfs_prog = NFS_PROGRAM; if (nfs_parse_mount_options((char *)options, args) == 0) return -EINVAL; @@ -2849,6 +2879,8 @@ static int nfs4_validate_mount_data(void *options, args->version = 4; + 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 c176f705bf98..4514af8b8d39 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -63,6 +63,7 @@ struct nfs_client { u32 cl_minorversion;/* NFSv4 minorversion */ unsigned int cl_nconnect; /* Number of connections */ const char * cl_principal; /* used for machine cred */ + int nfs_prog; #if IS_ENABLED(CONFIG_NFS_V4) struct list_head cl_ds_clients; /* auth flavor data servers */ @@ -85,6 +86,7 @@ struct nfs_client { const char * cl_owner_id; u32 cl_cb_ident; /* v4.0 callback identifier */ + const struct nfs4_minor_version_ops *cl_mvops; unsigned long cl_mig_gen; diff --git a/include/uapi/linux/nfs_mount.h b/include/uapi/linux/nfs_mount.h index e3bcfc6aa3b0..ed57fec0beef 100644 --- a/include/uapi/linux/nfs_mount.h +++ b/include/uapi/linux/nfs_mount.h @@ -21,7 +21,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 { @@ -44,6 +44,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 */ -- 2.19.1