diff options
author | Alexandros Batsakis <batsakis@netapp.com> | 2010-02-05 06:45:05 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-02 12:54:30 -0500 |
commit | 7135840fc74699513d50e0c9c64922f2d38aa5e3 (patch) | |
tree | 565b03cebb1bff5fde1cc54418eb56d54e5bd743 /fs/nfs | |
parent | dc96aef96a75348b4d1b01c4c0429ab52780683e (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.c | 18 |
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 | } |
424 | out: | 425 | out: |
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 | ||
5041 | static void nfs41_sequence_call_done(struct rpc_task *task, void *data) | 5044 | static 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 | 5062 | out: | |
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; |