RPCSEC_GSS: cleanup au_rslack calculation

 Various xdr encode routines use au_rslack to guess where the reply argument
 will end up, so we can set up the xdr_buf to recieve data into the right place
 for zero copy.

 Currently we calculate the au_rslack estimate when we check the verifier.
 Normally this only depends on the verifier size.  In the integrity case we add
 a few bytes to allow for a length and sequence number.

 It's a bit simpler to calculate only the verifier size when we check the
 verifier, and delay the full calculation till we unwrap.

 Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 04ebc24..b68c11a 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -66,7 +66,12 @@
 
 struct rpc_auth {
 	unsigned int		au_cslack;	/* call cred size estimate */
-	unsigned int		au_rslack;	/* reply verf size guess */
+				/* guess at number of u32's auth adds before
+				 * reply data; normally the verifier size: */
+	unsigned int		au_rslack;
+				/* for gss, used to calculate au_rslack: */
+	unsigned int		au_verfsize;
+
 	unsigned int		au_flags;	/* various flags */
 	struct rpc_authops *	au_ops;		/* operations */
 	rpc_authflavor_t	au_flavor;	/* pseudoflavor (note may
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index d2b08f1..dc95b79 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -886,8 +886,6 @@
 gss_validate(struct rpc_task *task, u32 *p)
 {
 	struct rpc_cred *cred = task->tk_msg.rpc_cred;
-	struct gss_cred	*gss_cred = container_of(cred, struct gss_cred,
-						gc_base);
 	struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
 	u32		seq, qop_state;
 	struct kvec	iov;
@@ -915,18 +913,9 @@
 		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
 	if (maj_stat)
 		goto out_bad;
-       switch (gss_cred->gc_service) {
-       case RPC_GSS_SVC_NONE:
-	       /* verifier data, flavor, length: */
-	       task->tk_auth->au_rslack = XDR_QUADLEN(len) + 2;
-	       break;
-       case RPC_GSS_SVC_INTEGRITY:
-	       /* verifier data, flavor, length, length, sequence number: */
-	       task->tk_auth->au_rslack = XDR_QUADLEN(len) + 4;
-	       break;
-       case RPC_GSS_SVC_PRIVACY:
-	       goto out_bad;
-       }
+	/* We leave it to unwrap to calculate au_rslack. For now we just
+	 * calculate the length of the verifier: */
+	task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2;
 	gss_put_ctx(ctx);
 	dprintk("RPC: %4u GSS gss_validate: gss_verify_mic succeeded.\n",
 			task->tk_pid);
@@ -1067,6 +1056,7 @@
 	struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
 			gc_base);
 	struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
+	u32		*savedp = p;
 	int             status = -EIO;
 
 	if (ctx->gc_proc != RPC_GSS_PROC_DATA)
@@ -1082,6 +1072,8 @@
        		case RPC_GSS_SVC_PRIVACY:
 			break;
 	}
+	/* take into account extra slack for integrity and privacy cases: */
+	task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp);
 out_decode:
 	status = decode(rqstp, p, obj);
 out: