[pnfs] [PATCH 22/23] 2.6-latest pnfs client nfs41_proc_async_sequence bug fix
andros at umich.edu
andros at umich.edu
Thu Dec 13 15:51:48 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>
---
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 f3aa86e..2c52819 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3130,6 +3130,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 = {
@@ -3235,6 +3238,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)
@@ -3261,17 +3271,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
@@ -5169,13 +5187,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.0.2
More information about the pNFS
mailing list