[pnfs] [PATCH 24/29] nfs41: nfs41_proc_async_sequence bug fix
Benny Halevy
bhalevy at panasas.com
Fri Dec 28 03:46:04 EST 2007
From: Andy Adamson <andros at umich.edu>
Move the put_rpccred() call from nfs4_renew_state90 into the asyc state
renewal rpc_call_done routine so the rpc cred is not reaped before the call
is done.
The async rpc call requires kmalloc'ed arguments.
Replace the local nfs41_sequence_args and nfs41_sequence_res
nfs41_proc_async_sequence() variables with kmalloc versions. Free
in rpc_call_done routine.
Signed-off-by: Andy Adamson<andros at umich.edu>
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfs/nfs4proc.c | 32 +++++++++++++++++++++++++-------
fs/nfs/nfs4renewd.c | 1 -
2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 40492e1..7b65623 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3167,6 +3167,9 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
if (time_before(clp->cl_last_renewal,timestamp))
clp->cl_last_renewal = timestamp;
spin_unlock(&clp->cl_lock);
+ dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
+ task->tk_msg.rpc_cred);
+ put_rpccred(task->tk_msg.rpc_cred);
}
static const struct rpc_call_ops nfs4_renew_ops = {
@@ -5006,6 +5009,13 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
nfs41_recover_session(clp, session);
}
}
+ dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
+
+ put_rpccred(task->tk_msg.rpc_cred);
+ kfree(task->tk_msg.rpc_argp);
+ kfree(task->tk_msg.rpc_resp);
+
+ dprintk("<-- %s\n", __func__);
}
static void nfs41_sequence_validate(struct rpc_task *task, void *data)
@@ -5033,17 +5043,25 @@ static const struct rpc_call_ops nfs41_sequence_ops = {
int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred)
{
- struct nfs41_sequence_args args;
- struct nfs41_sequence_res res;
+ struct nfs41_sequence_args *args;
+ struct nfs41_sequence_res *res;
struct nfs_server *server;
-
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
- .rpc_argp = &args,
- .rpc_resp = &res,
.rpc_cred = cred,
};
+ args = kzalloc(sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (!res) {
+ kfree(args);
+ return -ENOMEM;
+ }
+ msg.rpc_argp = args;
+ msg.rpc_resp = res;
+
/*
* We need to renew the lease on the server. For this, we use any
* session we have on the server to send the SEQUENCE op
@@ -5216,13 +5234,13 @@ struct nfs4_state_recovery_ops nfs41_network_partition_recovery_ops = {
struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = {
.sched_state_renewal = nfs4_proc_async_renew,
- .get_state_renewal_cred = nfs41_get_state_renewal_cred,
+ .get_state_renewal_cred = nfs4_get_renew_cred,
};
#if defined(CONFIG_NFS_V4_1)
struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
.sched_state_renewal = nfs41_proc_async_sequence,
- .get_state_renewal_cred = nfs4_get_renew_cred,
+ .get_state_renewal_cred = nfs41_get_state_renewal_cred,
};
#endif
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 20667d8..94f1d82 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -91,7 +91,6 @@ nfs4_renew_state(struct work_struct *work)
spin_unlock(&clp->cl_lock);
/* Queue an asynchronous RENEW. */
ops->sched_state_renewal(clp, cred);
- put_rpccred(cred);
timeout = (2 * lease) / 3;
spin_lock(&clp->cl_lock);
} else
--
1.5.3.3
More information about the pNFS
mailing list