aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 618a327027b3..c6f07c1c71e6 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -8,6 +8,7 @@
8 */ 8 */
9#include <linux/config.h> 9#include <linux/config.h>
10#include <linux/completion.h> 10#include <linux/completion.h>
11#include <linux/kthread.h>
11#include <linux/module.h> 12#include <linux/module.h>
12#include <linux/sched.h> 13#include <linux/sched.h>
13#include <linux/spinlock.h> 14#include <linux/spinlock.h>
@@ -130,6 +131,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
130 sizeof(delegation->stateid.data)); 131 sizeof(delegation->stateid.data));
131 delegation->type = res->delegation_type; 132 delegation->type = res->delegation_type;
132 delegation->maxsize = res->maxsize; 133 delegation->maxsize = res->maxsize;
134 delegation->change_attr = nfsi->change_attr;
133 delegation->cred = get_rpccred(cred); 135 delegation->cred = get_rpccred(cred);
134 delegation->inode = inode; 136 delegation->inode = inode;
135 137
@@ -157,8 +159,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
157{ 159{
158 int res = 0; 160 int res = 0;
159 161
160 __nfs_revalidate_inode(NFS_SERVER(inode), inode);
161
162 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); 162 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
163 nfs_free_delegation(delegation); 163 nfs_free_delegation(delegation);
164 return res; 164 return res;
@@ -231,6 +231,49 @@ restart:
231 spin_unlock(&clp->cl_lock); 231 spin_unlock(&clp->cl_lock);
232} 232}
233 233
234int nfs_do_expire_all_delegations(void *ptr)
235{
236 struct nfs4_client *clp = ptr;
237 struct nfs_delegation *delegation;
238 struct inode *inode;
239
240 allow_signal(SIGKILL);
241restart:
242 spin_lock(&clp->cl_lock);
243 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
244 goto out;
245 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
246 goto out;
247 list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
248 inode = igrab(delegation->inode);
249 if (inode == NULL)
250 continue;
251 spin_unlock(&clp->cl_lock);
252 nfs_inode_return_delegation(inode);
253 iput(inode);
254 goto restart;
255 }
256out:
257 spin_unlock(&clp->cl_lock);
258 nfs4_put_client(clp);
259 module_put_and_exit(0);
260}
261
262void nfs_expire_all_delegations(struct nfs4_client *clp)
263{
264 struct task_struct *task;
265
266 __module_get(THIS_MODULE);
267 atomic_inc(&clp->cl_count);
268 task = kthread_run(nfs_do_expire_all_delegations, clp,
269 "%u.%u.%u.%u-delegreturn",
270 NIPQUAD(clp->cl_addr));
271 if (!IS_ERR(task))
272 return;
273 nfs4_put_client(clp);
274 module_put(THIS_MODULE);
275}
276
234/* 277/*
235 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. 278 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
236 */ 279 */