From 62c4f3f69a5ea26c0dba196c51f1d88f6e9ea2eb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 26 Feb 2004 06:47:42 -0800 Subject: [PATCH] [PATCH] kNFSd: correctly tests and sets nfserr_nofilehandle for current and save fh. From: NeilBrown nfsd4_restore_fh() returns nfserr_restorefh instead of nfserr_nofilehandle --- fs/nfsd/nfs4proc.c | 32 ++++++++++++++++++++++++++++---- fs/nfsd/nfs4xdr.c | 10 ++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a7c429b750ced..39ee88b7fda56 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -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, ¤t_fh, &op->u.access); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 1f191e3cc96ff..6223ac91cc33a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -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: -- 2.53.0