nfs4_put_deleg_lease(fp);
 }
 
-static void destroy_revoked_delegation(struct nfs4_delegation *dp)
-{
-       list_del_init(&dp->dl_recall_lru);
-       nfs4_put_delegation(dp);
-}
-
 static void destroy_delegation(struct nfs4_delegation *dp)
 {
        spin_lock(&state_lock);
 {
        struct nfs4_client *clp = dp->dl_stid.sc_client;
 
+       WARN_ON(!list_empty(&dp->dl_recall_lru));
+
        if (clp->cl_minorversion == 0)
-               destroy_revoked_delegation(dp);
+               nfs4_put_delegation(dp);
        else {
                dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
-               list_move(&dp->dl_recall_lru, &clp->cl_revoked);
+               spin_lock(&clp->cl_lock);
+               list_add(&dp->dl_recall_lru, &clp->cl_revoked);
+               spin_unlock(&clp->cl_lock);
        }
 }
 
                list_del_init(&dp->dl_recall_lru);
                nfs4_put_delegation(dp);
        }
-       list_splice_init(&clp->cl_revoked, &reaplist);
-       while (!list_empty(&reaplist)) {
+       while (!list_empty(&clp->cl_revoked)) {
                dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
-               destroy_revoked_delegation(dp);
+               list_del_init(&dp->dl_recall_lru);
+               nfs4_put_delegation(dp);
        }
        while (!list_empty(&clp->cl_openowners)) {
                oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
                list_add(&dp->dl_recall_lru, &reaplist);
        }
        spin_unlock(&state_lock);
-       list_for_each_safe(pos, next, &reaplist) {
-               dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
+       while (!list_empty(&reaplist)) {
+               dp = list_first_entry(&reaplist, struct nfs4_delegation,
+                                       dl_recall_lru);
+               list_del_init(&dp->dl_recall_lru);
                revoke_delegation(dp);
        }
        list_for_each_safe(pos, next, &nn->close_lru) {
                break;
        case NFS4_REVOKED_DELEG_STID:
                dp = delegstateid(s);
-               destroy_revoked_delegation(dp);
+               spin_lock(&cl->cl_lock);
+               list_del_init(&dp->dl_recall_lru);
+               spin_unlock(&cl->cl_lock);
+               nfs4_put_delegation(dp);
                ret = nfs_ok;
                break;
        default:
        count = nfsd_find_all_delegations(clp, max, &victims);
        spin_unlock(&state_lock);
 
-       list_for_each_entry_safe(dp, next, &victims, dl_recall_lru)
+       list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) {
+               list_del_init(&dp->dl_recall_lru);
                revoke_delegation(dp);
+       }
 
        return count;
 }