nfsd4: implement new 4.1 open reclaim types
authorJ. Bruce Fields <bfields@redhat.com>
Wed, 19 Oct 2011 15:52:12 +0000 (11:52 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 19 Oct 2011 15:52:12 +0000 (11:52 -0400)
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
include/linux/nfs4.h

index 710b97b..458ebb6 100644 (file)
@@ -366,12 +366,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        switch (open->op_claim_type) {
                case NFS4_OPEN_CLAIM_DELEGATE_CUR:
                case NFS4_OPEN_CLAIM_NULL:
-                       /*
-                        * (1) set CURRENT_FH to the file being opened,
-                        * creating it if necessary, (2) set open->op_cinfo,
-                        * (3) set open->op_truncate if the file is to be
-                        * truncated after opening, (4) do permission checking.
-                        */
                        status = do_open_lookup(rqstp, &cstate->current_fh,
                                                open);
                        if (status)
@@ -379,17 +373,14 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        break;
                case NFS4_OPEN_CLAIM_PREVIOUS:
                        open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
-                       /*
-                        * The CURRENT_FH is already set to the file being
-                        * opened.  (1) set open->op_cinfo, (2) set
-                        * open->op_truncate if the file is to be truncated
-                        * after opening, (3) do permission checking.
-                       */
+               case NFS4_OPEN_CLAIM_FH:
+               case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
                        status = do_open_fhandle(rqstp, &cstate->current_fh,
                                                 open);
                        if (status)
                                goto out;
                        break;
+               case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
                case NFS4_OPEN_CLAIM_DELEGATE_PREV:
                        open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
                        dprintk("NFSD: unsupported OPEN claim type %d\n",
index 15e0db1..e8c2a3e 100644 (file)
@@ -2587,6 +2587,12 @@ static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, statei
        return delegstateid(ret);
 }
 
+static bool nfsd4_is_deleg_cur(struct nfsd4_open *open)
+{
+       return open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR ||
+              open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH;
+}
+
 static __be32
 nfs4_check_deleg(struct nfs4_client *cl, struct nfs4_file *fp, struct nfsd4_open *open,
                struct nfs4_delegation **dp)
@@ -2602,7 +2608,7 @@ nfs4_check_deleg(struct nfs4_client *cl, struct nfs4_file *fp, struct nfsd4_open
        if (status)
                *dp = NULL;
 out:
-       if (open->op_claim_type != NFS4_OPEN_CLAIM_DELEGATE_CUR)
+       if (!nfsd4_is_deleg_cur(open))
                return nfs_ok;
        if (status)
                return status;
@@ -2879,7 +2885,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
                        goto out;
        } else {
                status = nfserr_bad_stateid;
-               if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
+               if (nfsd4_is_deleg_cur(open))
                        goto out;
                status = nfserr_jukebox;
                fp = open->op_file;
index 645a0a9..fdc09a5 100644 (file)
@@ -803,6 +803,19 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
                if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
                        return status;
                break;
+       case NFS4_OPEN_CLAIM_FH:
+       case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
+               if (argp->minorversion < 1)
+                       goto xdr_error;
+               /* void */
+               break;
+       case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
+               if (argp->minorversion < 1)
+                       goto xdr_error;
+               status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
+               if (status)
+                       return status;
+               break;
        default:
                goto xdr_error;
        }
index b875b03..32345c2 100644 (file)
@@ -410,7 +410,10 @@ enum open_claim_type4 {
        NFS4_OPEN_CLAIM_NULL = 0,
        NFS4_OPEN_CLAIM_PREVIOUS = 1,
        NFS4_OPEN_CLAIM_DELEGATE_CUR = 2,
-       NFS4_OPEN_CLAIM_DELEGATE_PREV = 3
+       NFS4_OPEN_CLAIM_DELEGATE_PREV = 3,
+       NFS4_OPEN_CLAIM_FH = 4, /* 4.1 */
+       NFS4_OPEN_CLAIM_DELEG_CUR_FH = 5, /* 4.1 */
+       NFS4_OPEN_CLAIM_DELEG_PREV_FH = 6, /* 4.1 */
 };
 
 enum opentype4 {