From: NeilBrown Signed-off-by: Andy Adamson Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/fs/nfsd/nfs4proc.c | 3 +++ 25-akpm/fs/nfsd/nfs4state.c | 16 ++++++++++++++++ 25-akpm/fs/nfsd/nfs4xdr.c | 17 +++++++++++++++++ 25-akpm/include/linux/nfsd/xdr4.h | 7 +++++++ 4 files changed, 43 insertions(+) diff -puN fs/nfsd/nfs4proc.c~knfsd-add-the-delegreturn-operation fs/nfsd/nfs4proc.c --- 25/fs/nfsd/nfs4proc.c~knfsd-add-the-delegreturn-operation Fri Dec 17 15:08:46 2004 +++ 25-akpm/fs/nfsd/nfs4proc.c Fri Dec 17 15:08:46 2004 @@ -840,6 +840,9 @@ nfsd4_proc_compound(struct svc_rqst *rqs case OP_CREATE: op->status = nfsd4_create(rqstp, current_fh, &op->u.create); break; + case OP_DELEGRETURN: + op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn); + break; case OP_GETATTR: op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr); break; diff -puN fs/nfsd/nfs4state.c~knfsd-add-the-delegreturn-operation fs/nfsd/nfs4state.c --- 25/fs/nfsd/nfs4state.c~knfsd-add-the-delegreturn-operation Fri Dec 17 15:08:46 2004 +++ 25-akpm/fs/nfsd/nfs4state.c Fri Dec 17 15:08:46 2004 @@ -2332,6 +2332,22 @@ out: return status; } +int +nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr) +{ + int status; + + if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) + goto out; + + nfs4_lock_state(); + status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET); + nfs4_unlock_state(); +out: + return status; +} + + /* * Lock owner state (byte-range locks) */ diff -puN fs/nfsd/nfs4xdr.c~knfsd-add-the-delegreturn-operation fs/nfsd/nfs4xdr.c --- 25/fs/nfsd/nfs4xdr.c~knfsd-add-the-delegreturn-operation Fri Dec 17 15:08:46 2004 +++ 25-akpm/fs/nfsd/nfs4xdr.c Fri Dec 17 15:08:46 2004 @@ -615,6 +615,18 @@ nfsd4_decode_create(struct nfsd4_compoun } static inline int +nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) +{ + DECODE_HEAD; + + READ_BUF(sizeof(stateid_t)); + READ32(dr->dr_stateid.si_generation); + COPYMEM(&dr->dr_stateid.si_opaque, sizeof(stateid_opaque_t)); + + DECODE_TAIL; +} + +static inline int nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) { return nfsd4_decode_bitmap(argp, getattr->ga_bmval); @@ -1170,6 +1182,9 @@ nfsd4_decode_compound(struct nfsd4_compo case OP_CREATE: op->status = nfsd4_decode_create(argp, &op->u.create); break; + case OP_DELEGRETURN: + op->status = nfsd4_decode_delegreturn(argp, &op->u.delegreturn); + break; case OP_GETATTR: op->status = nfsd4_decode_getattr(argp, &op->u.getattr); break; @@ -2451,6 +2466,8 @@ nfsd4_encode_operation(struct nfsd4_comp case OP_CREATE: nfsd4_encode_create(resp, op->status, &op->u.create); break; + case OP_DELEGRETURN: + break; case OP_GETATTR: op->status = nfsd4_encode_getattr(resp, op->status, &op->u.getattr); break; diff -puN include/linux/nfsd/xdr4.h~knfsd-add-the-delegreturn-operation include/linux/nfsd/xdr4.h --- 25/include/linux/nfsd/xdr4.h~knfsd-add-the-delegreturn-operation Fri Dec 17 15:08:46 2004 +++ 25-akpm/include/linux/nfsd/xdr4.h Fri Dec 17 15:08:46 2004 @@ -94,6 +94,10 @@ struct nfsd4_create { #define cr_specdata1 u.dev.specdata1 #define cr_specdata2 u.dev.specdata2 +struct nfsd4_delegreturn { + stateid_t dr_stateid; +}; + struct nfsd4_getattr { u32 ga_bmval[2]; /* request */ struct svc_fh *ga_fhp; /* response */ @@ -335,6 +339,7 @@ struct nfsd4_op { struct nfsd4_close close; struct nfsd4_commit commit; struct nfsd4_create create; + struct nfsd4_delegreturn delegreturn; struct nfsd4_getattr getattr; struct svc_fh * getfh; struct nfsd4_link link; @@ -446,6 +451,8 @@ extern int nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner); extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); +extern int nfsd4_delegreturn(struct svc_rqst *rqstp, + struct svc_fh *current_fh, struct nfsd4_delegreturn *dr); #endif /* _