aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorAlexandros Batsakis <batsakis@netapp.com>2010-02-05 06:45:05 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-03-02 12:54:30 -0500
commit7135840fc74699513d50e0c9c64922f2d38aa5e3 (patch)
tree565b03cebb1bff5fde1cc54418eb56d54e5bd743 /fs/nfs
parentdc96aef96a75348b4d1b01c4c0429ab52780683e (diff)
nfs41: renewd sequence operations should take/put client reference
renewd sends SEQUENCE requests to the NFS server in order to renew state. As the request is asynchronous, renewd should take a reference to the nfs_client to prevent concurrent umounts from freeing the session/client Signed-off-by: Alexandros Batsakis <batsakis@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 726bc195039d..663ae0c36834 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -419,7 +419,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
419 clp->cl_last_renewal = timestamp; 419 clp->cl_last_renewal = timestamp;
420 spin_unlock(&clp->cl_lock); 420 spin_unlock(&clp->cl_lock);
421 /* Check sequence flags */ 421 /* Check sequence flags */
422 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); 422 if (atomic_read(&clp->cl_count) > 1)
423 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
423 } 424 }
424out: 425out:
425 /* The session may be reset by one of the error handlers. */ 426 /* The session may be reset by one of the error handlers. */
@@ -5035,7 +5036,9 @@ static void nfs41_sequence_release(void *data)
5035{ 5036{
5036 struct nfs_client *clp = (struct nfs_client *)data; 5037 struct nfs_client *clp = (struct nfs_client *)data;
5037 5038
5038 nfs4_schedule_state_renewal(clp); 5039 if (atomic_read(&clp->cl_count) > 1)
5040 nfs4_schedule_state_renewal(clp);
5041 nfs_put_client(clp);
5039} 5042}
5040 5043
5041static void nfs41_sequence_call_done(struct rpc_task *task, void *data) 5044static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
@@ -5046,6 +5049,8 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
5046 5049
5047 if (task->tk_status < 0) { 5050 if (task->tk_status < 0) {
5048 dprintk("%s ERROR %d\n", __func__, task->tk_status); 5051 dprintk("%s ERROR %d\n", __func__, task->tk_status);
5052 if (atomic_read(&clp->cl_count) == 1)
5053 goto out;
5049 5054
5050 if (_nfs4_async_handle_error(task, NULL, clp, NULL) 5055 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
5051 == -EAGAIN) { 5056 == -EAGAIN) {
@@ -5054,7 +5059,7 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
5054 } 5059 }
5055 } 5060 }
5056 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); 5061 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
5057 5062out:
5058 kfree(task->tk_msg.rpc_argp); 5063 kfree(task->tk_msg.rpc_argp);
5059 kfree(task->tk_msg.rpc_resp); 5064 kfree(task->tk_msg.rpc_resp);
5060 5065
@@ -5092,12 +5097,13 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
5092 .rpc_cred = cred, 5097 .rpc_cred = cred,
5093 }; 5098 };
5094 5099
5100 if (!atomic_inc_not_zero(&clp->cl_count))
5101 return -EIO;
5095 args = kzalloc(sizeof(*args), GFP_KERNEL); 5102 args = kzalloc(sizeof(*args), GFP_KERNEL);
5096 if (!args)
5097 return -ENOMEM;
5098 res = kzalloc(sizeof(*res), GFP_KERNEL); 5103 res = kzalloc(sizeof(*res), GFP_KERNEL);
5099 if (!res) { 5104 if (!args || !res) {
5100 kfree(args); 5105 kfree(args);
5106 nfs_put_client(clp);
5101 return -ENOMEM; 5107 return -ENOMEM;
5102 } 5108 }
5103 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 5109 res->sr_slotid = NFS4_MAX_SLOT_TABLE;