Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
new file mode 100644
index 0000000..04ebc24
--- /dev/null
+++ b/include/linux/sunrpc/auth.h
@@ -0,0 +1,149 @@
+/*
+ * linux/include/linux/sunrpc/auth.h
+ *
+ * Declarations for the RPC client authentication machinery.
+ *
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_AUTH_H
+#define _LINUX_SUNRPC_AUTH_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/xdr.h>
+
+#include <asm/atomic.h>
+
+/* size of the nodename buffer */
+#define UNX_MAXNODENAME	32
+
+/* Maximum size (in bytes) of an rpc credential or verifier */
+#define RPC_MAX_AUTH_SIZE (400)
+
+/* Work around the lack of a VFS credential */
+struct auth_cred {
+	uid_t	uid;
+	gid_t	gid;
+	struct group_info *group_info;
+};
+
+/*
+ * Client user credentials
+ */
+struct rpc_cred {
+	struct hlist_node	cr_hash;	/* hash chain */
+	struct rpc_credops *	cr_ops;
+	unsigned long		cr_expire;	/* when to gc */
+	atomic_t		cr_count;	/* ref count */
+	unsigned short		cr_flags;	/* various flags */
+#ifdef RPC_DEBUG
+	unsigned long		cr_magic;	/* 0x0f4aa4f0 */
+#endif
+
+	uid_t			cr_uid;
+
+	/* per-flavor data */
+};
+#define RPCAUTH_CRED_LOCKED	0x0001
+#define RPCAUTH_CRED_UPTODATE	0x0002
+
+#define RPCAUTH_CRED_MAGIC	0x0f4aa4f0
+
+/*
+ * Client authentication handle
+ */
+#define RPC_CREDCACHE_NR	8
+#define RPC_CREDCACHE_MASK	(RPC_CREDCACHE_NR - 1)
+struct rpc_cred_cache {
+	struct hlist_head	hashtable[RPC_CREDCACHE_NR];
+	unsigned long		nextgc;		/* next garbage collection */
+	unsigned long		expire;		/* cache expiry interval */
+};
+
+struct rpc_auth {
+	unsigned int		au_cslack;	/* call cred size estimate */
+	unsigned int		au_rslack;	/* reply verf size guess */
+	unsigned int		au_flags;	/* various flags */
+	struct rpc_authops *	au_ops;		/* operations */
+	rpc_authflavor_t	au_flavor;	/* pseudoflavor (note may
+						 * differ from the flavor in
+						 * au_ops->au_flavor in gss
+						 * case) */
+	atomic_t		au_count;	/* Reference counter */
+
+	struct rpc_cred_cache *	au_credcache;
+	/* per-flavor data */
+};
+#define RPC_AUTH_PROC_CREDS	0x0010		/* process creds (including
+						 * uid/gid, fs[ug]id, gids)
+						 */
+
+/*
+ * Client authentication ops
+ */
+struct rpc_authops {
+	struct module		*owner;
+	rpc_authflavor_t	au_flavor;	/* flavor (RPC_AUTH_*) */
+#ifdef RPC_DEBUG
+	char *			au_name;
+#endif
+	struct rpc_auth *	(*create)(struct rpc_clnt *, rpc_authflavor_t);
+	void			(*destroy)(struct rpc_auth *);
+
+	struct rpc_cred *	(*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
+	struct rpc_cred *	(*crcreate)(struct rpc_auth*, struct auth_cred *, int);
+};
+
+struct rpc_credops {
+	const char *		cr_name;	/* Name of the auth flavour */
+	void			(*crdestroy)(struct rpc_cred *);
+
+	int			(*crmatch)(struct auth_cred *, struct rpc_cred *, int);
+	u32 *			(*crmarshal)(struct rpc_task *, u32 *);
+	int			(*crrefresh)(struct rpc_task *);
+	u32 *			(*crvalidate)(struct rpc_task *, u32 *);
+	int			(*crwrap_req)(struct rpc_task *, kxdrproc_t,
+						void *, u32 *, void *);
+	int			(*crunwrap_resp)(struct rpc_task *, kxdrproc_t,
+						void *, u32 *, void *);
+};
+
+extern struct rpc_authops	authunix_ops;
+extern struct rpc_authops	authnull_ops;
+#ifdef CONFIG_SUNRPC_SECURE
+extern struct rpc_authops	authdes_ops;
+#endif
+
+int			rpcauth_register(struct rpc_authops *);
+int			rpcauth_unregister(struct rpc_authops *);
+struct rpc_auth *	rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
+void			rpcauth_destroy(struct rpc_auth *);
+struct rpc_cred *	rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
+struct rpc_cred *	rpcauth_lookupcred(struct rpc_auth *, int);
+struct rpc_cred *	rpcauth_bindcred(struct rpc_task *);
+void			rpcauth_holdcred(struct rpc_task *);
+void			put_rpccred(struct rpc_cred *);
+void			rpcauth_unbindcred(struct rpc_task *);
+u32 *			rpcauth_marshcred(struct rpc_task *, u32 *);
+u32 *			rpcauth_checkverf(struct rpc_task *, u32 *);
+int			rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, u32 *data, void *obj);
+int			rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, u32 *data, void *obj);
+int			rpcauth_refreshcred(struct rpc_task *);
+void			rpcauth_invalcred(struct rpc_task *);
+int			rpcauth_uptodatecred(struct rpc_task *);
+int			rpcauth_init_credcache(struct rpc_auth *, unsigned long);
+void			rpcauth_free_credcache(struct rpc_auth *);
+
+static inline
+struct rpc_cred *	get_rpccred(struct rpc_cred *cred)
+{
+	atomic_inc(&cred->cr_count);
+	return cred;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_AUTH_H */
diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
new file mode 100644
index 0000000..03084dc
--- /dev/null
+++ b/include/linux/sunrpc/auth_gss.h
@@ -0,0 +1,97 @@
+/*
+ * linux/include/linux/auth_gss.h
+ *
+ * Declarations for RPCSEC_GSS
+ *
+ * Dug Song <dugsong@monkey.org>
+ * Andy Adamson <andros@umich.edu>
+ * Bruce Fields <bfields@umich.edu>
+ * Copyright (c) 2000 The Regents of the University of Michigan
+ *
+ * $Id$
+ */
+
+#ifndef _LINUX_SUNRPC_AUTH_GSS_H
+#define _LINUX_SUNRPC_AUTH_GSS_H
+
+#ifdef __KERNEL__
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/gss_api.h>
+
+#define RPC_GSS_VERSION		1
+
+#define MAXSEQ 0x80000000 /* maximum legal sequence number, from rfc 2203 */
+
+enum rpc_gss_proc {
+	RPC_GSS_PROC_DATA = 0,
+	RPC_GSS_PROC_INIT = 1,
+	RPC_GSS_PROC_CONTINUE_INIT = 2,
+	RPC_GSS_PROC_DESTROY = 3
+};
+
+enum rpc_gss_svc {
+	RPC_GSS_SVC_NONE = 1,
+	RPC_GSS_SVC_INTEGRITY = 2,
+	RPC_GSS_SVC_PRIVACY = 3
+};
+
+/* on-the-wire gss cred: */
+struct rpc_gss_wire_cred {
+	u32			gc_v;		/* version */
+	u32			gc_proc;	/* control procedure */
+	u32			gc_seq;		/* sequence number */
+	u32			gc_svc;		/* service */
+	struct xdr_netobj	gc_ctx;		/* context handle */
+};
+
+/* on-the-wire gss verifier: */
+struct rpc_gss_wire_verf {
+	u32			gv_flavor;
+	struct xdr_netobj	gv_verf;
+};
+
+/* return from gss NULL PROC init sec context */
+struct rpc_gss_init_res {
+	struct xdr_netobj	gr_ctx;		/* context handle */
+	u32			gr_major;	/* major status */
+	u32			gr_minor;	/* minor status */
+	u32			gr_win;		/* sequence window */
+	struct xdr_netobj	gr_token;	/* token */
+};
+
+/* The gss_cl_ctx struct holds all the information the rpcsec_gss client
+ * code needs to know about a single security context.  In particular,
+ * gc_gss_ctx is the context handle that is used to do gss-api calls, while
+ * gc_wire_ctx is the context handle that is used to identify the context on
+ * the wire when communicating with a server. */
+
+struct gss_cl_ctx {
+	atomic_t		count;
+	enum rpc_gss_proc	gc_proc;
+	u32			gc_seq;
+	spinlock_t		gc_seq_lock;
+	struct gss_ctx		*gc_gss_ctx;
+	struct xdr_netobj	gc_wire_ctx;
+	u32			gc_win;
+	unsigned long		gc_expiry;
+};
+
+struct gss_upcall_msg;
+struct gss_cred {
+	struct rpc_cred		gc_base;
+	enum rpc_gss_svc	gc_service;
+	struct gss_cl_ctx	*gc_ctx;
+	struct gss_upcall_msg	*gc_upcall;
+};
+
+#define gc_uid			gc_base.cr_uid
+#define gc_count		gc_base.cr_count
+#define gc_flags		gc_base.cr_flags
+#define gc_expire		gc_base.cr_expire
+
+void print_hexl(u32 *p, u_int length, u_int offset);
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_AUTH_GSS_H */
+
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
new file mode 100644
index 0000000..6864063
--- /dev/null
+++ b/include/linux/sunrpc/cache.h
@@ -0,0 +1,312 @@
+/*
+ * include/linux/sunrpc/cache.h
+ *
+ * Generic code for various authentication-related caches
+ * used by sunrpc clients and servers.
+ *
+ * Copyright (C) 2002 Neil Brown <neilb@cse.unsw.edu.au>
+ *
+ * Released under terms in GPL version 2.  See COPYING.
+ *
+ */
+
+#ifndef _LINUX_SUNRPC_CACHE_H_
+#define _LINUX_SUNRPC_CACHE_H_
+
+#include <linux/slab.h>
+#include <asm/atomic.h>
+#include <linux/proc_fs.h>
+
+/*
+ * Each cache requires:
+ *  - A 'struct cache_detail' which contains information specific to the cache
+ *    for common code to use.
+ *  - An item structure that must contain a "struct cache_head"
+ *  - A lookup function defined using DefineCacheLookup
+ *  - A 'put' function that can release a cache item. It will only
+ *    be called after cache_put has succeed, so there are guarantee
+ *    to be no references.
+ *  - A function to calculate a hash of an item's key.
+ *
+ * as well as assorted code fragments (e.g. compare keys) and numbers
+ * (e.g. hash size, goal_age, etc).
+ *
+ * Each cache must be registered so that it can be cleaned regularly.
+ * When the cache is unregistered, it is flushed completely.
+ *
+ * Entries have a ref count and a 'hashed' flag which counts the existance
+ * in the hash table.
+ * We only expire entries when refcount is zero.
+ * Existance in the cache is counted  the refcount.
+ */
+
+/* Every cache item has a common header that is used
+ * for expiring and refreshing entries.
+ * 
+ */
+struct cache_head {
+	struct cache_head * next;
+	time_t		expiry_time;	/* After time time, don't use the data */
+	time_t		last_refresh;   /* If CACHE_PENDING, this is when upcall 
+					 * was sent, else this is when update was received
+					 */
+	atomic_t 	refcnt;
+	unsigned long	flags;
+};
+#define	CACHE_VALID	0	/* Entry contains valid data */
+#define	CACHE_NEGATIVE	1	/* Negative entry - there is no match for the key */
+#define	CACHE_PENDING	2	/* An upcall has been sent but no reply received yet*/
+
+#define	CACHE_NEW_EXPIRY 120	/* keep new things pending confirmation for 120 seconds */
+
+struct cache_detail {
+	int			hash_size;
+	struct cache_head **	hash_table;
+	rwlock_t		hash_lock;
+
+	atomic_t		inuse; /* active user-space update or lookup */
+
+	char			*name;
+	void			(*cache_put)(struct cache_head *,
+					     struct cache_detail*);
+
+	void			(*cache_request)(struct cache_detail *cd,
+						 struct cache_head *h,
+						 char **bpp, int *blen);
+	int			(*cache_parse)(struct cache_detail *,
+					       char *buf, int len);
+
+	int			(*cache_show)(struct seq_file *m,
+					      struct cache_detail *cd,
+					      struct cache_head *h);
+
+	/* fields below this comment are for internal use
+	 * and should not be touched by cache owners
+	 */
+	time_t			flush_time;		/* flush all cache items with last_refresh
+							 * earlier than this */
+	struct list_head	others;
+	time_t			nextcheck;
+	int			entries;
+
+	/* fields for communication over channel */
+	struct list_head	queue;
+	struct proc_dir_entry	*proc_ent;
+	struct proc_dir_entry   *flush_ent, *channel_ent, *content_ent;
+
+	atomic_t		readers;		/* how many time is /chennel open */
+	time_t			last_close;		/* if no readers, when did last close */
+	time_t			last_warn;		/* when we last warned about no readers */
+	void			(*warn_no_listener)(struct cache_detail *cd);
+};
+
+
+/* this must be embedded in any request structure that
+ * identifies an object that will want a callback on
+ * a cache fill
+ */
+struct cache_req {
+	struct cache_deferred_req *(*defer)(struct cache_req *req);
+};
+/* this must be embedded in a deferred_request that is being
+ * delayed awaiting cache-fill
+ */
+struct cache_deferred_req {
+	struct list_head	hash;	/* on hash chain */
+	struct list_head	recent; /* on fifo */
+	struct cache_head	*item;  /* cache item we wait on */
+	time_t			recv_time;
+	void			*owner; /* we might need to discard all defered requests
+					 * owned by someone */
+	void			(*revisit)(struct cache_deferred_req *req,
+					   int too_many);
+};
+
+/*
+ * just like a template in C++, this macro does cache lookup
+ * for us.
+ * The function is passed some sort of HANDLE from which a cache_detail
+ * structure can be determined (via SETUP, DETAIL), a template
+ * cache entry (type RTN*), and a "set" flag.  Using the HASHFN and the 
+ * TEST, the function will try to find a matching cache entry in the cache.
+ * If "set" == 0 :
+ *    If an entry is found, it is returned
+ *    If no entry is found, a new non-VALID entry is created.
+ * If "set" == 1 and INPLACE == 0 :
+ *    If no entry is found a new one is inserted with data from "template"
+ *    If a non-CACHE_VALID entry is found, it is updated from template using UPDATE
+ *    If a CACHE_VALID entry is found, a new entry is swapped in with data
+ *       from "template"
+ * If set == 1, and INPLACE == 1 :
+ *    As above, except that if a CACHE_VALID entry is found, we UPDATE in place
+ *       instead of swapping in a new entry.
+ *
+ * If the passed handle has the CACHE_NEGATIVE flag set, then UPDATE is not
+ * run but insteead CACHE_NEGATIVE is set in any new item.
+
+ *  In any case, the new entry is returned with a reference count.
+ *
+ *    
+ * RTN is a struct type for a cache entry
+ * MEMBER is the member of the cache which is cache_head, which must be first
+ * FNAME is the name for the function	
+ * ARGS are arguments to function and must contain RTN *item, int set.  May
+ *   also contain something to be usedby SETUP or DETAIL to find cache_detail.
+ * SETUP  locates the cache detail and makes it available as...
+ * DETAIL identifies the cache detail, possibly set up by SETUP
+ * HASHFN returns a hash value of the cache entry "item"
+ * TEST  tests if "tmp" matches "item"
+ * INIT copies key information from "item" to "new"
+ * UPDATE copies content information from "item" to "tmp"
+ * INPLACE is true if updates can happen inplace rather than allocating a new structure
+ *
+ * WARNING: any substantial changes to this must be reflected in
+ *   net/sunrpc/svcauth.c(auth_domain_lookup)
+ *  which is a similar routine that is open-coded.
+ */
+#define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE,INPLACE)	\
+RTN *FNAME ARGS										\
+{											\
+	RTN *tmp, *new=NULL;								\
+	struct cache_head **hp, **head;							\
+	SETUP;										\
+	head = &(DETAIL)->hash_table[HASHFN];						\
+ retry:											\
+	if (set||new) write_lock(&(DETAIL)->hash_lock);					\
+	else read_lock(&(DETAIL)->hash_lock);						\
+	for(hp=head; *hp != NULL; hp = &tmp->MEMBER.next) {				\
+		tmp = container_of(*hp, RTN, MEMBER);					\
+		if (TEST) { /* found a match */						\
+											\
+			if (set && !INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \
+				break;							\
+											\
+			if (new)							\
+				{INIT;}							\
+			if (set) {							\
+				if (!INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
+				{ /* need to swap in new */				\
+					RTN *t2;					\
+											\
+					new->MEMBER.next = tmp->MEMBER.next;		\
+					*hp = &new->MEMBER;				\
+					tmp->MEMBER.next = NULL;			\
+					t2 = tmp; tmp = new; new = t2;			\
+				}							\
+				if (test_bit(CACHE_NEGATIVE,  &item->MEMBER.flags))	\
+					set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags);	\
+				else {							\
+					UPDATE;						\
+					clear_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags);	\
+				}							\
+			}								\
+			cache_get(&tmp->MEMBER);					\
+			if (set||new) write_unlock(&(DETAIL)->hash_lock);		\
+			else read_unlock(&(DETAIL)->hash_lock);				\
+			if (set)							\
+				cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \
+			if (set && !INPLACE && new) cache_fresh(DETAIL, &new->MEMBER, 0);	\
+			if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL);		\
+			return tmp;							\
+		}									\
+	}										\
+	/* Didn't find anything */							\
+	if (new) {									\
+		INIT;									\
+		new->MEMBER.next = *head;						\
+		*head = &new->MEMBER;							\
+		(DETAIL)->entries ++;							\
+		cache_get(&new->MEMBER);						\
+		if (set) {								\
+			tmp = new;							\
+			if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags))		\
+				set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags);		\
+			else {UPDATE;}							\
+		}									\
+	}										\
+	if (set||new) write_unlock(&(DETAIL)->hash_lock);				\
+	else read_unlock(&(DETAIL)->hash_lock);						\
+	if (new && set)									\
+		cache_fresh(DETAIL, &new->MEMBER, item->MEMBER.expiry_time);		\
+	if (new)				       					\
+		return new;								\
+	new = kmalloc(sizeof(*new), GFP_KERNEL);					\
+	if (new) {									\
+		cache_init(&new->MEMBER);						\
+		goto retry;								\
+	}										\
+	return NULL;									\
+}
+
+#define DefineSimpleCacheLookup(STRUCT,INPLACE)	\
+	DefineCacheLookup(struct STRUCT, h, STRUCT##_lookup, (struct STRUCT *item, int set), /*no setup */,	\
+			  & STRUCT##_cache, STRUCT##_hash(item), STRUCT##_match(item, tmp),\
+			  STRUCT##_init(new, item), STRUCT##_update(tmp, item),INPLACE)
+
+#define cache_for_each(pos, detail, index, member) 						\
+	for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ;		\
+	     ({if (index==0)read_unlock(&(detail)->hash_lock); index--;});			\
+		)										\
+		for (pos = container_of((detail)->hash_table[index], typeof(*pos), member);	\
+		     &pos->member;								\
+		     pos = container_of(pos->member.next, typeof(*pos), member))
+
+	     
+
+extern void cache_clean_deferred(void *owner);
+
+static inline struct cache_head  *cache_get(struct cache_head *h)
+{
+	atomic_inc(&h->refcnt);
+	return h;
+}
+
+
+static inline int cache_put(struct cache_head *h, struct cache_detail *cd)
+{
+	if (atomic_read(&h->refcnt) <= 2 &&
+	    h->expiry_time < cd->nextcheck)
+		cd->nextcheck = h->expiry_time;
+	return atomic_dec_and_test(&h->refcnt);
+}
+
+extern void cache_init(struct cache_head *h);
+extern void cache_fresh(struct cache_detail *detail,
+			struct cache_head *head, time_t expiry);
+extern int cache_check(struct cache_detail *detail,
+		       struct cache_head *h, struct cache_req *rqstp);
+extern void cache_flush(void);
+extern void cache_purge(struct cache_detail *detail);
+#define NEVER (0x7FFFFFFF)
+extern void cache_register(struct cache_detail *cd);
+extern int cache_unregister(struct cache_detail *cd);
+
+extern void qword_add(char **bpp, int *lp, char *str);
+extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
+extern int qword_get(char **bpp, char *dest, int bufsize);
+
+static inline int get_int(char **bpp, int *anint)
+{
+	char buf[50];
+	char *ep;
+	int rv;
+	int len = qword_get(bpp, buf, 50);
+	if (len < 0) return -EINVAL;
+	if (len ==0) return -ENOENT;
+	rv = simple_strtol(buf, &ep, 0);
+	if (*ep) return -EINVAL;
+	*anint = rv;
+	return 0;
+}
+
+static inline time_t get_expiry(char **bpp)
+{
+	int rv;
+	if (get_int(bpp, &rv))
+		return 0;
+	if (rv < 0)
+		return 0;
+	return rv;
+}
+
+#endif /*  _LINUX_SUNRPC_CACHE_H_ */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
new file mode 100644
index 0000000..2709caf
--- /dev/null
+++ b/include/linux/sunrpc/clnt.h
@@ -0,0 +1,153 @@
+/*
+ *  linux/include/linux/sunrpc/clnt.h
+ *
+ *  Declarations for the high-level RPC client interface
+ *
+ *  Copyright (C) 1995, 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_CLNT_H
+#define _LINUX_SUNRPC_CLNT_H
+
+#include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/xprt.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/timer.h>
+#include <asm/signal.h>
+
+/*
+ * This defines an RPC port mapping
+ */
+struct rpc_portmap {
+	__u32			pm_prog;
+	__u32			pm_vers;
+	__u32			pm_prot;
+	__u16			pm_port;
+	unsigned char		pm_binding : 1;	/* doing a getport() */
+	struct rpc_wait_queue	pm_bindwait;	/* waiting on getport() */
+};
+
+struct rpc_inode;
+
+/*
+ * The high-level client handle
+ */
+struct rpc_clnt {
+	atomic_t		cl_count;	/* Number of clones */
+	atomic_t		cl_users;	/* number of references */
+	struct rpc_xprt *	cl_xprt;	/* transport */
+	struct rpc_procinfo *	cl_procinfo;	/* procedure info */
+	u32			cl_maxproc;	/* max procedure number */
+
+	char *			cl_server;	/* server machine name */
+	char *			cl_protname;	/* protocol name */
+	struct rpc_auth *	cl_auth;	/* authenticator */
+	struct rpc_stat *	cl_stats;	/* statistics */
+
+	unsigned int		cl_softrtry : 1,/* soft timeouts */
+				cl_intr     : 1,/* interruptible */
+				cl_chatty   : 1,/* be verbose */
+				cl_autobind : 1,/* use getport() */
+				cl_oneshot  : 1,/* dispose after use */
+				cl_dead     : 1;/* abandoned */
+
+	struct rpc_rtt *	cl_rtt;		/* RTO estimator data */
+	struct rpc_portmap *	cl_pmap;	/* port mapping */
+
+	int			cl_nodelen;	/* nodename length */
+	char 			cl_nodename[UNX_MAXNODENAME];
+	char			cl_pathname[30];/* Path in rpc_pipe_fs */
+	struct dentry *		cl_dentry;	/* inode */
+	struct rpc_clnt *	cl_parent;	/* Points to parent of clones */
+	struct rpc_rtt		cl_rtt_default;
+	struct rpc_portmap	cl_pmap_default;
+	char			cl_inline_name[32];
+};
+#define cl_timeout		cl_xprt->timeout
+#define cl_prog			cl_pmap->pm_prog
+#define cl_vers			cl_pmap->pm_vers
+#define cl_port			cl_pmap->pm_port
+#define cl_prot			cl_pmap->pm_prot
+
+/*
+ * General RPC program info
+ */
+#define RPC_MAXVERSION		4
+struct rpc_program {
+	char *			name;		/* protocol name */
+	u32			number;		/* program number */
+	unsigned int		nrvers;		/* number of versions */
+	struct rpc_version **	version;	/* version array */
+	struct rpc_stat *	stats;		/* statistics */
+	char *			pipe_dir_name;	/* path to rpc_pipefs dir */
+};
+
+struct rpc_version {
+	u32			number;		/* version number */
+	unsigned int		nrprocs;	/* number of procs */
+	struct rpc_procinfo *	procs;		/* procedure array */
+};
+
+/*
+ * Procedure information
+ */
+struct rpc_procinfo {
+	u32			p_proc;		/* RPC procedure number */
+	kxdrproc_t		p_encode;	/* XDR encode function */
+	kxdrproc_t		p_decode;	/* XDR decode function */
+	unsigned int		p_bufsiz;	/* req. buffer size */
+	unsigned int		p_count;	/* call count */
+	unsigned int		p_timer;	/* Which RTT timer to use */
+};
+
+#define RPC_CONGESTED(clnt)	(RPCXPRT_CONGESTED((clnt)->cl_xprt))
+#define RPC_PEERADDR(clnt)	(&(clnt)->cl_xprt->addr)
+
+#ifdef __KERNEL__
+
+struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
+				struct rpc_program *info,
+				u32 version, rpc_authflavor_t authflavor);
+struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
+int		rpc_shutdown_client(struct rpc_clnt *);
+int		rpc_destroy_client(struct rpc_clnt *);
+void		rpc_release_client(struct rpc_clnt *);
+void		rpc_getport(struct rpc_task *, struct rpc_clnt *);
+int		rpc_register(u32, u32, int, unsigned short, int *);
+
+void		rpc_call_setup(struct rpc_task *, struct rpc_message *, int);
+
+int		rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg,
+			       int flags, rpc_action callback, void *clntdata);
+int		rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
+			      int flags);
+void		rpc_restart_call(struct rpc_task *);
+void		rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
+void		rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
+void		rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
+size_t		rpc_max_payload(struct rpc_clnt *);
+
+static __inline__
+int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
+{
+	struct rpc_message msg = {
+		.rpc_proc	= &clnt->cl_procinfo[proc],
+		.rpc_argp	= argp,
+		.rpc_resp	= resp,
+		.rpc_cred	= NULL
+	};
+	return rpc_call_sync(clnt, &msg, flags);
+}
+		
+extern void rpciod_wake_up(void);
+
+/*
+ * Helper function for NFSroot support
+ */
+int		rpc_getport_external(struct sockaddr_in *, __u32, __u32, int);
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
new file mode 100644
index 0000000..eadb31e
--- /dev/null
+++ b/include/linux/sunrpc/debug.h
@@ -0,0 +1,99 @@
+/*
+ * linux/include/linux/sunrpc/debug.h
+ *
+ * Debugging support for sunrpc module
+ *
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_DEBUG_H_
+#define _LINUX_SUNRPC_DEBUG_H_
+
+#include <linux/config.h>
+
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+
+/*
+ * Enable RPC debugging/profiling.
+ */
+#ifdef CONFIG_SYSCTL
+#define  RPC_DEBUG
+#endif
+/* #define  RPC_PROFILE */
+
+/*
+ * RPC debug facilities
+ */
+#define RPCDBG_XPRT		0x0001
+#define RPCDBG_CALL		0x0002
+#define RPCDBG_DEBUG		0x0004
+#define RPCDBG_NFS		0x0008
+#define RPCDBG_AUTH		0x0010
+#define RPCDBG_PMAP		0x0020
+#define RPCDBG_SCHED		0x0040
+#define RPCDBG_SVCSOCK		0x0100
+#define RPCDBG_SVCDSP		0x0200
+#define RPCDBG_MISC		0x0400
+#define RPCDBG_CACHE		0x0800
+#define RPCDBG_ALL		0x7fff
+
+#ifdef __KERNEL__
+
+/*
+ * Debugging macros etc
+ */
+#ifdef RPC_DEBUG
+extern unsigned int		rpc_debug;
+extern unsigned int		nfs_debug;
+extern unsigned int		nfsd_debug;
+extern unsigned int		nlm_debug;
+#endif
+
+#define dprintk(args...)	dfprintk(FACILITY, ## args)
+
+#undef ifdebug
+#ifdef RPC_DEBUG			
+# define ifdebug(fac)		if (unlikely(rpc_debug & RPCDBG_##fac))
+# define dfprintk(fac, args...)	do { ifdebug(fac) printk(args); } while(0)
+# define RPC_IFDEBUG(x)		x
+#else
+# define ifdebug(fac)		if (0)
+# define dfprintk(fac, args...)	do ; while (0)
+# define RPC_IFDEBUG(x)
+#endif
+
+#ifdef RPC_PROFILE
+# define pprintk(args...)	printk(## args)
+#else
+# define pprintk(args...)	do ; while (0)
+#endif
+
+/*
+ * Sysctl interface for RPC debugging
+ */
+#ifdef RPC_DEBUG
+void		rpc_register_sysctl(void);
+void		rpc_unregister_sysctl(void);
+#endif
+
+#endif /* __KERNEL__ */
+
+/*
+ * Declarations for the sysctl debug interface, which allows to read or
+ * change the debug flags for rpc, nfs, nfsd, and lockd. Since the sunrpc
+ * module currently registers its sysctl table dynamically, the sysctl path
+ * for module FOO is <CTL_SUNRPC, CTL_FOODEBUG>.
+ */
+#define CTL_SUNRPC	7249	/* arbitrary and hopefully unused */
+
+enum {
+	CTL_RPCDEBUG = 1,
+	CTL_NFSDEBUG,
+	CTL_NFSDDEBUG,
+	CTL_NLMDEBUG,
+	CTL_SLOTTABLE_UDP,
+	CTL_SLOTTABLE_TCP,
+};
+
+#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
new file mode 100644
index 0000000..689262f
--- /dev/null
+++ b/include/linux/sunrpc/gss_api.h
@@ -0,0 +1,122 @@
+/*
+ * linux/include/linux/gss_api.h
+ *
+ * Somewhat simplified version of the gss api.
+ *
+ * Dug Song <dugsong@monkey.org>
+ * Andy Adamson <andros@umich.edu>
+ * Bruce Fields <bfields@umich.edu>
+ * Copyright (c) 2000 The Regents of the University of Michigan
+ *
+ * $Id$
+ */
+
+#ifndef _LINUX_SUNRPC_GSS_API_H
+#define _LINUX_SUNRPC_GSS_API_H
+
+#ifdef __KERNEL__
+#include <linux/sunrpc/xdr.h>
+#include <linux/uio.h>
+
+/* The mechanism-independent gss-api context: */
+struct gss_ctx {
+	struct gss_api_mech	*mech_type;
+	void			*internal_ctx_id;
+};
+
+#define GSS_C_NO_BUFFER		((struct xdr_netobj) 0)
+#define GSS_C_NO_CONTEXT	((struct gss_ctx *) 0)
+#define GSS_C_NULL_OID		((struct xdr_netobj) 0)
+
+/*XXX  arbitrary length - is this set somewhere? */
+#define GSS_OID_MAX_LEN 32
+
+/* gss-api prototypes; note that these are somewhat simplified versions of
+ * the prototypes specified in RFC 2744. */
+int gss_import_sec_context(
+		const void*		input_token,
+		size_t			bufsize,
+		struct gss_api_mech	*mech,
+		struct gss_ctx		**ctx_id);
+u32 gss_get_mic(
+		struct gss_ctx		*ctx_id,
+		u32			qop,
+		struct xdr_buf		*message,
+		struct xdr_netobj	*mic_token);
+u32 gss_verify_mic(
+		struct gss_ctx		*ctx_id,
+		struct xdr_buf		*message,
+		struct xdr_netobj	*mic_token,
+		u32			*qstate);
+u32 gss_delete_sec_context(
+		struct gss_ctx		**ctx_id);
+
+u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor);
+char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
+
+struct pf_desc {
+	u32	pseudoflavor;
+	u32	qop;
+	u32	service;
+	char	*name;
+	char	*auth_domain_name;
+};
+
+/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
+ * mechanisms may be dynamically registered or unregistered by modules. */
+
+/* Each mechanism is described by the following struct: */
+struct gss_api_mech {
+	struct list_head	gm_list;
+	struct module		*gm_owner;
+	struct xdr_netobj	gm_oid;
+	char			*gm_name;
+	struct gss_api_ops	*gm_ops;
+	/* pseudoflavors supported by this mechanism: */
+	int			gm_pf_num;
+	struct pf_desc *	gm_pfs;
+};
+
+/* and must provide the following operations: */
+struct gss_api_ops {
+	int (*gss_import_sec_context)(
+			const void		*input_token,
+			size_t			bufsize,
+			struct gss_ctx		*ctx_id);
+	u32 (*gss_get_mic)(
+			struct gss_ctx		*ctx_id,
+			u32			qop, 
+			struct xdr_buf		*message,
+			struct xdr_netobj	*mic_token);
+	u32 (*gss_verify_mic)(
+			struct gss_ctx		*ctx_id,
+			struct xdr_buf		*message,
+			struct xdr_netobj	*mic_token,
+			u32			*qstate);
+	void (*gss_delete_sec_context)(
+			void			*internal_ctx_id);
+};
+
+int gss_mech_register(struct gss_api_mech *);
+void gss_mech_unregister(struct gss_api_mech *);
+
+/* returns a mechanism descriptor given an OID, and increments the mechanism's
+ * reference count. */
+struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *);
+
+/* Returns a reference to a mechanism, given a name like "krb5" etc. */
+struct gss_api_mech *gss_mech_get_by_name(const char *);
+
+/* Similar, but get by pseudoflavor. */
+struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
+
+/* Just increments the mechanism's reference count and returns its input: */
+struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
+
+/* For every succesful gss_mech_get or gss_mech_get_by_* call there must be a
+ * corresponding call to gss_mech_put. */
+void gss_mech_put(struct gss_api_mech *);
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_GSS_API_H */
+
diff --git a/include/linux/sunrpc/gss_asn1.h b/include/linux/sunrpc/gss_asn1.h
new file mode 100644
index 0000000..3ccecd0
--- /dev/null
+++ b/include/linux/sunrpc/gss_asn1.h
@@ -0,0 +1,81 @@
+/*
+ *  linux/include/linux/sunrpc/gss_asn1.h
+ *
+ *  minimal asn1 for generic encoding/decoding of gss tokens
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
+ *  lib/gssapi/krb5/gssapiP_krb5.h, and others
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+
+#include <linux/sunrpc/gss_api.h>
+
+#define SIZEOF_INT 4
+
+/* from gssapi_err_generic.h */
+#define G_BAD_SERVICE_NAME                       (-2045022976L)
+#define G_BAD_STRING_UID                         (-2045022975L)
+#define G_NOUSER                                 (-2045022974L)
+#define G_VALIDATE_FAILED                        (-2045022973L)
+#define G_BUFFER_ALLOC                           (-2045022972L)
+#define G_BAD_MSG_CTX                            (-2045022971L)
+#define G_WRONG_SIZE                             (-2045022970L)
+#define G_BAD_USAGE                              (-2045022969L)
+#define G_UNKNOWN_QOP                            (-2045022968L)
+#define G_NO_HOSTNAME                            (-2045022967L)
+#define G_BAD_HOSTNAME                           (-2045022966L)
+#define G_WRONG_MECH                             (-2045022965L)
+#define G_BAD_TOK_HEADER                         (-2045022964L)
+#define G_BAD_DIRECTION                          (-2045022963L)
+#define G_TOK_TRUNC                              (-2045022962L)
+#define G_REFLECT                                (-2045022961L)
+#define G_WRONG_TOKID                            (-2045022960L)
+
+#define g_OID_equal(o1,o2) \
+   (((o1)->len == (o2)->len) && \
+    (memcmp((o1)->data,(o2)->data,(int) (o1)->len) == 0))
+
+u32 g_verify_token_header(
+     struct xdr_netobj *mech,
+     int *body_size,
+     unsigned char **buf_in,
+     int toksize);
+
+int g_token_size(
+     struct xdr_netobj *mech,
+     unsigned int body_size);
+
+void g_make_token_header(
+     struct xdr_netobj *mech,
+     int body_size,
+     unsigned char **buf);
diff --git a/include/linux/sunrpc/gss_err.h b/include/linux/sunrpc/gss_err.h
new file mode 100644
index 0000000..92608a2
--- /dev/null
+++ b/include/linux/sunrpc/gss_err.h
@@ -0,0 +1,177 @@
+/*
+ *  linux/include/sunrpc/gss_err.h
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 include/gssapi/gssapi.h
+ *
+ *  Copyright (c) 2002 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LINUX_SUNRPC_GSS_ERR_H
+#define _LINUX_SUNRPC_GSS_ERR_H
+
+#ifdef __KERNEL__
+
+typedef unsigned int OM_uint32;
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define	GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+
+/*
+ * Define the default Quality of Protection for per-message services.  Note
+ * that an implementation that offers multiple levels of QOP may either reserve
+ * a value (for example zero, as assumed here) to mean "default protection", or
+ * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
+ * QOP value.  However a value of 0 should always be interpreted by a GSSAPI
+ * implementation as a request for the default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
+
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
+
+/*
+ * The macros that test status codes for error conditions.  Note that the
+ * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
+ * evaluates its argument only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+  ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+  ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+  ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+  ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+	  (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+                             (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+                             (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+                             (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL \
+     (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED \
+     (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED \
+     (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT \
+     (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN \
+     (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+/* XXXX these are not part of the GSSAPI C bindings!  (but should be) */
+
+#define GSS_CALLING_ERROR_FIELD(x) \
+   (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
+#define GSS_ROUTINE_ERROR_FIELD(x) \
+   (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
+#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
+   (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
+
+/* XXXX This is a necessary evil until the spec is fixed */
+#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_SUNRPC_GSS_ERR_H */
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
new file mode 100644
index 0000000..ffe31d2
--- /dev/null
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -0,0 +1,148 @@
+/*
+ *  linux/include/linux/sunrpc/gss_krb5_types.h
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
+ *  lib/gssapi/krb5/gssapiP_krb5.h, and others
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ *  Bruce Fields   <bfields@umich.edu>
+ */
+
+/*
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_err.h>
+#include <linux/sunrpc/gss_asn1.h>
+
+struct krb5_ctx {
+	int			initiate; /* 1 = initiating, 0 = accepting */
+	int			seed_init;
+	unsigned char		seed[16];
+	int			signalg;
+	int			sealalg;
+	struct crypto_tfm	*enc;
+	struct crypto_tfm	*seq;
+	s32			endtime;
+	u32			seq_send;
+	struct xdr_netobj	mech_used;
+};
+
+#define KG_TOK_MIC_MSG    0x0101
+#define KG_TOK_WRAP_MSG   0x0201
+
+enum sgn_alg {
+	SGN_ALG_DES_MAC_MD5 = 0x0000,
+	SGN_ALG_MD2_5 = 0x0001,
+	SGN_ALG_DES_MAC = 0x0002,
+	SGN_ALG_3 = 0x0003,		/* not published */
+	SGN_ALG_HMAC_MD5 = 0x0011,	/* microsoft w2k; no support */
+	SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
+};
+enum seal_alg {
+	SEAL_ALG_NONE = 0xffff,
+	SEAL_ALG_DES = 0x0000,
+	SEAL_ALG_1 = 0x0001,		/* not published */
+	SEAL_ALG_MICROSOFT_RC4 = 0x0010,/* microsoft w2k; no support */
+	SEAL_ALG_DES3KD = 0x0002
+};
+
+#define KRB5_CKSUM_LENGTH 8
+
+#define CKSUMTYPE_CRC32			0x0001
+#define CKSUMTYPE_RSA_MD4		0x0002
+#define CKSUMTYPE_RSA_MD4_DES		0x0003
+#define CKSUMTYPE_DESCBC		0x0004
+#define CKSUMTYPE_RSA_MD5		0x0007
+#define CKSUMTYPE_RSA_MD5_DES		0x0008
+#define CKSUMTYPE_NIST_SHA		0x0009
+#define CKSUMTYPE_HMAC_SHA1_DES3	0x000c
+
+/* from gssapi_err_krb5.h */
+#define KG_CCACHE_NOMATCH                        (39756032L)
+#define KG_KEYTAB_NOMATCH                        (39756033L)
+#define KG_TGT_MISSING                           (39756034L)
+#define KG_NO_SUBKEY                             (39756035L)
+#define KG_CONTEXT_ESTABLISHED                   (39756036L)
+#define KG_BAD_SIGN_TYPE                         (39756037L)
+#define KG_BAD_LENGTH                            (39756038L)
+#define KG_CTX_INCOMPLETE                        (39756039L)
+#define KG_CONTEXT                               (39756040L)
+#define KG_CRED                                  (39756041L)
+#define KG_ENC_DESC                              (39756042L)
+#define KG_BAD_SEQ                               (39756043L)
+#define KG_EMPTY_CCACHE                          (39756044L)
+#define KG_NO_CTYPES                             (39756045L)
+
+/* per Kerberos v5 protocol spec crypto types from the wire. 
+ * these get mapped to linux kernel crypto routines.  
+ */
+#define ENCTYPE_NULL            0x0000
+#define ENCTYPE_DES_CBC_CRC     0x0001	/* DES cbc mode with CRC-32 */
+#define ENCTYPE_DES_CBC_MD4     0x0002	/* DES cbc mode with RSA-MD4 */
+#define ENCTYPE_DES_CBC_MD5     0x0003	/* DES cbc mode with RSA-MD5 */
+#define ENCTYPE_DES_CBC_RAW     0x0004	/* DES cbc mode raw */
+/* XXX deprecated? */
+#define ENCTYPE_DES3_CBC_SHA    0x0005	/* DES-3 cbc mode with NIST-SHA */
+#define ENCTYPE_DES3_CBC_RAW    0x0006	/* DES-3 cbc mode raw */
+#define ENCTYPE_DES_HMAC_SHA1   0x0008
+#define ENCTYPE_DES3_CBC_SHA1   0x0010
+#define ENCTYPE_UNKNOWN         0x01ff
+
+s32
+make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
+		   struct xdr_netobj *cksum);
+
+u32
+krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
+	struct xdr_buf *input_message_buffer,
+	struct xdr_netobj *output_message_buffer, int toktype);
+
+u32
+krb5_read_token(struct krb5_ctx *context_handle,
+	  struct xdr_netobj *input_token_buffer,
+	  struct xdr_buf *message_buffer,
+	  int *qop_state, int toktype);
+
+u32
+krb5_encrypt(struct crypto_tfm * key,
+	     void *iv, void *in, void *out, int length);
+
+u32
+krb5_decrypt(struct crypto_tfm * key,
+	     void *iv, void *in, void *out, int length); 
+
+s32
+krb5_make_seq_num(struct crypto_tfm * key,
+		int direction,
+		s32 seqnum, unsigned char *cksum, unsigned char *buf);
+
+s32
+krb5_get_seq_num(struct crypto_tfm * key,
+	       unsigned char *cksum,
+	       unsigned char *buf, int *direction, s32 * seqnum);
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
new file mode 100644
index 0000000..b5c9968
--- /dev/null
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -0,0 +1,61 @@
+/*
+ *  linux/include/linux/sunrpc/gss_spkm3.h
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_err.h>
+#include <linux/sunrpc/gss_asn1.h>
+
+struct spkm3_ctx {
+	struct xdr_netobj	ctx_id; /* per message context id */
+	int			qop;         /* negotiated qop */
+	struct xdr_netobj	mech_used;
+	unsigned int		ret_flags ;
+	unsigned int		req_flags ;
+	struct xdr_netobj	share_key;
+	int			conf_alg;
+	struct crypto_tfm*	derived_conf_key;
+	int			intg_alg;
+	struct crypto_tfm*	derived_integ_key;
+	int			keyestb_alg;   /* alg used to get share_key */
+	int			owf_alg;   /* one way function */
+};
+
+/* from openssl/objects.h */
+/* XXX need SEAL_ALG_NONE */
+#define NID_md5		4
+#define NID_dhKeyAgreement	28 
+#define NID_des_cbc		31 
+#define NID_sha1		64
+#define NID_cast5_cbc		108
+
+/* SPKM InnerContext Token types */
+
+#define SPKM_ERROR_TOK	3
+#define SPKM_MIC_TOK	4
+#define SPKM_WRAP_TOK	5
+#define SPKM_DEL_TOK	6
+
+u32 spkm3_make_token(struct spkm3_ctx *ctx, int qop_req, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
+
+u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int *qop_state, int toktype);
+
+#define CKSUMTYPE_RSA_MD5            0x0007
+
+s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
+                   struct xdr_netobj *cksum);
+void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits);
+int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, 
+                   int explen);
+void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, 
+                   unsigned char *ctxhdr, int elen, int zbit);
+void spkm3_make_mic_token(unsigned  char **tokp, int toklen, 
+                   struct xdr_netobj *mic_hdr,
+                   struct xdr_netobj *md5cksum, int md5elen, int md5zbit);
+u32 spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, 
+                   unsigned char **cksum);
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
new file mode 100644
index 0000000..15f1153
--- /dev/null
+++ b/include/linux/sunrpc/msg_prot.h
@@ -0,0 +1,80 @@
+/*
+ * linux/include/net/sunrpc/msg_prot.h
+ *
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_MSGPROT_H_
+#define _LINUX_SUNRPC_MSGPROT_H_
+
+#ifdef __KERNEL__ /* user programs should get these from the rpc header files */
+
+#define RPC_VERSION 2
+
+/* spec defines authentication flavor as an unsigned 32 bit integer */
+typedef u32	rpc_authflavor_t;
+
+enum rpc_auth_flavors {
+	RPC_AUTH_NULL  = 0,
+	RPC_AUTH_UNIX  = 1,
+	RPC_AUTH_SHORT = 2,
+	RPC_AUTH_DES   = 3,
+	RPC_AUTH_KRB   = 4,
+	RPC_AUTH_GSS   = 6,
+	RPC_AUTH_MAXFLAVOR = 8,
+	/* pseudoflavors: */
+	RPC_AUTH_GSS_KRB5  = 390003,
+	RPC_AUTH_GSS_KRB5I = 390004,
+	RPC_AUTH_GSS_KRB5P = 390005,
+	RPC_AUTH_GSS_LKEY  = 390006,
+	RPC_AUTH_GSS_LKEYI = 390007,
+	RPC_AUTH_GSS_LKEYP = 390008,
+	RPC_AUTH_GSS_SPKM  = 390009,
+	RPC_AUTH_GSS_SPKMI = 390010,
+	RPC_AUTH_GSS_SPKMP = 390011,
+};
+
+enum rpc_msg_type {
+	RPC_CALL = 0,
+	RPC_REPLY = 1
+};
+
+enum rpc_reply_stat {
+	RPC_MSG_ACCEPTED = 0,
+	RPC_MSG_DENIED = 1
+};
+
+enum rpc_accept_stat {
+	RPC_SUCCESS = 0,
+	RPC_PROG_UNAVAIL = 1,
+	RPC_PROG_MISMATCH = 2,
+	RPC_PROC_UNAVAIL = 3,
+	RPC_GARBAGE_ARGS = 4,
+	RPC_SYSTEM_ERR = 5
+};
+
+enum rpc_reject_stat {
+	RPC_MISMATCH = 0,
+	RPC_AUTH_ERROR = 1
+};
+
+enum rpc_auth_stat {
+	RPC_AUTH_OK = 0,
+	RPC_AUTH_BADCRED = 1,
+	RPC_AUTH_REJECTEDCRED = 2,
+	RPC_AUTH_BADVERF = 3,
+	RPC_AUTH_REJECTEDVERF = 4,
+	RPC_AUTH_TOOWEAK = 5,
+	/* RPCSEC_GSS errors */
+	RPCSEC_GSS_CREDPROBLEM = 13,
+	RPCSEC_GSS_CTXPROBLEM = 14
+};
+
+#define RPC_PMAP_PROGRAM	100000
+#define RPC_PMAP_VERSION	2
+#define RPC_PMAP_PORT		111
+
+#define RPC_MAXNETNAMELEN	256
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
new file mode 100644
index 0000000..6392934
--- /dev/null
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -0,0 +1,50 @@
+#ifndef _LINUX_SUNRPC_RPC_PIPE_FS_H
+#define _LINUX_SUNRPC_RPC_PIPE_FS_H
+
+#ifdef __KERNEL__
+
+struct rpc_pipe_msg {
+	struct list_head list;
+	void *data;
+	size_t len;
+	size_t copied;
+	int errno;
+};
+
+struct rpc_pipe_ops {
+	ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char __user *, size_t);
+	ssize_t (*downcall)(struct file *, const char __user *, size_t);
+	void (*release_pipe)(struct inode *);
+	void (*destroy_msg)(struct rpc_pipe_msg *);
+};
+
+struct rpc_inode {
+	struct inode vfs_inode;
+	void *private;
+	struct list_head pipe;
+	struct list_head in_upcall;
+	int pipelen;
+	int nreaders;
+	int nwriters;
+	wait_queue_head_t waitq;
+#define RPC_PIPE_WAIT_FOR_OPEN	1
+	int flags;
+	struct rpc_pipe_ops *ops;
+	struct work_struct queue_timeout;
+};
+
+static inline struct rpc_inode *
+RPC_I(struct inode *inode)
+{
+	return container_of(inode, struct rpc_inode, vfs_inode);
+}
+
+extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
+
+extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *);
+extern int rpc_rmdir(char *);
+extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags);
+extern int rpc_unlink(char *);
+
+#endif
+#endif
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
new file mode 100644
index 0000000..99d17ed
--- /dev/null
+++ b/include/linux/sunrpc/sched.h
@@ -0,0 +1,273 @@
+/*
+ * linux/include/linux/sunrpc/sched.h
+ *
+ * Scheduling primitives for kernel Sun RPC.
+ *
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_SCHED_H_
+#define _LINUX_SUNRPC_SCHED_H_
+
+#include <linux/timer.h>
+#include <linux/sunrpc/types.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/sunrpc/xdr.h>
+
+/*
+ * This is the actual RPC procedure call info.
+ */
+struct rpc_procinfo;
+struct rpc_message {
+	struct rpc_procinfo *	rpc_proc;	/* Procedure information */
+	void *			rpc_argp;	/* Arguments */
+	void *			rpc_resp;	/* Result */
+	struct rpc_cred *	rpc_cred;	/* Credentials */
+};
+
+struct rpc_wait_queue;
+struct rpc_wait {
+	struct list_head	list;		/* wait queue links */
+	struct list_head	links;		/* Links to related tasks */
+	wait_queue_head_t	waitq;		/* sync: sleep on this q */
+	struct rpc_wait_queue *	rpc_waitq;	/* RPC wait queue we're on */
+};
+
+/*
+ * This is the RPC task struct
+ */
+struct rpc_task {
+#ifdef RPC_DEBUG
+	unsigned long		tk_magic;	/* 0xf00baa */
+#endif
+	struct list_head	tk_task;	/* global list of tasks */
+	struct rpc_clnt *	tk_client;	/* RPC client */
+	struct rpc_rqst *	tk_rqstp;	/* RPC request */
+	int			tk_status;	/* result of last operation */
+
+	/*
+	 * RPC call state
+	 */
+	struct rpc_message	tk_msg;		/* RPC call info */
+	__u32 *			tk_buffer;	/* XDR buffer */
+	size_t			tk_bufsize;
+	__u8			tk_garb_retry;
+	__u8			tk_cred_retry;
+
+	unsigned long		tk_cookie;	/* Cookie for batching tasks */
+
+	/*
+	 * timeout_fn   to be executed by timer bottom half
+	 * callback	to be executed after waking up
+	 * action	next procedure for async tasks
+	 * exit		exit async task and report to caller
+	 */
+	void			(*tk_timeout_fn)(struct rpc_task *);
+	void			(*tk_callback)(struct rpc_task *);
+	void			(*tk_action)(struct rpc_task *);
+	void			(*tk_exit)(struct rpc_task *);
+	void			(*tk_release)(struct rpc_task *);
+	void *			tk_calldata;
+
+	/*
+	 * tk_timer is used for async processing by the RPC scheduling
+	 * primitives. You should not access this directly unless
+	 * you have a pathological interest in kernel oopses.
+	 */
+	struct timer_list	tk_timer;	/* kernel timer */
+	unsigned long		tk_timeout;	/* timeout for rpc_sleep() */
+	unsigned short		tk_flags;	/* misc flags */
+	unsigned char		tk_active   : 1;/* Task has been activated */
+	unsigned char		tk_priority : 2;/* Task priority */
+	unsigned long		tk_runstate;	/* Task run status */
+	struct workqueue_struct	*tk_workqueue;	/* Normally rpciod, but could
+						 * be any workqueue
+						 */
+	union {
+		struct work_struct	tk_work;	/* Async task work queue */
+		struct rpc_wait		tk_wait;	/* RPC wait */
+	} u;
+#ifdef RPC_DEBUG
+	unsigned short		tk_pid;		/* debugging aid */
+#endif
+};
+#define tk_auth			tk_client->cl_auth
+#define tk_xprt			tk_client->cl_xprt
+
+/* support walking a list of tasks on a wait queue */
+#define	task_for_each(task, pos, head) \
+	list_for_each(pos, head) \
+		if ((task=list_entry(pos, struct rpc_task, u.tk_wait.list)),1)
+
+#define	task_for_first(task, head) \
+	if (!list_empty(head) &&  \
+	    ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
+
+/* .. and walking list of all tasks */
+#define	alltask_for_each(task, pos, head) \
+	list_for_each(pos, head) \
+		if ((task=list_entry(pos, struct rpc_task, tk_task)),1)
+
+typedef void			(*rpc_action)(struct rpc_task *);
+
+/*
+ * RPC task flags
+ */
+#define RPC_TASK_ASYNC		0x0001		/* is an async task */
+#define RPC_TASK_SWAPPER	0x0002		/* is swapping in/out */
+#define RPC_TASK_CHILD		0x0008		/* is child of other task */
+#define RPC_CALL_MAJORSEEN	0x0020		/* major timeout seen */
+#define RPC_TASK_ROOTCREDS	0x0040		/* force root creds */
+#define RPC_TASK_DYNAMIC	0x0080		/* task was kmalloc'ed */
+#define RPC_TASK_KILLED		0x0100		/* task was killed */
+#define RPC_TASK_SOFT		0x0200		/* Use soft timeouts */
+#define RPC_TASK_NOINTR		0x0400		/* uninterruptible task */
+
+#define RPC_IS_ASYNC(t)		((t)->tk_flags & RPC_TASK_ASYNC)
+#define RPC_IS_CHILD(t)		((t)->tk_flags & RPC_TASK_CHILD)
+#define RPC_IS_SWAPPER(t)	((t)->tk_flags & RPC_TASK_SWAPPER)
+#define RPC_DO_ROOTOVERRIDE(t)	((t)->tk_flags & RPC_TASK_ROOTCREDS)
+#define RPC_ASSASSINATED(t)	((t)->tk_flags & RPC_TASK_KILLED)
+#define RPC_IS_ACTIVATED(t)	((t)->tk_active)
+#define RPC_DO_CALLBACK(t)	((t)->tk_callback != NULL)
+#define RPC_IS_SOFT(t)		((t)->tk_flags & RPC_TASK_SOFT)
+#define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
+
+#define RPC_TASK_RUNNING	0
+#define RPC_TASK_QUEUED		1
+#define RPC_TASK_WAKEUP		2
+#define RPC_TASK_HAS_TIMER	3
+
+#define RPC_IS_RUNNING(t)	(test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_set_running(t)	(set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_test_and_set_running(t) \
+				(test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_clear_running(t)	\
+	do { \
+		smp_mb__before_clear_bit(); \
+		clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate); \
+		smp_mb__after_clear_bit(); \
+	} while (0)
+
+#define RPC_IS_QUEUED(t)	(test_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
+#define rpc_set_queued(t)	(set_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
+#define rpc_clear_queued(t)	\
+	do { \
+		smp_mb__before_clear_bit(); \
+		clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate); \
+		smp_mb__after_clear_bit(); \
+	} while (0)
+
+#define rpc_start_wakeup(t) \
+	(test_and_set_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate) == 0)
+#define rpc_finish_wakeup(t) \
+	do { \
+		smp_mb__before_clear_bit(); \
+		clear_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate); \
+		smp_mb__after_clear_bit(); \
+	} while (0)
+
+/*
+ * Task priorities.
+ * Note: if you change these, you must also change
+ * the task initialization definitions below.
+ */
+#define RPC_PRIORITY_LOW	0
+#define RPC_PRIORITY_NORMAL	1
+#define RPC_PRIORITY_HIGH	2
+#define RPC_NR_PRIORITY		(RPC_PRIORITY_HIGH+1)
+
+/*
+ * RPC synchronization objects
+ */
+struct rpc_wait_queue {
+	spinlock_t		lock;
+	struct list_head	tasks[RPC_NR_PRIORITY];	/* task queue for each priority level */
+	unsigned long		cookie;			/* cookie of last task serviced */
+	unsigned char		maxpriority;		/* maximum priority (0 if queue is not a priority queue) */
+	unsigned char		priority;		/* current priority */
+	unsigned char		count;			/* # task groups remaining serviced so far */
+	unsigned char		nr;			/* # tasks remaining for cookie */
+#ifdef RPC_DEBUG
+	const char *		name;
+#endif
+};
+
+/*
+ * This is the # requests to send consecutively
+ * from a single cookie.  The aim is to improve
+ * performance of NFS operations such as read/write.
+ */
+#define RPC_BATCH_COUNT			16
+
+#ifndef RPC_DEBUG
+# define RPC_WAITQ_INIT(var,qname) { \
+		.lock = SPIN_LOCK_UNLOCKED, \
+		.tasks = { \
+			[0] = LIST_HEAD_INIT(var.tasks[0]), \
+			[1] = LIST_HEAD_INIT(var.tasks[1]), \
+			[2] = LIST_HEAD_INIT(var.tasks[2]), \
+		}, \
+	}
+#else
+# define RPC_WAITQ_INIT(var,qname) { \
+		.lock = SPIN_LOCK_UNLOCKED, \
+		.tasks = { \
+			[0] = LIST_HEAD_INIT(var.tasks[0]), \
+			[1] = LIST_HEAD_INIT(var.tasks[1]), \
+			[2] = LIST_HEAD_INIT(var.tasks[2]), \
+		}, \
+		.name = qname, \
+	}
+#endif
+# define RPC_WAITQ(var,qname)      struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
+
+#define RPC_IS_PRIORITY(q)		((q)->maxpriority > 0)
+
+/*
+ * Function prototypes
+ */
+struct rpc_task *rpc_new_task(struct rpc_clnt *, rpc_action, int flags);
+struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
+void		rpc_init_task(struct rpc_task *, struct rpc_clnt *,
+					rpc_action exitfunc, int flags);
+void		rpc_release_task(struct rpc_task *);
+void		rpc_killall_tasks(struct rpc_clnt *);
+int		rpc_execute(struct rpc_task *);
+void		rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
+					rpc_action action);
+void		rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
+void		rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
+void		rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
+					rpc_action action, rpc_action timer);
+void		rpc_wake_up_task(struct rpc_task *);
+void		rpc_wake_up(struct rpc_wait_queue *);
+struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
+void		rpc_wake_up_status(struct rpc_wait_queue *, int);
+void		rpc_delay(struct rpc_task *, unsigned long);
+void *		rpc_malloc(struct rpc_task *, size_t);
+int		rpciod_up(void);
+void		rpciod_down(void);
+void		rpciod_wake_up(void);
+#ifdef RPC_DEBUG
+void		rpc_show_tasks(void);
+#endif
+int		rpc_init_mempool(void);
+void		rpc_destroy_mempool(void);
+
+static inline void rpc_exit(struct rpc_task *task, int status)
+{
+	task->tk_status = status;
+	task->tk_action = NULL;
+}
+
+#ifdef RPC_DEBUG
+static inline const char * rpc_qname(struct rpc_wait_queue *q)
+{
+	return ((q && q->name) ? q->name : "unknown");
+}
+#endif
+
+#endif /* _LINUX_SUNRPC_SCHED_H_ */
diff --git a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h
new file mode 100644
index 0000000..0d6ed3c
--- /dev/null
+++ b/include/linux/sunrpc/stats.h
@@ -0,0 +1,78 @@
+/*
+ * linux/include/linux/sunrpc/stats.h
+ *
+ * Client statistics collection for SUN RPC
+ *
+ * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_STATS_H
+#define _LINUX_SUNRPC_STATS_H
+
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+
+struct rpc_stat {
+	struct rpc_program *	program;
+
+	unsigned int		netcnt,
+				netudpcnt,
+				nettcpcnt,
+				nettcpconn,
+				netreconn;
+	unsigned int		rpccnt,
+				rpcretrans,
+				rpcauthrefresh,
+				rpcgarbage;
+};
+
+struct svc_stat {
+	struct svc_program *	program;
+
+	unsigned int		netcnt,
+				netudpcnt,
+				nettcpcnt,
+				nettcpconn;
+	unsigned int		rpccnt,
+				rpcbadfmt,
+				rpcbadauth,
+				rpcbadclnt;
+};
+
+void			rpc_proc_init(void);
+void			rpc_proc_exit(void);
+#ifdef MODULE
+void			rpc_modcount(struct inode *, int);
+#endif
+
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *	rpc_proc_register(struct rpc_stat *);
+void			rpc_proc_unregister(const char *);
+void			rpc_proc_zero(struct rpc_program *);
+struct proc_dir_entry *	svc_proc_register(struct svc_stat *,
+					  struct file_operations *);
+void			svc_proc_unregister(const char *);
+
+void			svc_seq_show(struct seq_file *,
+				     const struct svc_stat *);
+
+extern struct proc_dir_entry	*proc_net_rpc;
+
+#else
+
+static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
+static inline void rpc_proc_unregister(const char *p) {}
+static inline void rpc_proc_zero(struct rpc_program *p) {}
+
+static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s,
+						       struct file_operations *f) { return NULL; }
+static inline void svc_proc_unregister(const char *p) {}
+
+static inline void svc_seq_show(struct seq_file *seq,
+				const struct svc_stat *st) {}
+
+#define proc_net_rpc NULL
+
+#endif
+
+#endif /* _LINUX_SUNRPC_STATS_H */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
new file mode 100644
index 0000000..3700397
--- /dev/null
+++ b/include/linux/sunrpc/svc.h
@@ -0,0 +1,306 @@
+/*
+ * linux/include/linux/sunrpc/svc.h
+ *
+ * RPC server declarations.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+
+#ifndef SUNRPC_SVC_H
+#define SUNRPC_SVC_H
+
+#include <linux/in.h>
+#include <linux/sunrpc/types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/svcauth.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+
+/*
+ * RPC service.
+ *
+ * An RPC service is a ``daemon,'' possibly multithreaded, which
+ * receives and processes incoming RPC messages.
+ * It has one or more transport sockets associated with it, and maintains
+ * a list of idle threads waiting for input.
+ *
+ * We currently do not support more than one RPC program per daemon.
+ */
+struct svc_serv {
+	struct list_head	sv_threads;	/* idle server threads */
+	struct list_head	sv_sockets;	/* pending sockets */
+	struct svc_program *	sv_program;	/* RPC program */
+	struct svc_stat *	sv_stats;	/* RPC statistics */
+	spinlock_t		sv_lock;
+	unsigned int		sv_nrthreads;	/* # of server threads */
+	unsigned int		sv_bufsz;	/* datagram buffer size */
+	unsigned int		sv_xdrsize;	/* XDR buffer size */
+
+	struct list_head	sv_permsocks;	/* all permanent sockets */
+	struct list_head	sv_tempsocks;	/* all temporary sockets */
+	int			sv_tmpcnt;	/* count of temporary sockets */
+
+	char *			sv_name;	/* service name */
+};
+
+/*
+ * Maximum payload size supported by a kernel RPC server.
+ * This is use to determine the max number of pages nfsd is
+ * willing to return in a single READ operation.
+ */
+#define RPCSVC_MAXPAYLOAD	(64*1024u)
+
+/*
+ * RPC Requsts and replies are stored in one or more pages.
+ * We maintain an array of pages for each server thread.
+ * Requests are copied into these pages as they arrive.  Remaining
+ * pages are available to write the reply into.
+ *
+ * Pages are sent using ->sendpage so each server thread needs to
+ * allocate more to replace those used in sending.  To help keep track
+ * of these pages we have a receive list where all pages initialy live,
+ * and a send list where pages are moved to when there are to be part
+ * of a reply.
+ *
+ * We use xdr_buf for holding responses as it fits well with NFS
+ * read responses (that have a header, and some data pages, and possibly
+ * a tail) and means we can share some client side routines.
+ *
+ * The xdr_buf.head kvec always points to the first page in the rq_*pages
+ * list.  The xdr_buf.pages pointer points to the second page on that
+ * list.  xdr_buf.tail points to the end of the first page.
+ * This assumes that the non-page part of an rpc reply will fit
+ * in a page - NFSd ensures this.  lockd also has no trouble.
+ *
+ * Each request/reply pair can have at most one "payload", plus two pages,
+ * one for the request, and one for the reply.
+ */
+#define RPCSVC_MAXPAGES		((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
+
+static inline u32 svc_getu32(struct kvec *iov)
+{
+	u32 val, *vp;
+	vp = iov->iov_base;
+	val = *vp++;
+	iov->iov_base = (void*)vp;
+	iov->iov_len -= sizeof(u32);
+	return val;
+}
+
+static inline void svc_ungetu32(struct kvec *iov)
+{
+	u32 *vp = (u32 *)iov->iov_base;
+	iov->iov_base = (void *)(vp - 1);
+	iov->iov_len += sizeof(*vp);
+}
+
+static inline void svc_putu32(struct kvec *iov, u32 val)
+{
+	u32 *vp = iov->iov_base + iov->iov_len;
+	*vp = val;
+	iov->iov_len += sizeof(u32);
+}
+
+	
+/*
+ * The context of a single thread, including the request currently being
+ * processed.
+ * NOTE: First two items must be prev/next.
+ */
+struct svc_rqst {
+	struct list_head	rq_list;	/* idle list */
+	struct svc_sock *	rq_sock;	/* socket */
+	struct sockaddr_in	rq_addr;	/* peer address */
+	int			rq_addrlen;
+
+	struct svc_serv *	rq_server;	/* RPC service definition */
+	struct svc_procedure *	rq_procinfo;	/* procedure info */
+	struct auth_ops *	rq_authop;	/* authentication flavour */
+	struct svc_cred		rq_cred;	/* auth info */
+	struct sk_buff *	rq_skbuff;	/* fast recv inet buffer */
+	struct svc_deferred_req*rq_deferred;	/* deferred request we are replaying */
+
+	struct xdr_buf		rq_arg;
+	struct xdr_buf		rq_res;
+	struct page *		rq_argpages[RPCSVC_MAXPAGES];
+	struct page *		rq_respages[RPCSVC_MAXPAGES];
+	int			rq_restailpage;
+	short			rq_argused;	/* pages used for argument */
+	short			rq_arghi;	/* pages available in argument page list */
+	short			rq_resused;	/* pages used for result */
+
+	u32			rq_xid;		/* transmission id */
+	u32			rq_prog;	/* program number */
+	u32			rq_vers;	/* program version */
+	u32			rq_proc;	/* procedure number */
+	u32			rq_prot;	/* IP protocol */
+	unsigned short
+				rq_secure  : 1;	/* secure port */
+
+
+	__u32			rq_daddr;	/* dest addr of request - reply from here */
+
+	void *			rq_argp;	/* decoded arguments */
+	void *			rq_resp;	/* xdr'd results */
+	void *			rq_auth_data;	/* flavor-specific data */
+
+	int			rq_reserved;	/* space on socket outq
+						 * reserved for this request
+						 */
+
+	struct cache_req	rq_chandle;	/* handle passed to caches for 
+						 * request delaying 
+						 */
+	/* Catering to nfsd */
+	struct auth_domain *	rq_client;	/* RPC peer info */
+	struct svc_cacherep *	rq_cacherep;	/* cache info */
+	struct knfsd_fh *	rq_reffh;	/* Referrence filehandle, used to
+						 * determine what device number
+						 * to report (real or virtual)
+						 */
+
+	wait_queue_head_t	rq_wait;	/* synchronization */
+};
+
+/*
+ * Check buffer bounds after decoding arguments
+ */
+static inline int
+xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
+{
+	char *cp = (char *)p;
+	struct kvec *vec = &rqstp->rq_arg.head[0];
+	return cp - (char*)vec->iov_base <= vec->iov_len;
+}
+
+static inline int
+xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
+{
+	struct kvec *vec = &rqstp->rq_res.head[0];
+	char *cp = (char*)p;
+
+	vec->iov_len = cp - (char*)vec->iov_base;
+
+	return vec->iov_len <= PAGE_SIZE;
+}
+
+static inline int svc_take_page(struct svc_rqst *rqstp)
+{
+	if (rqstp->rq_arghi <= rqstp->rq_argused)
+		return -ENOMEM;
+	rqstp->rq_arghi--;
+	rqstp->rq_respages[rqstp->rq_resused] =
+		rqstp->rq_argpages[rqstp->rq_arghi];
+	rqstp->rq_resused++;
+	return 0;
+}
+
+static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
+{
+        while (rqstp->rq_resused) {
+		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
+			continue;
+		rqstp->rq_argpages[rqstp->rq_arghi++] =
+			rqstp->rq_respages[rqstp->rq_resused];
+		rqstp->rq_respages[rqstp->rq_resused] = NULL;
+	}
+}
+
+static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
+{
+	while (rqstp->rq_resused &&
+	       rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
+
+		if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
+			rqstp->rq_argpages[rqstp->rq_arghi++] =
+				rqstp->rq_respages[rqstp->rq_resused];
+			rqstp->rq_respages[rqstp->rq_resused] = NULL;
+		}
+	}
+}
+
+static inline void svc_free_allpages(struct svc_rqst *rqstp)
+{
+        while (rqstp->rq_resused) {
+		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
+			continue;
+		put_page(rqstp->rq_respages[rqstp->rq_resused]);
+		rqstp->rq_respages[rqstp->rq_resused] = NULL;
+	}
+}
+
+struct svc_deferred_req {
+	u32			prot;	/* protocol (UDP or TCP) */
+	struct sockaddr_in	addr;
+	struct svc_sock		*svsk;	/* where reply must go */
+	struct cache_deferred_req handle;
+	int			argslen;
+	u32			args[0];
+};
+
+/*
+ * RPC program
+ */
+struct svc_program {
+	u32			pg_prog;	/* program number */
+	unsigned int		pg_lovers;	/* lowest version */
+	unsigned int		pg_hivers;	/* lowest version */
+	unsigned int		pg_nvers;	/* number of versions */
+	struct svc_version **	pg_vers;	/* version array */
+	char *			pg_name;	/* service name */
+	char *			pg_class;	/* class name: services sharing authentication */
+	struct svc_stat *	pg_stats;	/* rpc statistics */
+	int			(*pg_authenticate)(struct svc_rqst *);
+};
+
+/*
+ * RPC program version
+ */
+struct svc_version {
+	u32			vs_vers;	/* version number */
+	u32			vs_nproc;	/* number of procedures */
+	struct svc_procedure *	vs_proc;	/* per-procedure info */
+	u32			vs_xdrsize;	/* xdrsize needed for this version */
+
+	/* Override dispatch function (e.g. when caching replies).
+	 * A return value of 0 means drop the request. 
+	 * vs_dispatch == NULL means use default dispatcher.
+	 */
+	int			(*vs_dispatch)(struct svc_rqst *, u32 *);
+};
+
+/*
+ * RPC procedure info
+ */
+typedef int	(*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
+struct svc_procedure {
+	svc_procfunc		pc_func;	/* process the request */
+	kxdrproc_t		pc_decode;	/* XDR decode args */
+	kxdrproc_t		pc_encode;	/* XDR encode result */
+	kxdrproc_t		pc_release;	/* XDR free result */
+	unsigned int		pc_argsize;	/* argument struct size */
+	unsigned int		pc_ressize;	/* result struct size */
+	unsigned int		pc_count;	/* call count */
+	unsigned int		pc_cachetype;	/* cache info (NFS) */
+	unsigned int		pc_xdrressize;	/* maximum size of XDR reply */
+};
+
+/*
+ * This is the RPC server thread function prototype
+ */
+typedef void		(*svc_thread_fn)(struct svc_rqst *);
+
+/*
+ * Function prototypes.
+ */
+struct svc_serv *  svc_create(struct svc_program *, unsigned int);
+int		   svc_create_thread(svc_thread_fn, struct svc_serv *);
+void		   svc_exit_thread(struct svc_rqst *);
+void		   svc_destroy(struct svc_serv *);
+int		   svc_process(struct svc_serv *, struct svc_rqst *);
+int		   svc_register(struct svc_serv *, int, unsigned short);
+void		   svc_wake_up(struct svc_serv *);
+void		   svc_reserve(struct svc_rqst *rqstp, int space);
+
+#endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
new file mode 100644
index 0000000..c119ce7
--- /dev/null
+++ b/include/linux/sunrpc/svcauth.h
@@ -0,0 +1,167 @@
+/*
+ * linux/include/linux/sunrpc/svcauth.h
+ *
+ * RPC server-side authentication stuff.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_SVCAUTH_H_
+#define _LINUX_SUNRPC_SVCAUTH_H_
+
+#ifdef __KERNEL__
+
+#include <linux/string.h>
+#include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/cache.h>
+#include <linux/hash.h>
+
+#define SVC_CRED_NGROUPS	32
+struct svc_cred {
+	uid_t			cr_uid;
+	gid_t			cr_gid;
+	struct group_info	*cr_group_info;
+};
+
+struct svc_rqst;		/* forward decl */
+
+/* Authentication is done in the context of a domain.
+ *
+ * Currently, the nfs server uses the auth_domain to stand
+ * for the "client" listed in /etc/exports.
+ *
+ * More generally, a domain might represent a group of clients using
+ * a common mechanism for authentication and having a common mapping
+ * between local identity (uid) and network identity.  All clients
+ * in a domain have similar general access rights.  Each domain can
+ * contain multiple principals which will have different specific right
+ * based on normal Discretionary Access Control.
+ *
+ * A domain is created by an authentication flavour module based on name
+ * only.  Userspace then fills in detail on demand.
+ *
+ * In the case of auth_unix and auth_null, the auth_domain is also
+ * associated with entries in another cache representing the mapping
+ * of ip addresses to the given client.
+ */
+struct auth_domain {
+	struct	cache_head	h;
+	char			*name;
+	int			flavour;
+};
+
+/*
+ * Each authentication flavour registers an auth_ops
+ * structure.
+ * name is simply the name.
+ * flavour gives the auth flavour. It determines where the flavour is registered
+ * accept() is given a request and should verify it.
+ *   It should inspect the authenticator and verifier, and possibly the data.
+ *    If there is a problem with the authentication *authp should be set.
+ *    The return value of accept() can indicate:
+ *      OK - authorised. client and credential are set in rqstp.
+ *           reqbuf points to arguments
+ *           resbuf points to good place for results.  verfier
+ *             is (probably) already in place.  Certainly space is
+ *	       reserved for it.
+ *      DROP - simply drop the request. It may have been deferred
+ *      GARBAGE - rpc garbage_args error
+ *      SYSERR - rpc system_err error
+ *      DENIED - authp holds reason for denial.
+ *      COMPLETE - the reply is encoded already and ready to be sent; no
+ *		further processing is necessary.  (This is used for processing
+ *		null procedure calls which are used to set up encryption
+ *		contexts.)
+ *
+ *   accept is passed the proc number so that it can accept NULL rpc requests
+ *   even if it cannot authenticate the client (as is sometimes appropriate).
+ *
+ * release() is given a request after the procedure has been run.
+ *  It should sign/encrypt the results if needed
+ * It should return:
+ *    OK - the resbuf is ready to be sent
+ *    DROP - the reply should be quitely dropped
+ *    DENIED - authp holds a reason for MSG_DENIED
+ *    SYSERR - rpc system_err
+ *
+ * domain_release()
+ *   This call releases a domain.
+ */
+struct auth_ops {
+	char *	name;
+	struct module *owner;
+	int	flavour;
+	int	(*accept)(struct svc_rqst *rq, u32 *authp);
+	int	(*release)(struct svc_rqst *rq);
+	void	(*domain_release)(struct auth_domain *);
+	int	(*set_client)(struct svc_rqst *rq);
+};
+
+#define	SVC_GARBAGE	1
+#define	SVC_SYSERR	2
+#define	SVC_VALID	3
+#define	SVC_NEGATIVE	4
+#define	SVC_OK		5
+#define	SVC_DROP	6
+#define	SVC_DENIED	7
+#define	SVC_PENDING	8
+#define	SVC_COMPLETE	9
+
+
+extern int	svc_authenticate(struct svc_rqst *rqstp, u32 *authp);
+extern int	svc_authorise(struct svc_rqst *rqstp);
+extern int	svc_set_client(struct svc_rqst *rqstp);
+extern int	svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
+extern void	svc_auth_unregister(rpc_authflavor_t flavor);
+
+extern struct auth_domain *unix_domain_find(char *name);
+extern void auth_domain_put(struct auth_domain *item);
+extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
+extern struct auth_domain *auth_domain_lookup(struct auth_domain *item, int set);
+extern struct auth_domain *auth_domain_find(char *name);
+extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
+extern int auth_unix_forget_old(struct auth_domain *dom);
+extern void svcauth_unix_purge(void);
+
+static inline unsigned long hash_str(char *name, int bits)
+{
+	unsigned long hash = 0;
+	unsigned long l = 0;
+	int len = 0;
+	unsigned char c;
+	do {
+		if (unlikely(!(c = *name++))) {
+			c = (char)len; len = -1;
+		}
+		l = (l << 8) | c;
+		len++;
+		if ((len & (BITS_PER_LONG/8-1))==0)
+			hash = hash_long(hash^l, BITS_PER_LONG);
+	} while (len);
+	return hash >> (BITS_PER_LONG - bits);
+}
+
+static inline unsigned long hash_mem(char *buf, int length, int bits)
+{
+	unsigned long hash = 0;
+	unsigned long l = 0;
+	int len = 0;
+	unsigned char c;
+	do {
+		if (len == length) {
+			c = (char)len; len = -1;
+		} else
+			c = *buf++;
+		l = (l << 8) | c;
+		len++;
+		if ((len & (BITS_PER_LONG/8-1))==0)
+			hash = hash_long(hash^l, BITS_PER_LONG);
+	} while (len);
+	return hash >> (BITS_PER_LONG - bits);
+}
+
+extern struct cache_detail auth_domain_cache, ip_map_cache;
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_SUNRPC_SVCAUTH_H_ */
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
new file mode 100644
index 0000000..3a2206f
--- /dev/null
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -0,0 +1,27 @@
+/*
+ * linux/include/linux/svcauth_gss.h
+ *
+ * Bruce Fields <bfields@umich.edu>
+ * Copyright (c) 2002 The Regents of the Unviersity of Michigan
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _LINUX_SUNRPC_SVCAUTH_GSS_H
+#define _LINUX_SUNRPC_SVCAUTH_GSS_H
+
+#ifdef __KERNEL__
+#include <linux/sched.h>
+#include <linux/sunrpc/types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/svcauth.h>
+#include <linux/sunrpc/svcsock.h>
+#include <linux/sunrpc/auth_gss.h>
+
+int gss_svc_init(void);
+void gss_svc_shutdown(void);
+int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
new file mode 100644
index 0000000..d33c6fa
--- /dev/null
+++ b/include/linux/sunrpc/svcsock.h
@@ -0,0 +1,65 @@
+/*
+ * linux/include/linux/sunrpc/svcsock.h
+ *
+ * RPC server socket I/O.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef SUNRPC_SVCSOCK_H
+#define SUNRPC_SVCSOCK_H
+
+#include <linux/sunrpc/svc.h>
+
+/*
+ * RPC server socket.
+ */
+struct svc_sock {
+	struct list_head	sk_ready;	/* list of ready sockets */
+	struct list_head	sk_list;	/* list of all sockets */
+	struct socket *		sk_sock;	/* berkeley socket layer */
+	struct sock *		sk_sk;		/* INET layer */
+
+	struct svc_serv *	sk_server;	/* service for this socket */
+	unsigned int		sk_inuse;	/* use count */
+	unsigned long		sk_flags;
+#define	SK_BUSY		0			/* enqueued/receiving */
+#define	SK_CONN		1			/* conn pending */
+#define	SK_CLOSE	2			/* dead or dying */
+#define	SK_DATA		3			/* data pending */
+#define	SK_TEMP		4			/* temp (TCP) socket */
+#define	SK_DEAD		6			/* socket closed */
+#define	SK_CHNGBUF	7			/* need to change snd/rcv buffer sizes */
+#define	SK_DEFERRED	8			/* request on sk_deferred */
+
+	int			sk_reserved;	/* space on outq that is reserved */
+
+	struct list_head	sk_deferred;	/* deferred requests that need to
+						 * be revisted */
+	struct semaphore        sk_sem;		/* to serialize sending data */
+
+	int			(*sk_recvfrom)(struct svc_rqst *rqstp);
+	int			(*sk_sendto)(struct svc_rqst *rqstp);
+
+	/* We keep the old state_change and data_ready CB's here */
+	void			(*sk_ostate)(struct sock *);
+	void			(*sk_odata)(struct sock *, int bytes);
+	void			(*sk_owspace)(struct sock *);
+
+	/* private TCP part */
+	int			sk_reclen;	/* length of record */
+	int			sk_tcplen;	/* current read length */
+	time_t			sk_lastrecv;	/* time of last received request */
+};
+
+/*
+ * Function prototypes.
+ */
+int		svc_makesock(struct svc_serv *, int, unsigned short);
+void		svc_delete_socket(struct svc_sock *);
+int		svc_recv(struct svc_serv *, struct svc_rqst *, long);
+int		svc_send(struct svc_rqst *);
+void		svc_drop(struct svc_rqst *);
+void		svc_sock_update_bufs(struct svc_serv *serv);
+
+#endif /* SUNRPC_SVCSOCK_H */
diff --git a/include/linux/sunrpc/timer.h b/include/linux/sunrpc/timer.h
new file mode 100644
index 0000000..a67fd73
--- /dev/null
+++ b/include/linux/sunrpc/timer.h
@@ -0,0 +1,49 @@
+/*
+ *  linux/include/linux/sunrpc/timer.h
+ *
+ *  Declarations for the RPC transport timer.
+ *
+ *  Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no>
+ */
+
+#ifndef _LINUX_SUNRPC_TIMER_H
+#define _LINUX_SUNRPC_TIMER_H
+
+#include <asm/atomic.h>
+
+struct rpc_rtt {
+	unsigned long timeo;	/* default timeout value */
+	unsigned long srtt[5];	/* smoothed round trip time << 3 */
+	unsigned long sdrtt[5];	/* smoothed medium deviation of RTT */
+	int ntimeouts[5];	/* Number of timeouts for the last request */
+};
+
+
+extern void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo);
+extern void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m);
+extern unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer);
+
+static inline void rpc_set_timeo(struct rpc_rtt *rt, int timer, int ntimeo)
+{
+	int *t;
+	if (!timer)
+		return;
+	t = &rt->ntimeouts[timer-1];
+	if (ntimeo < *t) {
+		if (*t > 0)
+			(*t)--;
+	} else {
+		if (ntimeo > 8)
+			ntimeo = 8;
+		*t = ntimeo;
+	}
+}
+
+static inline int rpc_ntimeo(struct rpc_rtt *rt, int timer)
+{
+	if (!timer)
+		return 0;
+	return rt->ntimeouts[timer-1];
+}
+
+#endif /* _LINUX_SUNRPC_TIMER_H */
diff --git a/include/linux/sunrpc/types.h b/include/linux/sunrpc/types.h
new file mode 100644
index 0000000..d222f47
--- /dev/null
+++ b/include/linux/sunrpc/types.h
@@ -0,0 +1,22 @@
+/*
+ * linux/include/linux/sunrpc/types.h
+ *
+ * Generic types and misc stuff for RPC.
+ *
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_TYPES_H_
+#define _LINUX_SUNRPC_TYPES_H_
+
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/sunrpc/debug.h>
+#include <linux/list.h>
+
+/*
+ * Shorthands
+ */
+#define signalled()		(signal_pending(current))
+
+#endif /* _LINUX_SUNRPC_TYPES_H_ */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
new file mode 100644
index 0000000..541dcf8
--- /dev/null
+++ b/include/linux/sunrpc/xdr.h
@@ -0,0 +1,192 @@
+/*
+ * include/linux/sunrpc/xdr.h
+ *
+ * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _SUNRPC_XDR_H_
+#define _SUNRPC_XDR_H_
+
+#ifdef __KERNEL__
+
+#include <linux/uio.h>
+#include <asm/byteorder.h>
+
+/*
+ * Buffer adjustment
+ */
+#define XDR_QUADLEN(l)		(((l) + 3) >> 2)
+
+/*
+ * Generic opaque `network object.' At the kernel level, this type
+ * is used only by lockd.
+ */
+#define XDR_MAX_NETOBJ		1024
+struct xdr_netobj {
+	unsigned int		len;
+	u8 *			data;
+};
+
+/*
+ * This is the generic XDR function. rqstp is either a rpc_rqst (client
+ * side) or svc_rqst pointer (server side).
+ * Encode functions always assume there's enough room in the buffer.
+ */
+typedef int	(*kxdrproc_t)(void *rqstp, u32 *data, void *obj);
+
+/*
+ * Basic structure for transmission/reception of a client XDR message.
+ * Features a header (for a linear buffer containing RPC headers
+ * and the data payload for short messages), and then an array of
+ * pages.
+ * The tail iovec allows you to append data after the page array. Its
+ * main interest is for appending padding to the pages in order to
+ * satisfy the int_32-alignment requirements in RFC1832.
+ *
+ * For the future, we might want to string several of these together
+ * in a list if anybody wants to make use of NFSv4 COMPOUND
+ * operations and/or has a need for scatter/gather involving pages.
+ */
+struct xdr_buf {
+	struct kvec	head[1],	/* RPC header + non-page data */
+			tail[1];	/* Appended after page data */
+
+	struct page **	pages;		/* Array of contiguous pages */
+	unsigned int	page_base,	/* Start of page data */
+			page_len;	/* Length of page data */
+
+	unsigned int	buflen,		/* Total length of storage buffer */
+			len;		/* Length of XDR encoded message */
+
+};
+
+/*
+ * pre-xdr'ed macros.
+ */
+
+#define	xdr_zero	__constant_htonl(0)
+#define	xdr_one		__constant_htonl(1)
+#define	xdr_two		__constant_htonl(2)
+
+#define	rpc_success		__constant_htonl(RPC_SUCCESS)
+#define	rpc_prog_unavail	__constant_htonl(RPC_PROG_UNAVAIL)
+#define	rpc_prog_mismatch	__constant_htonl(RPC_PROG_MISMATCH)
+#define	rpc_proc_unavail	__constant_htonl(RPC_PROC_UNAVAIL)
+#define	rpc_garbage_args	__constant_htonl(RPC_GARBAGE_ARGS)
+#define	rpc_system_err		__constant_htonl(RPC_SYSTEM_ERR)
+
+#define	rpc_auth_ok		__constant_htonl(RPC_AUTH_OK)
+#define	rpc_autherr_badcred	__constant_htonl(RPC_AUTH_BADCRED)
+#define	rpc_autherr_rejectedcred __constant_htonl(RPC_AUTH_REJECTEDCRED)
+#define	rpc_autherr_badverf	__constant_htonl(RPC_AUTH_BADVERF)
+#define	rpc_autherr_rejectedverf __constant_htonl(RPC_AUTH_REJECTEDVERF)
+#define	rpc_autherr_tooweak	__constant_htonl(RPC_AUTH_TOOWEAK)
+#define	rpcsec_gsserr_credproblem	__constant_htonl(RPCSEC_GSS_CREDPROBLEM)
+#define	rpcsec_gsserr_ctxproblem	__constant_htonl(RPCSEC_GSS_CTXPROBLEM)
+#define	rpc_autherr_oldseqnum	__constant_htonl(101)
+
+/*
+ * Miscellaneous XDR helper functions
+ */
+u32 *	xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
+u32 *	xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
+u32 *	xdr_encode_string(u32 *p, const char *s);
+u32 *	xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen);
+u32 *	xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
+u32 *	xdr_encode_netobj(u32 *p, const struct xdr_netobj *);
+u32 *	xdr_decode_netobj(u32 *p, struct xdr_netobj *);
+
+void	xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
+			 unsigned int);
+void	xdr_inline_pages(struct xdr_buf *, unsigned int,
+			 struct page **, unsigned int, unsigned int);
+
+static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
+{
+	return xdr_encode_opaque(p, s, len);
+}
+
+/*
+ * Decode 64bit quantities (NFSv3 support)
+ */
+static inline u32 *
+xdr_encode_hyper(u32 *p, __u64 val)
+{
+	*p++ = htonl(val >> 32);
+	*p++ = htonl(val & 0xFFFFFFFF);
+	return p;
+}
+
+static inline u32 *
+xdr_decode_hyper(u32 *p, __u64 *valp)
+{
+	*valp  = ((__u64) ntohl(*p++)) << 32;
+	*valp |= ntohl(*p++);
+	return p;
+}
+
+/*
+ * Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
+ */
+static inline int
+xdr_adjust_iovec(struct kvec *iov, u32 *p)
+{
+	return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
+}
+
+/*
+ * Maximum number of iov's we use.
+ */
+#define MAX_IOVEC	(12)
+
+/*
+ * XDR buffer helper functions
+ */
+extern void xdr_shift_buf(struct xdr_buf *, size_t);
+extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
+extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int);
+extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int);
+extern int read_bytes_from_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len);
+
+/*
+ * Helper structure for copying from an sk_buff.
+ */
+typedef struct {
+	struct sk_buff	*skb;
+	unsigned int	offset;
+	size_t		count;
+	unsigned int	csum;
+} skb_reader_t;
+
+typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
+
+extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
+		skb_reader_t *, skb_read_actor_t);
+
+struct socket;
+struct sockaddr;
+extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
+		struct xdr_buf *, unsigned int, int);
+
+/*
+ * Provide some simple tools for XDR buffer overflow-checking etc.
+ */
+struct xdr_stream {
+	uint32_t *p;		/* start of available buffer */
+	struct xdr_buf *buf;	/* XDR buffer to read/write */
+
+	uint32_t *end;		/* end of available buffer space */
+	struct kvec *iov;	/* pointer to the current kvec */
+};
+
+extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
+extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
+extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
+		unsigned int base, unsigned int len);
+extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
+extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
+extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
+
+#endif /* __KERNEL__ */
+
+#endif /* _SUNRPC_XDR_H_ */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
new file mode 100644
index 0000000..e618c16
--- /dev/null
+++ b/include/linux/sunrpc/xprt.h
@@ -0,0 +1,232 @@
+/*
+ *  linux/include/linux/sunrpc/clnt_xprt.h
+ *
+ *  Declarations for the RPC transport interface.
+ *
+ *  Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_SUNRPC_XPRT_H
+#define _LINUX_SUNRPC_XPRT_H
+
+#include <linux/uio.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/xdr.h>
+
+/*
+ * The transport code maintains an estimate on the maximum number of out-
+ * standing RPC requests, using a smoothed version of the congestion
+ * avoidance implemented in 44BSD. This is basically the Van Jacobson
+ * congestion algorithm: If a retransmit occurs, the congestion window is
+ * halved; otherwise, it is incremented by 1/cwnd when
+ *
+ *	-	a reply is received and
+ *	-	a full number of requests are outstanding and
+ *	-	the congestion window hasn't been updated recently.
+ *
+ * Upper procedures may check whether a request would block waiting for
+ * a free RPC slot by using the RPC_CONGESTED() macro.
+ */
+extern unsigned int xprt_udp_slot_table_entries;
+extern unsigned int xprt_tcp_slot_table_entries;
+
+#define RPC_MIN_SLOT_TABLE	(2U)
+#define RPC_DEF_SLOT_TABLE	(16U)
+#define RPC_MAX_SLOT_TABLE	(128U)
+
+#define RPC_CWNDSHIFT		(8U)
+#define RPC_CWNDSCALE		(1U << RPC_CWNDSHIFT)
+#define RPC_INITCWND		RPC_CWNDSCALE
+#define RPC_MAXCWND(xprt)	((xprt)->max_reqs << RPC_CWNDSHIFT)
+#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
+
+/* Default timeout values */
+#define RPC_MAX_UDP_TIMEOUT	(60*HZ)
+#define RPC_MAX_TCP_TIMEOUT	(600*HZ)
+
+/*
+ * Wait duration for an RPC TCP connection to be established.  Solaris
+ * NFS over TCP uses 60 seconds, for example, which is in line with how
+ * long a server takes to reboot.
+ */
+#define RPC_CONNECT_TIMEOUT	(60*HZ)
+
+/*
+ * Delay an arbitrary number of seconds before attempting to reconnect
+ * after an error.
+ */
+#define RPC_REESTABLISH_TIMEOUT	(15*HZ)
+
+/* RPC call and reply header size as number of 32bit words (verifier
+ * size computed separately)
+ */
+#define RPC_CALLHDRSIZE		6
+#define RPC_REPHDRSIZE		4
+
+/*
+ * This describes a timeout strategy
+ */
+struct rpc_timeout {
+	unsigned long		to_initval,		/* initial timeout */
+				to_maxval,		/* max timeout */
+				to_increment;		/* if !exponential */
+	unsigned int		to_retries;		/* max # of retries */
+	unsigned char		to_exponential;
+};
+
+/*
+ * This describes a complete RPC request
+ */
+struct rpc_rqst {
+	/*
+	 * This is the user-visible part
+	 */
+	struct rpc_xprt *	rq_xprt;		/* RPC client */
+	struct xdr_buf		rq_snd_buf;		/* send buffer */
+	struct xdr_buf		rq_rcv_buf;		/* recv buffer */
+
+	/*
+	 * This is the private part
+	 */
+	struct rpc_task *	rq_task;	/* RPC task data */
+	__u32			rq_xid;		/* request XID */
+	int			rq_cong;	/* has incremented xprt->cong */
+	int			rq_received;	/* receive completed */
+	u32			rq_seqno;	/* gss seq no. used on req. */
+
+	struct list_head	rq_list;
+
+	struct xdr_buf		rq_private_buf;		/* The receive buffer
+							 * used in the softirq.
+							 */
+	unsigned long		rq_majortimeo;	/* major timeout alarm */
+	unsigned long		rq_timeout;	/* Current timeout value */
+	unsigned int		rq_retries;	/* # of retries */
+	/*
+	 * For authentication (e.g. auth_des)
+	 */
+	u32			rq_creddata[2];
+	
+	/*
+	 * Partial send handling
+	 */
+	
+	u32			rq_bytes_sent;	/* Bytes we have sent */
+
+	unsigned long		rq_xtime;	/* when transmitted */
+	int			rq_ntrans;
+};
+#define rq_svec			rq_snd_buf.head
+#define rq_slen			rq_snd_buf.len
+
+#define XPRT_LAST_FRAG		(1 << 0)
+#define XPRT_COPY_RECM		(1 << 1)
+#define XPRT_COPY_XID		(1 << 2)
+#define XPRT_COPY_DATA		(1 << 3)
+
+struct rpc_xprt {
+	struct socket *		sock;		/* BSD socket layer */
+	struct sock *		inet;		/* INET layer */
+
+	struct rpc_timeout	timeout;	/* timeout parms */
+	struct sockaddr_in	addr;		/* server address */
+	int			prot;		/* IP protocol */
+
+	unsigned long		cong;		/* current congestion */
+	unsigned long		cwnd;		/* congestion window */
+
+	unsigned int		rcvsize,	/* socket receive buffer size */
+				sndsize;	/* socket send buffer size */
+
+	size_t			max_payload;	/* largest RPC payload size,
+						   in bytes */
+
+	struct rpc_wait_queue	sending;	/* requests waiting to send */
+	struct rpc_wait_queue	resend;		/* requests waiting to resend */
+	struct rpc_wait_queue	pending;	/* requests in flight */
+	struct rpc_wait_queue	backlog;	/* waiting for slot */
+	struct list_head	free;		/* free slots */
+	struct rpc_rqst *	slot;		/* slot table storage */
+	unsigned int		max_reqs;	/* total slots */
+	unsigned long		sockstate;	/* Socket state */
+	unsigned char		shutdown   : 1,	/* being shut down */
+				nocong	   : 1,	/* no congestion control */
+				resvport   : 1, /* use a reserved port */
+				stream     : 1;	/* TCP */
+
+	/*
+	 * XID
+	 */
+	__u32			xid;		/* Next XID value to use */
+
+	/*
+	 * State of TCP reply receive stuff
+	 */
+	u32			tcp_recm,	/* Fragment header */
+				tcp_xid,	/* Current XID */
+				tcp_reclen,	/* fragment length */
+				tcp_offset;	/* fragment offset */
+	unsigned long		tcp_copied,	/* copied to request */
+				tcp_flags;
+	/*
+	 * Connection of sockets
+	 */
+	struct work_struct	sock_connect;
+	unsigned short		port;
+	/*
+	 * Disconnection of idle sockets
+	 */
+	struct work_struct	task_cleanup;
+	struct timer_list	timer;
+	unsigned long		last_used;
+
+	/*
+	 * Send stuff
+	 */
+	spinlock_t		sock_lock;	/* lock socket info */
+	spinlock_t		xprt_lock;	/* lock xprt info */
+	struct rpc_task *	snd_task;	/* Task blocked in send */
+
+	struct list_head	recv;
+
+
+	void			(*old_data_ready)(struct sock *, int);
+	void			(*old_state_change)(struct sock *);
+	void			(*old_write_space)(struct sock *);
+
+	wait_queue_head_t	cong_wait;
+};
+
+#ifdef __KERNEL__
+
+struct rpc_xprt *	xprt_create_proto(int proto, struct sockaddr_in *addr,
+					struct rpc_timeout *toparms);
+int			xprt_destroy(struct rpc_xprt *);
+void			xprt_set_timeout(struct rpc_timeout *, unsigned int,
+					unsigned long);
+
+void			xprt_reserve(struct rpc_task *);
+int			xprt_prepare_transmit(struct rpc_task *);
+void			xprt_transmit(struct rpc_task *);
+void			xprt_receive(struct rpc_task *);
+int			xprt_adjust_timeout(struct rpc_rqst *req);
+void			xprt_release(struct rpc_task *);
+void			xprt_connect(struct rpc_task *);
+void			xprt_sock_setbufsize(struct rpc_xprt *);
+
+#define XPRT_LOCKED	0
+#define XPRT_CONNECT	1
+#define XPRT_CONNECTING	2
+
+#define xprt_connected(xp)		(test_bit(XPRT_CONNECT, &(xp)->sockstate))
+#define xprt_set_connected(xp)		(set_bit(XPRT_CONNECT, &(xp)->sockstate))
+#define xprt_test_and_set_connected(xp)	(test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
+#define xprt_test_and_clear_connected(xp) \
+					(test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
+#define xprt_clear_connected(xp)	(clear_bit(XPRT_CONNECT, &(xp)->sockstate))
+
+#endif /* __KERNEL__*/
+
+#endif /* _LINUX_SUNRPC_XPRT_H */