summaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorOlga Kornievskaia <aglo@citi.umich.edu>2008-03-28 16:04:56 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-04-23 16:13:42 -0400
commitff7d9756b501744540be65e172d27ee321d86103 (patch)
treed5f812aa7dd230e51f4b5e2d921692757f41b983 /fs/nfsd
parent8774282c4cef82695ccca8bd09976de5d6e49610 (diff)
downloadop-kernel-dev-ff7d9756b501744540be65e172d27ee321d86103.zip
op-kernel-dev-ff7d9756b501744540be65e172d27ee321d86103.tar.gz
nfsd: use static memory for callback program and stats
There's no need to dynamically allocate this memory, and doing so may create the possibility of races on shutdown of the rpc client. (We've witnessed it only after adding rpcsec_gss support to the server, after which the rpc code can send destroys calls that expect to still be able to access the rpc_stats structure after it has been destroyed.) Such races are in theory possible if the module containing this "static" memory is removed very quickly after an rpc client is destroyed, but we haven't seen that happen. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4callback.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index aae2b29..562abf3 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -344,6 +344,21 @@ static struct rpc_version * nfs_cb_version[] = {
&nfs_cb_version4,
};
+static struct rpc_program cb_program;
+
+static struct rpc_stat cb_stats = {
+ .program = &cb_program
+};
+
+#define NFS4_CALLBACK 0x40000000
+static struct rpc_program cb_program = {
+ .name = "nfs4_cb",
+ .number = NFS4_CALLBACK,
+ .nrvers = ARRAY_SIZE(nfs_cb_version),
+ .version = nfs_cb_version,
+ .stats = &cb_stats,
+};
+
/* Reference counting, callback cleanup, etc., all look racy as heck.
* And why is cb_set an atomic? */
@@ -358,13 +373,12 @@ static int do_probe_callback(void *data)
.to_maxval = (NFSD_LEASE_TIME/2) * HZ,
.to_exponential = 1,
};
- struct rpc_program * program = &cb->cb_program;
struct rpc_create_args args = {
.protocol = IPPROTO_TCP,
.address = (struct sockaddr *)&addr,
.addrsize = sizeof(addr),
.timeout = &timeparms,
- .program = program,
+ .program = &cb_program,
.version = nfs_cb_version[1]->number,
.authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
.flags = (RPC_CLNT_CREATE_NOPING),
@@ -382,16 +396,8 @@ static int do_probe_callback(void *data)
addr.sin_port = htons(cb->cb_port);
addr.sin_addr.s_addr = htonl(cb->cb_addr);
- /* Initialize rpc_program */
- program->name = "nfs4_cb";
- program->number = cb->cb_prog;
- program->nrvers = ARRAY_SIZE(nfs_cb_version);
- program->version = nfs_cb_version;
- program->stats = &cb->cb_stat;
-
/* Initialize rpc_stat */
- memset(program->stats, 0, sizeof(cb->cb_stat));
- program->stats->program = program;
+ memset(args.program->stats, 0, sizeof(struct rpc_stat));
/* Create RPC client */
client = rpc_create(&args);
OpenPOWER on IntegriCloud