VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / nfsd / nfs4proc.c
index d54c85a..ff8c203 100644 (file)
@@ -135,9 +135,11 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
 {
        int status;
 
-       dprintk("NFSD: do_open_fhandle\n");
+       /* Only reclaims from previously confirmed clients are valid */
+       if ((status = nfs4_check_open_reclaim(&open->op_clientid)))
+               return status;
 
-       /* we don't know the target directory, and therefore can not
+       /* We don't know the target directory, and therefore can not
        * set the change info
        */
 
@@ -172,8 +174,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
        if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
                return nfserr_grace;
 
-       if (nfs4_in_no_grace() &&
-                          open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
+       if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
                return nfserr_no_grace;
 
        /* This check required by spec. */
@@ -318,7 +319,7 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com
        return status;
 }
 
-static inline int
+static int
 nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create)
 {
        struct svc_fh resfh;
@@ -435,7 +436,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
        return status;
 }
 
-static inline int
+static int
 nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
 {
        struct svc_fh tmp_fh;
@@ -773,13 +774,20 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                    struct nfsd4_compoundres *resp)
 {
        struct nfsd4_op *op;
-       struct svc_fh   current_fh;
-       struct svc_fh   save_fh;
+       struct svc_fh   *current_fh = NULL;
+       struct svc_fh   *save_fh = NULL;
        int             slack_space;    /* in words, not bytes! */
        int             status;
 
-       fh_init(&current_fh, NFS4_FHSIZE);
-       fh_init(&save_fh, NFS4_FHSIZE);
+       status = nfserr_resource;
+       current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL);
+       if (current_fh == NULL)
+               goto out;
+       fh_init(current_fh, NFS4_FHSIZE);
+       save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL);
+       if (save_fh == NULL)
+               goto out;
+       fh_init(save_fh, NFS4_FHSIZE);
 
        resp->xbuf = &rqstp->rq_res;
        resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len;
@@ -831,7 +839,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                * SETATTR NOFILEHANDLE error handled in nfsd4_setattr
                * due to required returned bitmap argument
                */
-               if ((!current_fh.fh_dentry) &&
+               if ((!current_fh->fh_dentry) &&
                   !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) ||
                   (op->opnum == OP_SETCLIENTID) ||
                   (op->opnum == OP_SETCLIENTID_CONFIRM) ||
@@ -843,105 +851,105 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                }
                switch (op->opnum) {
                case OP_ACCESS:
-                       op->status = nfsd4_access(rqstp, &current_fh, &op->u.access);
+                       op->status = nfsd4_access(rqstp, current_fh, &op->u.access);
                        break;
                case OP_CLOSE:
-                       op->status = nfsd4_close(rqstp, &current_fh, &op->u.close);
+                       op->status = nfsd4_close(rqstp, current_fh, &op->u.close);
                        if (op->u.close.cl_stateowner)
                                op->replay =
                                        &op->u.close.cl_stateowner->so_replay;
                        break;
                case OP_COMMIT:
-                       op->status = nfsd4_commit(rqstp, &current_fh, &op->u.commit);
+                       op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit);
                        break;
                case OP_CREATE:
-                       op->status = nfsd4_create(rqstp, &current_fh, &op->u.create);
+                       op->status = nfsd4_create(rqstp, current_fh, &op->u.create);
                        break;
                case OP_GETATTR:
-                       op->status = nfsd4_getattr(rqstp, &current_fh, &op->u.getattr);
+                       op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr);
                        break;
                case OP_GETFH:
-                       op->status = nfsd4_getfh(&current_fh, &op->u.getfh);
+                       op->status = nfsd4_getfh(current_fh, &op->u.getfh);
                        break;
                case OP_LINK:
-                       op->status = nfsd4_link(rqstp, &current_fh, &save_fh, &op->u.link);
+                       op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link);
                        break;
                case OP_LOCK:
-                       op->status = nfsd4_lock(rqstp, &current_fh, &op->u.lock);
+                       op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock);
                        if (op->u.lock.lk_stateowner)
                                op->replay =
                                        &op->u.lock.lk_stateowner->so_replay;
                        break;
                case OP_LOCKT:
-                       op->status = nfsd4_lockt(rqstp, &current_fh, &op->u.lockt);
+                       op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt);
                        break;
                case OP_LOCKU:
-                       op->status = nfsd4_locku(rqstp, &current_fh, &op->u.locku);
+                       op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku);
                        if (op->u.locku.lu_stateowner)
                                op->replay =
                                        &op->u.locku.lu_stateowner->so_replay;
                        break;
                case OP_LOOKUP:
-                       op->status = nfsd4_lookup(rqstp, &current_fh, &op->u.lookup);
+                       op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup);
                        break;
                case OP_LOOKUPP:
-                       op->status = nfsd4_lookupp(rqstp, &current_fh);
+                       op->status = nfsd4_lookupp(rqstp, current_fh);
                        break;
                case OP_NVERIFY:
-                       op->status = nfsd4_verify(rqstp, &current_fh, &op->u.nverify);
+                       op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify);
                        if (op->status == nfserr_not_same)
                                op->status = nfs_ok;
                        break;
                case OP_OPEN:
-                       op->status = nfsd4_open(rqstp, &current_fh, &op->u.open);
+                       op->status = nfsd4_open(rqstp, current_fh, &op->u.open);
                        if (op->u.open.op_stateowner)
                                op->replay =
                                        &op->u.open.op_stateowner->so_replay;
                        break;
                case OP_OPEN_CONFIRM:
-                       op->status = nfsd4_open_confirm(rqstp, &current_fh, &op->u.open_confirm);
+                       op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm);
                        if (op->u.open_confirm.oc_stateowner)
                                op->replay =
                                        &op->u.open_confirm.oc_stateowner->so_replay;
                        break;
                case OP_OPEN_DOWNGRADE:
-                       op->status = nfsd4_open_downgrade(rqstp, &current_fh, &op->u.open_downgrade);
+                       op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade);
                        if (op->u.open_downgrade.od_stateowner)
                                op->replay =
                                        &op->u.open_downgrade.od_stateowner->so_replay;
                        break;
                case OP_PUTFH:
-                       op->status = nfsd4_putfh(rqstp, &current_fh, &op->u.putfh);
+                       op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh);
                        break;
                case OP_PUTROOTFH:
-                       op->status = nfsd4_putrootfh(rqstp, &current_fh);
+                       op->status = nfsd4_putrootfh(rqstp, current_fh);
                        break;
                case OP_READ:
-                       op->status = nfsd4_read(rqstp, &current_fh, &op->u.read);
+                       op->status = nfsd4_read(rqstp, current_fh, &op->u.read);
                        break;
                case OP_READDIR:
-                       op->status = nfsd4_readdir(rqstp, &current_fh, &op->u.readdir);
+                       op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir);
                        break;
                case OP_READLINK:
-                       op->status = nfsd4_readlink(rqstp, &current_fh, &op->u.readlink);
+                       op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink);
                        break;
                case OP_REMOVE:
-                       op->status = nfsd4_remove(rqstp, &current_fh, &op->u.remove);
+                       op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove);
                        break;
                case OP_RENAME:
-                       op->status = nfsd4_rename(rqstp, &current_fh, &save_fh, &op->u.rename);
+                       op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename);
                        break;
                case OP_RENEW:
                        op->status = nfsd4_renew(&op->u.renew);
                        break;
                case OP_RESTOREFH:
-                       op->status = nfsd4_restorefh(&current_fh, &save_fh);
+                       op->status = nfsd4_restorefh(current_fh, save_fh);
                        break;
                case OP_SAVEFH:
-                       op->status = nfsd4_savefh(&current_fh, &save_fh);
+                       op->status = nfsd4_savefh(current_fh, save_fh);
                        break;
                case OP_SETATTR:
-                       op->status = nfsd4_setattr(rqstp, &current_fh, &op->u.setattr);
+                       op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr);
                        break;
                case OP_SETCLIENTID:
                        op->status = nfsd4_setclientid(rqstp, &op->u.setclientid);
@@ -950,12 +958,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                        op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm);
                        break;
                case OP_VERIFY:
-                       op->status = nfsd4_verify(rqstp, &current_fh, &op->u.verify);
+                       op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify);
                        if (op->status == nfserr_same)
                                op->status = nfs_ok;
                        break;
                case OP_WRITE:
-                       op->status = nfsd4_write(rqstp, &current_fh, &op->u.write);
+                       op->status = nfsd4_write(rqstp, current_fh, &op->u.write);
                        break;
                case OP_RELEASE_LOCKOWNER:
                        op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner);
@@ -976,22 +984,13 @@ encode_op:
        }
 
 out:
-       if (args->ops != args->iops) {
-               kfree(args->ops);
-               args->ops = args->iops;
-       }
-       if (args->tmpp) {
-               kfree(args->tmpp);
-               args->tmpp = NULL;
-       }
-       while (args->to_free) {
-               struct tmpbuf *tb = args->to_free;
-               args->to_free = tb->next;
-               kfree(tb->buf);
-               kfree(tb);
-       }
-       fh_put(&current_fh);
-       fh_put(&save_fh);
+       nfsd4_release_compoundargs(args);
+       if (current_fh)
+               fh_put(current_fh);
+       kfree(current_fh);
+       if (save_fh)
+               fh_put(save_fh);
+       kfree(save_fh);
        return status;
 }