Merge branch 'audit.b32' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit...
[pandora-kernel.git] / fs / nfsd / nfs4proc.c
index b0e095e..8333db1 100644 (file)
@@ -600,7 +600,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
                        &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
                nfs4_unlock_state();
                if (status) {
-                       dprintk("NFSD: nfsd4_setattr: couldn't process stateid!");
+                       dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
                        return status;
                }
        }
@@ -646,7 +646,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
        *p++ = nfssvc_boot.tv_usec;
 
        status =  nfsd_write(rqstp, current_fh, filp, write->wr_offset,
-                       write->wr_vec, write->wr_vlen, write->wr_buflen,
+                       rqstp->rq_vec, write->wr_vlen, write->wr_buflen,
                        &write->wr_how_written);
        if (filp)
                fput(filp);
@@ -721,6 +721,12 @@ nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
        return nfs_ok;
 }
 
+static inline void nfsd4_increment_op_stats(u32 opnum)
+{
+       if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
+               nfsdstats.nfs4_opcount[opnum]++;
+}
+
 
 /*
  * COMPOUND call.
@@ -796,13 +802,29 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
                * require a valid current filehandle
                */
-               if ((!current_fh->fh_dentry) &&
-                  !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) ||
-                  (op->opnum == OP_SETCLIENTID) ||
-                  (op->opnum == OP_SETCLIENTID_CONFIRM) ||
-                  (op->opnum == OP_RENEW) || (op->opnum == OP_RESTOREFH) ||
-                  (op->opnum == OP_RELEASE_LOCKOWNER))) {
-                       op->status = nfserr_nofilehandle;
+               if (!current_fh->fh_dentry) {
+                       if (!((op->opnum == OP_PUTFH) ||
+                             (op->opnum == OP_PUTROOTFH) ||
+                             (op->opnum == OP_SETCLIENTID) ||
+                             (op->opnum == OP_SETCLIENTID_CONFIRM) ||
+                             (op->opnum == OP_RENEW) ||
+                             (op->opnum == OP_RESTOREFH) ||
+                             (op->opnum == OP_RELEASE_LOCKOWNER))) {
+                               op->status = nfserr_nofilehandle;
+                               goto encode_op;
+                       }
+               }
+               /* Check must be done at start of each operation, except
+                * for GETATTR and ops not listed as returning NFS4ERR_MOVED
+                */
+               else if (current_fh->fh_export->ex_fslocs.migrated &&
+                        !((op->opnum == OP_GETATTR) ||
+                          (op->opnum == OP_PUTROOTFH) ||
+                          (op->opnum == OP_PUTPUBFH) ||
+                          (op->opnum == OP_RENEW) ||
+                          (op->opnum == OP_SETCLIENTID) ||
+                          (op->opnum == OP_RELEASE_LOCKOWNER))) {
+                       op->status = nfserr_moved;
                        goto encode_op;
                }
                switch (op->opnum) {
@@ -930,6 +952,8 @@ encode_op:
                /* 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);
        }
 
 out: