SUNRPC: Fix pointer arithmetic bug recently introduced in rpc_malloc/free

Use a cleaner method to find the size of an rpc_buffer.  This actually
works on x86-64!

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 9901451..b28a0b0 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -736,6 +736,11 @@
 	__rpc_execute(container_of(work, struct rpc_task, u.tk_work));
 }
 
+struct rpc_buffer {
+	size_t	len;
+	char	data[];
+};
+
 /**
  * rpc_malloc - allocate an RPC buffer
  * @task: RPC task that will use this buffer
@@ -754,18 +759,18 @@
  */
 void *rpc_malloc(struct rpc_task *task, size_t size)
 {
-	size_t *buf;
+	struct rpc_buffer *buf;
 	gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT;
 
-	size += sizeof(size_t);
+	size += sizeof(struct rpc_buffer);
 	if (size <= RPC_BUFFER_MAXSIZE)
 		buf = mempool_alloc(rpc_buffer_mempool, gfp);
 	else
 		buf = kmalloc(size, gfp);
-	*buf = size;
+	buf->len = size;
 	dprintk("RPC: %5u allocated buffer of size %zu at %p\n",
 			task->tk_pid, size, buf);
-	return ++buf;
+	return &buf->data;
 }
 
 /**
@@ -775,15 +780,18 @@
  */
 void rpc_free(void *buffer)
 {
-	size_t size, *buf = buffer;
+	size_t size;
+	struct rpc_buffer *buf;
 
 	if (!buffer)
 		return;
-	size = *buf;
-	buf--;
+
+	buf = container_of(buffer, struct rpc_buffer, data);
+	size = buf->len;
 
 	dprintk("RPC:       freeing buffer of size %zu at %p\n",
 			size, buf);
+
 	if (size <= RPC_BUFFER_MAXSIZE)
 		mempool_free(buf, rpc_buffer_mempool);
 	else