aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
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/nfs4callback.c
parent8774282c4cef82695ccca8bd09976de5d6e49610 (diff)
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/nfs4callback.c')
-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 aae2b29ae2c9..562abf3380d0 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -344,6 +344,21 @@ static struct rpc_version * nfs_cb_version[] = {
344 &nfs_cb_version4, 344 &nfs_cb_version4,
345}; 345};
346 346
347static struct rpc_program cb_program;
348
349static struct rpc_stat cb_stats = {
350 .program = &cb_program
351};
352
353#define NFS4_CALLBACK 0x40000000
354static struct rpc_program cb_program = {
355 .name = "nfs4_cb",
356 .number = NFS4_CALLBACK,
357 .nrvers = ARRAY_SIZE(nfs_cb_version),
358 .version = nfs_cb_version,
359 .stats = &cb_stats,
360};
361
347/* Reference counting, callback cleanup, etc., all look racy as heck. 362/* Reference counting, callback cleanup, etc., all look racy as heck.
348 * And why is cb_set an atomic? */ 363 * And why is cb_set an atomic? */
349 364
@@ -358,13 +373,12 @@ static int do_probe_callback(void *data)
358 .to_maxval = (NFSD_LEASE_TIME/2) * HZ, 373 .to_maxval = (NFSD_LEASE_TIME/2) * HZ,
359 .to_exponential = 1, 374 .to_exponential = 1,
360 }; 375 };
361 struct rpc_program * program = &cb->cb_program;
362 struct rpc_create_args args = { 376 struct rpc_create_args args = {
363 .protocol = IPPROTO_TCP, 377 .protocol = IPPROTO_TCP,
364 .address = (struct sockaddr *)&addr, 378 .address = (struct sockaddr *)&addr,
365 .addrsize = sizeof(addr), 379 .addrsize = sizeof(addr),
366 .timeout = &timeparms, 380 .timeout = &timeparms,
367 .program = program, 381 .program = &cb_program,
368 .version = nfs_cb_version[1]->number, 382 .version = nfs_cb_version[1]->number,
369 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ 383 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
370 .flags = (RPC_CLNT_CREATE_NOPING), 384 .flags = (RPC_CLNT_CREATE_NOPING),
@@ -382,16 +396,8 @@ static int do_probe_callback(void *data)
382 addr.sin_port = htons(cb->cb_port); 396 addr.sin_port = htons(cb->cb_port);
383 addr.sin_addr.s_addr = htonl(cb->cb_addr); 397 addr.sin_addr.s_addr = htonl(cb->cb_addr);
384 398
385 /* Initialize rpc_program */
386 program->name = "nfs4_cb";
387 program->number = cb->cb_prog;
388 program->nrvers = ARRAY_SIZE(nfs_cb_version);
389 program->version = nfs_cb_version;
390 program->stats = &cb->cb_stat;
391
392 /* Initialize rpc_stat */ 399 /* Initialize rpc_stat */
393 memset(program->stats, 0, sizeof(cb->cb_stat)); 400 memset(args.program->stats, 0, sizeof(struct rpc_stat));
394 program->stats->program = program;
395 401
396 /* Create RPC client */ 402 /* Create RPC client */
397 client = rpc_create(&args); 403 client = rpc_create(&args);