

Declare a new struct rpc_upcall_info to be added to struct rpc_cred_cache to 
bookeep a common upcall interface for all gss security mechanisms using the
common credcache. The struct rpc_cred_cache reference counting is sufficient 
to protect this addiion.
The first fsid that exports AUTH_GSS will create the upcall pipe.

Signed-off-by: Andy Adamson <andros@citi.umich.edu>
---


diff -puN include/linux/sunrpc/auth.h~gss-common-upcall-init include/linux/sunrpc/auth.h
--- linux-2.6.18-rc5/include/linux/sunrpc/auth.h~gss-common-upcall-init	2006-10-17 15:05:43.000000000 -0400
+++ linux-2.6.18-rc5-andros/include/linux/sunrpc/auth.h	2006-10-17 15:05:43.000000000 -0400
@@ -59,8 +59,17 @@ struct rpc_cred {
  */
 #define RPC_CREDCACHE_NR	8
 #define RPC_CREDCACHE_MASK	(RPC_CREDCACHE_NR - 1)
+struct rpc_upcall_info {
+	struct list_head	upcalls;        /* upcalls in progress */
+	spinlock_t		lock;           /* protects upcall list */
+	u32			mkey;           /* message key enumerator */
+	wait_queue_head_t	waitqueue;      /* RPC task waiting on upcall */
+	struct dentry		*dentry;        /* upcall pipe */
+};
+
 struct rpc_cred_cache {
 	struct hlist_head	hashtable[RPC_CREDCACHE_NR];
+	struct rpc_upcall_info	*info;     /* common gss upcall */
 	struct kref		ref;
 	struct list_head        auth_list; /* cred cache entry auth types */
 };
@@ -162,6 +171,7 @@ void			rpcauth_invalcred(struct rpc_task
 int			rpcauth_uptodatecred(struct rpc_task *);
 int			rpcauth_init_credcache(struct rpc_clnt *);
 void			rpcauth_free_credcache(struct rpc_clnt *);
+struct rpc_upcall_info * rpcauth_create_upcall_info(void);
 
 static inline
 struct rpc_cred *	get_rpccred(struct rpc_cred *cred)
diff -puN net/sunrpc/auth.c~gss-common-upcall-init net/sunrpc/auth.c
--- linux-2.6.18-rc5/net/sunrpc/auth.c~gss-common-upcall-init	2006-10-17 15:05:43.000000000 -0400
+++ linux-2.6.18-rc5-andros/net/sunrpc/auth.c	2006-10-17 15:05:43.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/errno.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/spinlock.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_AUTH
@@ -61,6 +62,33 @@ rpcauth_unregister(struct rpc_authops *o
 	return 0;
 }
 
+struct rpc_upcall_info *
+rpcauth_create_upcall_info(void)
+{
+	struct rpc_upcall_info *info;
+
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		info = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+	INIT_LIST_HEAD(&info->upcalls);
+	spin_lock_init(&info->lock);
+	info->mkey = 0;
+	init_waitqueue_head(&info->waitqueue);
+	info->dentry = NULL;
+out:
+	return info;
+}
+
+/*Caller releases rpc_upcall_info->upcalls */
+void
+rpcauth_free_upcall_info(struct rpc_upcall_info *info)
+{
+	rpc_unlink(info->dentry);
+	kfree(info);
+}
+
 static DEFINE_SPINLOCK(rpc_credcache_lock);
 
 static struct rpc_auth *
@@ -140,6 +168,7 @@ rpcauth_init_credcache(struct rpc_clnt *
 	err = 0;
 	for (i = 0; i < RPC_CREDCACHE_NR; i++)
 		INIT_HLIST_HEAD(&new->hashtable[i]);
+	new->info = NULL;
 	kref_init(&new->ref);
 	INIT_LIST_HEAD(&new->auth_list);
 done:
_
