+int nfs_do_expire_all_delegations(void *ptr)
+{
+ struct nfs_client *clp = ptr;
+ struct nfs_delegation *delegation;
+ struct inode *inode;
+
+ allow_signal(SIGKILL);
+restart:
+ spin_lock(&clp->cl_lock);
+ if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
+ goto out;
+ if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
+ goto out;
+ list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
+ inode = igrab(delegation->inode);
+ if (inode == NULL)
+ continue;
+ spin_unlock(&clp->cl_lock);
+ nfs_inode_return_delegation(inode);
+ iput(inode);
+ goto restart;
+ }
+out:
+ spin_unlock(&clp->cl_lock);
+ nfs_put_client(clp);
+ module_put_and_exit(0);
+}
+
+void nfs_expire_all_delegations(struct nfs_client *clp)
+{
+ struct task_struct *task;
+
+ __module_get(THIS_MODULE);
+ atomic_inc(&clp->cl_count);
+ task = kthread_run(nfs_do_expire_all_delegations, clp,
+ "%u.%u.%u.%u-delegreturn",
+ NIPQUAD(clp->cl_addr.sin_addr));
+ if (!IS_ERR(task))
+ return;
+ nfs_put_client(clp);
+ module_put(THIS_MODULE);
+}
+