]> git.hungrycats.org Git - linux/commitdiff
[PATCH] kNFSd: correctly tests and sets nfserr_nofilehandle for current and save fh.
authorAndrew Morton <akpm@osdl.org>
Thu, 26 Feb 2004 14:47:42 +0000 (06:47 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 26 Feb 2004 14:47:42 +0000 (06:47 -0800)
From: NeilBrown <neilb@cse.unsw.edu.au>

nfsd4_restore_fh() returns nfserr_restorefh instead of nfserr_nofilehandle

fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c

index a7c429b750ced09448b9335b20826726648efaf4..39ee88b7fda5625b23ed8384d0545eb347a393cf 100644 (file)
@@ -192,7 +192,7 @@ static inline int
 nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
 {
        if (!save_fh->fh_dentry)
-               return nfserr_nofilehandle;
+               return nfserr_restorefh;
 
        fh_dup2(current_fh, save_fh);
        return nfs_ok;
@@ -336,8 +336,10 @@ static inline int
 nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
           struct svc_fh *save_fh, struct nfsd4_link *link)
 {
-       int status;
+       int status = nfserr_nofilehandle;
 
+       if (!save_fh->fh_dentry)
+               return status;
        status = nfsd_link(rqstp, current_fh, link->li_name, link->li_namelen, save_fh);
        if (!status)
                set_change_info(&link->li_cinfo, current_fh);
@@ -458,8 +460,10 @@ static inline int
 nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
             struct svc_fh *save_fh, struct nfsd4_rename *rename)
 {
-       int status;
+       int status = nfserr_nofilehandle;
 
+       if (!save_fh->fh_dentry)
+               return status;
        status = nfsd_rename(rqstp, save_fh, rename->rn_sname,
                             rename->rn_snamelen, current_fh,
                             rename->rn_tname, rename->rn_tnamelen);
@@ -474,8 +478,12 @@ static inline int
 nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
 {
        struct nfs4_stateid *stp;
-       int status = nfs_ok;
+       int status = nfserr_nofilehandle;
+
+       if (!current_fh->fh_dentry)
+               goto out;
 
+       status = nfs_ok;
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
 
                status = nfserr_bad_stateid;
@@ -679,6 +687,22 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                        goto encode_op;
                }
 
+               /* All operations except RENEW, SETCLIENTID, RESTOREFH
+               * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
+               * require a valid current filehandle
+               *
+               * SETATTR NOFILEHANDLE error handled in nfsd4_setattr
+               * due to required returned bitmap argument
+               */
+               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_SETATTR))) {
+                       op->status = nfserr_nofilehandle;
+                       goto encode_op;
+               }
                switch (op->opnum) {
                case OP_ACCESS:
                        op->status = nfsd4_access(rqstp, &current_fh, &op->u.access);
index 1f191e3cc96ff8fb291a415d7def59ded8f56c94..6223ac91cc33abfcdf595b9be887e3a5ebdc9ce7 100644 (file)
@@ -2226,8 +2226,14 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 
        RESERVE_SPACE(8);
        WRITE32(op->opnum);
-       statp = p++;                  /* to be backfilled at the end */
-       ADJUST_ARGS();
+       if ((op->opnum != OP_SETATTR) && (op->opnum != OP_LOCK) && (op->opnum != OP_LOCKT) && (op->opnum != OP_SETCLIENTID) && (op->status)) {
+               *p++ = op->status;
+               ADJUST_ARGS();
+               return;
+       } else {
+               statp = p++;        /* to be backfilled at the end */
+               ADJUST_ARGS();
+       }
 
        switch (op->opnum) {
        case OP_ACCESS: