[PATCH] knfsd: nfsd4: delegation recovery
authorNeilBrown <neilb@cse.unsw.edu.au>
Fri, 24 Jun 2005 05:03:23 +0000 (22:03 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 24 Jun 2005 07:06:31 +0000 (00:06 -0700)
Allow recovery of delegations after reboot.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
include/linux/nfsd/xdr4.h

index 16c9a43218c363dadd766fa2c5647953c92c65aa..0f6119714c8cc0fb21824528b69eb4d15f675627 100644 (file)
@@ -1709,14 +1709,30 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        int status, flag = 0;
 
        flag = NFS4_OPEN_DELEGATE_NONE;
-       if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL
-            || !atomic_read(&cb->cb_set) || !sop->so_confirmed)
-               goto out;
-
-       if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
-               flag = NFS4_OPEN_DELEGATE_WRITE;
-       else
-               flag = NFS4_OPEN_DELEGATE_READ;
+       open->op_recall = 0;
+       switch (open->op_claim_type) {
+               case NFS4_OPEN_CLAIM_PREVIOUS:
+                       if (!atomic_read(&cb->cb_set))
+                               open->op_recall = 1;
+                       flag = open->op_delegate_type;
+                       if (flag == NFS4_OPEN_DELEGATE_NONE)
+                               goto out;
+                       break;
+               case NFS4_OPEN_CLAIM_NULL:
+                       /* Let's not give out any delegations till everyone's
+                        * had the chance to reclaim theirs.... */
+                       if (nfs4_in_grace())
+                               goto out;
+                       if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
+                               goto out;
+                       if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
+                               flag = NFS4_OPEN_DELEGATE_WRITE;
+                       else
+                               flag = NFS4_OPEN_DELEGATE_READ;
+                       break;
+               default:
+                       goto out;
+       }
 
        dp = alloc_init_deleg(sop->so_client, stp, fh, flag);
        if (dp == NULL) {
@@ -1750,6 +1766,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
                     dp->dl_stateid.si_fileid,
                     dp->dl_stateid.si_generation);
 out:
+       if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
+                       && flag == NFS4_OPEN_DELEGATE_NONE
+                       && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
+               printk("NFSD: WARNING: refusing delegation reclaim\n");
        open->op_delegate_type = flag;
 }
 
index 0ae1467c3bc3f7def4048118dc42ecf68ca7d615..cfe978a72cea71996b115ce1cc4de168b7023bfc 100644 (file)
@@ -1972,7 +1972,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open
        case NFS4_OPEN_DELEGATE_READ:
                RESERVE_SPACE(20 + sizeof(stateid_t));
                WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
-               WRITE32(0);
+               WRITE32(open->op_recall);
 
                /*
                 * TODO: ACE's in delegations
index a1f5ad0be1bf0a17473c36d6e057662fa6b7120b..4d24d65c0e88ae44abd098ee1b6aa25fc75f8a40 100644 (file)
@@ -210,6 +210,7 @@ struct nfsd4_open {
        u32             op_share_access;    /* request */
        u32             op_share_deny;      /* request */
        stateid_t       op_stateid;         /* response */
+       u32             op_recall;          /* recall */
        struct nfsd4_change_info  op_cinfo; /* response */
        u32             op_rflags;          /* response */
        int             op_truncate;        /* used during processing */