These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / fs / nfsd / nfs4proc.c
index 864e200..a9f096c 100644 (file)
@@ -276,13 +276,13 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
                        nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
 
                /*
-                * Following rfc 3530 14.2.16, use the returned bitmask
-                * to indicate which attributes we used to store the
-                * verifier:
+                * Following rfc 3530 14.2.16, and rfc 5661 18.16.4
+                * use the returned bitmask to indicate which attributes
+                * we used to store the verifier:
                 */
-               if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
-                       open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
-                                                       FATTR4_WORD1_TIME_MODIFY);
+               if (nfsd_create_is_exclusive(open->op_createmode) && status == 0)
+                       open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS |
+                                               FATTR4_WORD1_TIME_MODIFY);
        } else
                /*
                 * Note this may exit with the parent still locked.
@@ -362,7 +362,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        __be32 status;
        struct svc_fh *resfh = NULL;
-       struct nfsd4_compoundres *resp;
        struct net *net = SVC_NET(rqstp);
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
@@ -389,8 +388,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                copy_clientid(&open->op_clientid, cstate->session);
 
        /* check seqid for replay. set nfs4_owner */
-       resp = rqstp->rq_resp;
-       status = nfsd4_process_open1(&resp->cstate, open, nn);
+       status = nfsd4_process_open1(cstate, open, nn);
        if (status == nfserr_replay_me) {
                struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay;
                fh_put(&cstate->current_fh);
@@ -417,10 +415,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        /* Openowner is now set, so sequence id will get bumped.  Now we need
         * these checks before we do any creates: */
        status = nfserr_grace;
-       if (locks_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
+       if (opens_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
                goto out;
        status = nfserr_no_grace;
-       if (!locks_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
+       if (!opens_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
                goto out;
 
        switch (open->op_claim_type) {
@@ -760,8 +758,6 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        __be32 status;
 
-       /* no need to check permission - this will be done in nfsd_read() */
-
        read->rd_filp = NULL;
        if (read->rd_offset >= OFFSET_MAX)
                return nfserr_inval;
@@ -778,9 +774,9 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
 
        /* check stateid */
-       if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
-                                                cstate, &read->rd_stateid,
-                                                RD_STATE, &read->rd_filp))) {
+       status = nfs4_preprocess_stateid_op(rqstp, cstate, &read->rd_stateid,
+                       RD_STATE, &read->rd_filp, &read->rd_tmp_file);
+       if (status) {
                dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
                goto out;
        }
@@ -831,7 +827,7 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        __be32 status;
 
-       if (locks_in_grace(SVC_NET(rqstp)))
+       if (opens_in_grace(SVC_NET(rqstp)))
                return nfserr_grace;
        status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
                             remove->rm_name, remove->rm_namelen);
@@ -850,7 +846,7 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        if (!cstate->save_fh.fh_dentry)
                return status;
-       if (locks_in_grace(SVC_NET(rqstp)) &&
+       if (opens_in_grace(SVC_NET(rqstp)) &&
                !(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK))
                return nfserr_grace;
        status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
@@ -924,8 +920,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        int err;
 
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
-               status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
-                       &setattr->sa_stateid, WR_STATE, NULL);
+               status = nfs4_preprocess_stateid_op(rqstp, cstate,
+                       &setattr->sa_stateid, WR_STATE, NULL, NULL);
                if (status) {
                        dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
                        return status;
@@ -986,13 +982,11 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        unsigned long cnt;
        int nvecs;
 
-       /* no need to check permission - this will be done in nfsd_write() */
-
        if (write->wr_offset >= OFFSET_MAX)
                return nfserr_inval;
 
-       status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
-                                       cstate, stateid, WR_STATE, &filp);
+       status = nfs4_preprocess_stateid_op(rqstp, cstate, stateid, WR_STATE,
+                       &filp, NULL);
        if (status) {
                dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
                return status;
@@ -1005,11 +999,10 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        nvecs = fill_in_write_vector(rqstp->rq_vec, write);
        WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
 
-       status =  nfsd_write(rqstp, &cstate->current_fh, filp,
-                            write->wr_offset, rqstp->rq_vec, nvecs,
-                            &cnt, &write->wr_how_written);
-       if (filp)
-               fput(filp);
+       status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp,
+                               write->wr_offset, rqstp->rq_vec, nvecs, &cnt,
+                               &write->wr_how_written);
+       fput(filp);
 
        write->wr_bytes_written = cnt;
 
@@ -1023,15 +1016,13 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        __be32 status = nfserr_notsupp;
        struct file *file;
 
-       status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
+       status = nfs4_preprocess_stateid_op(rqstp, cstate,
                                            &fallocate->falloc_stateid,
-                                           WR_STATE, &file);
+                                           WR_STATE, &file, NULL);
        if (status != nfs_ok) {
                dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
                return status;
        }
-       if (!file)
-               return nfserr_bad_stateid;
 
        status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
                                     fallocate->falloc_offset,
@@ -1064,15 +1055,13 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        __be32 status;
        struct file *file;
 
-       status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
+       status = nfs4_preprocess_stateid_op(rqstp, cstate,
                                            &seek->seek_stateid,
-                                           RD_STATE, &file);
+                                           RD_STATE, &file, NULL);
        if (status) {
                dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
                return status;
        }
-       if (!file)
-               return nfserr_bad_stateid;
 
        switch (seek->seek_whence) {
        case NFS4_CONTENT_DATA:
@@ -1320,6 +1309,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
        nfserr = nfsd4_insert_layout(lgp, ls);
 
 out_put_stid:
+       mutex_unlock(&ls->ls_mutex);
        nfs4_put_stid(&ls->ls_stid);
 out:
        return nfserr;
@@ -1373,9 +1363,8 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
                goto out;
        }
 
-       nfserr = ops->proc_layoutcommit(inode, lcp);
-       if (nfserr)
-               goto out_put_stid;
+       /* LAYOUTCOMMIT does not require any serialization */
+       mutex_unlock(&ls->ls_mutex);
 
        if (new_size > i_size_read(inode)) {
                lcp->lc_size_chg = 1;
@@ -1384,7 +1373,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
                lcp->lc_size_chg = 0;
        }
 
-out_put_stid:
+       nfserr = ops->proc_layoutcommit(inode, lcp);
        nfs4_put_stid(&ls->ls_stid);
 out:
        return nfserr;
@@ -1732,10 +1721,6 @@ encode_op:
                        be32_to_cpu(status));
 
                nfsd4_cstate_clear_replay(cstate);
-               /* XXX Ugh, we need to get rid of this kind of special case: */
-               if (op->opnum == OP_READ && op->u.read.rd_filp)
-                       fput(op->u.read.rd_filp);
-
                nfsd4_increment_op_stats(op->opnum);
        }