
From: NeilBrown <neilb@cse.unsw.edu.au>

Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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
 
 /*
_
