diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/Kconfig | 13 | ||||
-rw-r--r-- | fs/nfs/client.c | 12 | ||||
-rw-r--r-- | fs/nfs/internal.h | 7 | ||||
-rw-r--r-- | fs/nfs/mount_clnt.c | 7 | ||||
-rw-r--r-- | fs/nfs/super.c | 34 |
5 files changed, 65 insertions, 8 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 5f93cfacb3d1..73135eb5d0ae 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -39,6 +39,19 @@ config NFS_V2 If unsure, say Y. +config NFS_DEF_FILE_IO_SIZE + int "Default size for NFS I/O read and write at runtime" + depends on NFS_FS + default "4096" + help + To change the default rsize and wsize supported by the NFS client, + adjust NFS_DEF_FILE_IO_SIZE. 64KB is a typical maximum, but some + servers can support a megabyte or more. The default is left at 4096 + bytes, which is reasonable for NFS over UDP, however, for some + systems, setting a smaller value like 1024 can work around + limitations in the driver or hardware and result in overall + improved performance. + config NFS_V3 tristate "NFS client support for NFS version 3" depends on NFS_FS diff --git a/fs/nfs/client.c b/fs/nfs/client.c index b9129e2befea..d59f42ceb53d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ - #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> @@ -70,7 +69,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), @@ -162,6 +161,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; @@ -317,6 +317,9 @@ again: /* Match nfsv4 minorversion */ if (clp->cl_minorversion != data->minorversion) 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 */ @@ -520,6 +523,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", @@ -657,6 +664,7 @@ static int nfs_init_server(struct nfs_server *server, .proto = data->nfs_server.protocol, .net = data->net, .timeparms = &timeparms, + .nfs_prog = data->nfs_prog, }; struct nfs_client *clp; int error; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 8357ff69962f..a97b081ab843 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -83,6 +83,7 @@ struct nfs_client_initdata { u32 minorversion; struct net *net; const struct rpc_timeout *timeparms; + int nfs_prog; }; /* @@ -94,6 +95,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; @@ -150,11 +153,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 struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *); int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t); diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index d979ff4fee7e..7035dc1797c2 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, @@ -177,6 +177,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; @@ -530,7 +531,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/super.c b/fs/nfs/super.c index 5e470e233c83..6be98319ee98 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -102,6 +102,8 @@ enum { Opt_mountport, Opt_mountvers, Opt_minorversion, + Opt_mountprog, + Opt_nfsprog, /* Mount options that take string arguments */ Opt_nfsvers, @@ -167,6 +169,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" }, @@ -922,6 +926,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; @@ -1389,6 +1395,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; @@ -1789,7 +1815,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); @@ -2097,6 +2123,9 @@ static int nfs23_validate_mount_data(void *options, } break; + case 7: + args->nfs_prog = (data->version >= 7) ? data->nfs_prog : NFS_PROGRAM; + break; default: return NFS_TEXT_DATA; } @@ -2159,6 +2188,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; @@ -2778,6 +2808,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)) |