lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20071012160701.15119.64841.stgit@warthog.procyon.org.uk>
Date:	Fri, 12 Oct 2007 17:07:01 +0100
From:	David Howells <dhowells@...hat.com>
To:	viro@....linux.org.uk
Cc:	kwc@...i.umich.edu, Trond.Myklebust@...app.com,
	linux-kernel@...r.kernel.org, dhowells@...hat.com
Subject: [PATCH 20/52] CRED: Pass credentials into rpc_init_task()

Pass credentials into rpc_init_task().

Signed-off-by: David Howells <dhowells@...hat.com>
---

 fs/lockd/clntlock.c            |    2 
 fs/lockd/clntproc.c            |   34 ++-
 fs/lockd/host.c                |    6 
 fs/lockd/mon.c                 |   21 +-
 fs/lockd/svc.c                 |    2 
 fs/lockd/svc4proc.c            |    6 
 fs/lockd/svclock.c             |   13 +
 fs/lockd/svcproc.c             |    7 -
 fs/nfs/callback.c              |    2 
 fs/nfs/callback.h              |    2 
 fs/nfs/client.c                |  103 +++++---
 fs/nfs/delegation.c            |   24 +-
 fs/nfs/delegation.h            |   10 +
 fs/nfs/dir.c                   |  111 ++++++---
 fs/nfs/direct.c                |   29 +-
 fs/nfs/file.c                  |   14 +
 fs/nfs/getroot.c               |   22 +-
 fs/nfs/inode.c                 |   45 +++-
 fs/nfs/internal.h              |   24 +-
 fs/nfs/mount_clnt.c            |    7 -
 fs/nfs/namespace.c             |    5 
 fs/nfs/nfs3acl.c               |   43 ++-
 fs/nfs/nfs3proc.c              |  130 ++++++----
 fs/nfs/nfs4_fs.h               |   30 ++
 fs/nfs/nfs4namespace.c         |    7 -
 fs/nfs/nfs4proc.c              |  496 ++++++++++++++++++++++++----------------
 fs/nfs/nfs4renewd.c            |    2 
 fs/nfs/nfs4state.c             |   16 +
 fs/nfs/proc.c                  |   99 ++++----
 fs/nfs/read.c                  |    7 -
 fs/nfs/super.c                 |   41 ++-
 fs/nfs/symlink.c               |   24 ++
 fs/nfs/unlink.c                |   18 +
 fs/nfs/write.c                 |   17 +
 include/linux/lockd/bind.h     |    5 
 include/linux/lockd/lockd.h    |    5 
 include/linux/lockd/sm_inter.h |    4 
 include/linux/nfs_fs.h         |   38 ++-
 include/linux/nfs_xdr.h        |   54 +++-
 include/linux/sunrpc/clnt.h    |   10 -
 include/linux/sunrpc/sched.h   |   13 +
 net/sunrpc/auth_gss/auth_gss.c |    2 
 net/sunrpc/clnt.c              |   50 +++-
 net/sunrpc/rpcb_clnt.c         |   14 +
 net/sunrpc/sched.c             |   22 +-
 net/sunrpc/svc.c               |    5 
 46 files changed, 980 insertions(+), 661 deletions(-)

diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index d070b18..653a83e 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -174,7 +174,7 @@ reclaimer(void *ptr)
 	/* This one ensures that our parent doesn't terminate while the
 	 * reclaim is in progress */
 	lock_kernel();
-	lockd_up(0); /* note: this cannot fail as lockd is already running */
+	lockd_up(0, &init_cred); /* note: this cannot fail as lockd is already running */
 
 	dprintk("lockd: reclaiming locks for host %s\n", host->h_name);
 
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index a10343b..fde8f25 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -28,7 +28,8 @@ static int	nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
 static int	nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
 static int	nlm_stat_to_errno(__be32 stat);
 static void	nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
-static int	nlmclnt_cancel(struct nlm_host *, int , struct file_lock *);
+static int	nlmclnt_cancel(struct nlm_host *, int , struct file_lock *,
+			       struct cred *);
 
 static const struct rpc_call_ops nlmclnt_unlock_ops;
 static const struct rpc_call_ops nlmclnt_cancel_ops;
@@ -149,7 +150,8 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
  * This is the main entry point for the NLM client.
  */
 int
-nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
+nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl,
+	     struct cred *acred)
 {
 	struct rpc_clnt		*client = NFS_CLIENT(inode);
 	struct sockaddr_in	addr;
@@ -173,7 +175,7 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
 	if (host == NULL)
 		return -ENOLCK;
 
-	call = nlm_alloc_call(host);
+	call = nlm_alloc_call(host, acred);
 	if (call == NULL)
 		return -ENOMEM;
 
@@ -227,7 +229,7 @@ EXPORT_SYMBOL(nlmclnt_proc);
  * Note: the caller must hold a reference to host. In case of failure,
  * this reference will be released.
  */
-struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)
+struct nlm_rqst *nlm_alloc_call(struct nlm_host *host, struct cred *acred)
 {
 	struct nlm_rqst	*call;
 
@@ -237,6 +239,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)
 			locks_init_lock(&call->a_args.lock.fl);
 			locks_init_lock(&call->a_res.lock.fl);
 			call->a_host = host;
+			call->a_acred = get_cred(acred);
 			return call;
 		}
 		if (signalled())
@@ -252,10 +255,11 @@ void nlm_release_call(struct nlm_rqst *call)
 {
 	nlm_release_host(call->a_host);
 	nlmclnt_release_lockargs(call);
+	put_cred(call->a_acred);
 	kfree(call);
 }
 
-static void nlmclnt_rpc_release(void *data)
+static void nlmclnt_rpc_release(struct cred *acred, void *data)
 {
 	return nlm_release_call(data);
 }
@@ -300,12 +304,12 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
 			goto in_grace_period;
 
 		/* If we have no RPC client yet, create one. */
-		if ((clnt = nlm_bind_host(host)) == NULL)
+		if ((clnt = nlm_bind_host(host, req->a_acred)) == NULL)
 			return -ENOLCK;
 		msg.rpc_proc = &clnt->cl_procinfo[proc];
 
 		/* Perform the RPC call. If an error occurs, try again */
-		if ((status = rpc_call_sync(clnt, &msg, 0)) < 0) {
+		if ((status = rpc_call_sync(clnt, &msg, 0, req->a_acred)) < 0) {
 			dprintk("lockd: rpc_call returned error %d\n", -status);
 			switch (status) {
 			case -EPROTONOSUPPORT:
@@ -365,15 +369,16 @@ static int __nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *
 			(int)proc, host->h_name);
 
 	/* If we have no RPC client yet, create one. */
-	clnt = nlm_bind_host(host);
+	clnt = nlm_bind_host(host, req->a_acred);
 	if (clnt == NULL)
 		goto out_err;
 	msg->rpc_proc = &clnt->cl_procinfo[proc];
 
         /* bootstrap and kick off the async RPC call */
-        return rpc_call_async(clnt, msg, RPC_TASK_ASYNC, tk_ops, req);
+        return rpc_call_async(clnt, msg, RPC_TASK_ASYNC, tk_ops, req,
+			      req->a_acred);
 out_err:
-	tk_ops->rpc_release(req);
+	tk_ops->rpc_release(req->a_acred, req);
 	return -ENOLCK;
 }
 
@@ -499,7 +504,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
 	unsigned char fl_flags = fl->fl_flags;
 	int status = -ENOLCK;
 
-	if (nsm_monitor(host) < 0) {
+	if (nsm_monitor(host, req->a_acred) < 0) {
 		printk(KERN_NOTICE "lockd: failed to monitor %s\n",
 					host->h_name);
 		goto out;
@@ -553,7 +558,7 @@ out_unblock:
 	nlmclnt_finish_block(block);
 	/* Cancel the blocked request if it is still pending */
 	if (resp->status == nlm_lck_blocked)
-		nlmclnt_cancel(host, req->a_args.block, fl);
+		nlmclnt_cancel(host, req->a_args.block, fl, req->a_acred);
 out:
 	nlm_release_call(req);
 	fl->fl_flags = fl_flags;
@@ -681,7 +686,8 @@ static const struct rpc_call_ops nlmclnt_unlock_ops = {
  * We always use an async RPC call for this in order not to hang a
  * process that has been Ctrl-C'ed.
  */
-static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl)
+static int nlmclnt_cancel(struct nlm_host *host, int block,
+			  struct file_lock *fl, struct cred *acred)
 {
 	struct nlm_rqst	*req;
 	unsigned long	flags;
@@ -695,7 +701,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl
 	recalc_sigpending();
 	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
-	req = nlm_alloc_call(nlm_get_host(host));
+	req = nlm_alloc_call(nlm_get_host(host), acred);
 	if (!req)
 		return -ENOMEM;
 	req->a_flags = RPC_TASK_ASYNC;
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 572601e..15071a2 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -163,7 +163,7 @@ nlm_destroy_host(struct nlm_host *host)
 	/*
 	 * Release NSM handle and unmonitor host.
 	 */
-	nsm_unmonitor(host);
+	nsm_unmonitor(host, current->cred);
 
 	clnt = host->h_rpcclnt;
 	if (clnt != NULL)
@@ -203,7 +203,7 @@ nlmsvc_lookup_host(struct svc_rqst *rqstp,
  * Create the NLM RPC client for an NLM peer
  */
 struct rpc_clnt *
-nlm_bind_host(struct nlm_host *host)
+nlm_bind_host(struct nlm_host *host, struct cred *acred)
 {
 	struct rpc_clnt	*clnt;
 
@@ -246,7 +246,7 @@ nlm_bind_host(struct nlm_host *host)
 					   RPC_CLNT_CREATE_AUTOBIND),
 		};
 
-		clnt = rpc_create(&args);
+		clnt = rpc_create(&args, acred);
 		if (!IS_ERR(clnt))
 			host->h_rpcclnt = clnt;
 		else {
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 3353ed8..f2ca99f 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -17,7 +17,7 @@
 
 #define NLMDBG_FACILITY		NLMDBG_MONITOR
 
-static struct rpc_clnt *	nsm_create(void);
+static struct rpc_clnt *	nsm_create(struct cred *);
 
 static struct rpc_program	nsm_program;
 
@@ -30,7 +30,8 @@ int				nsm_local_state;
  * Common procedure for SM_MON/SM_UNMON calls
  */
 static int
-nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
+nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
+	      struct cred *acred)
 {
 	struct rpc_clnt	*clnt;
 	int		status;
@@ -40,7 +41,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 		.rpc_resp	= res,
 	};
 
-	clnt = nsm_create();
+	clnt = nsm_create(acred);
 	if (IS_ERR(clnt)) {
 		status = PTR_ERR(clnt);
 		goto out;
@@ -55,7 +56,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 	memset(res, 0, sizeof(*res));
 
 	msg.rpc_proc = &clnt->cl_procinfo[proc];
-	status = rpc_call_sync(clnt, &msg, 0);
+	status = rpc_call_sync(clnt, &msg, 0, acred);
 	if (status < 0)
 		printk(KERN_DEBUG "nsm_mon_unmon: rpc failed, status=%d\n",
 			status);
@@ -70,7 +71,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
  * Set up monitoring of a remote host
  */
 int
-nsm_monitor(struct nlm_host *host)
+nsm_monitor(struct nlm_host *host, struct cred *acred)
 {
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
@@ -82,7 +83,7 @@ nsm_monitor(struct nlm_host *host)
 	if (nsm->sm_monitored)
 		return 0;
 
-	status = nsm_mon_unmon(nsm, SM_MON, &res);
+	status = nsm_mon_unmon(nsm, SM_MON, &res, acred);
 
 	if (status < 0 || res.status != 0)
 		printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name);
@@ -95,7 +96,7 @@ nsm_monitor(struct nlm_host *host)
  * Cease to monitor remote host
  */
 int
-nsm_unmonitor(struct nlm_host *host)
+nsm_unmonitor(struct nlm_host *host, struct cred *acred)
 {
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
@@ -109,7 +110,7 @@ nsm_unmonitor(struct nlm_host *host)
 	 && nsm->sm_monitored && !nsm->sm_sticky) {
 		dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
 
-		status = nsm_mon_unmon(nsm, SM_UNMON, &res);
+		status = nsm_mon_unmon(nsm, SM_UNMON, &res, acred);
 		if (status < 0)
 			printk(KERN_NOTICE "lockd: cannot unmonitor %s\n",
 					host->h_name);
@@ -124,7 +125,7 @@ nsm_unmonitor(struct nlm_host *host)
  * Create NSM client for the local host
  */
 static struct rpc_clnt *
-nsm_create(void)
+nsm_create(struct cred *acred)
 {
 	struct sockaddr_in	sin = {
 		.sin_family	= AF_INET,
@@ -141,7 +142,7 @@ nsm_create(void)
 		.authflavor	= RPC_AUTH_NULL,
 	};
 
-	return rpc_create(&args);
+	return rpc_create(&args, acred);
 }
 
 /*
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 82e2192..d4fd193 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -264,7 +264,7 @@ static int make_socks(struct svc_serv *serv, int proto)
  * Bring up the lockd process if it's not already up.
  */
 int
-lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
+lockd_up(int proto, struct cred *acred) /* Maybe add a 'family' option when IPv6 is supported ?? */
 {
 	struct svc_serv *	serv;
 	int			error = 0;
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index bf27b6c..16efd5a 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -39,7 +39,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 
 	/* Obtain host handle */
 	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
-	 || (argp->monitor && nsm_monitor(host) < 0))
+	 || (argp->monitor && nsm_monitor(host, current->cred) < 0))
 		goto no_locks;
 	*hostp = host;
 
@@ -242,7 +242,7 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
 			-task->tk_status);
 }
 
-static void nlm4svc_callback_release(void *data)
+static void nlm4svc_callback_release(struct cred *acred, void *data)
 {
 	nlm_release_call(data);
 }
@@ -270,7 +270,7 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args
 	if (host == NULL)
 		return rpc_system_err;
 
-	call = nlm_alloc_call(host);
+	call = nlm_alloc_call(host, current->cred);
 	if (call == NULL)
 		return rpc_system_err;
 
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index d120ec3..50d89ea 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -174,12 +174,12 @@ found:
 static struct nlm_block *
 nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
 		    struct nlm_file *file, struct nlm_lock *lock,
-		    struct nlm_cookie *cookie)
+		    struct nlm_cookie *cookie, struct cred *acred)
 {
 	struct nlm_block	*block;
 	struct nlm_rqst		*call = NULL;
 
-	call = nlm_alloc_call(host);
+	call = nlm_alloc_call(host, acred);
 	if (call == NULL)
 		return NULL;
 
@@ -360,6 +360,7 @@ __be32
 nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
 			struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
 {
+	struct cred		*acred = current->cred;
 	struct nlm_block	*block = NULL;
 	struct nlm_host		*host;
 	int			error;
@@ -386,7 +387,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
 	block = nlmsvc_lookup_block(file, lock);
 	if (block == NULL) {
 		block = nlmsvc_create_block(rqstp, nlm_get_host(host), file,
-				lock, cookie);
+				lock, cookie, acred);
 		ret = nlm_lck_denied_nolocks;
 		if (block == NULL)
 			goto out;
@@ -463,6 +464,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 		struct nlm_lock *lock, struct nlm_lock *conflock,
 		struct nlm_cookie *cookie)
 {
+	struct cred		*acred = current->cred;
 	struct nlm_block 	*block = NULL;
 	int			error;
 	__be32			ret;
@@ -489,7 +491,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 			kfree(conf);
 			return nlm_lck_denied_nolocks;
 		}
-		block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
+		block = nlmsvc_create_block(rqstp, host, file, lock, cookie,
+					    acred);
 		if (block == NULL) {
 			kfree(conf);
 			return nlm_granted;
@@ -796,7 +799,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
 	svc_wake_up(block->b_daemon);
 }
 
-static void nlmsvc_grant_release(void *data)
+static void nlmsvc_grant_release(struct cred *acred, void *data)
 {
 	struct nlm_rqst		*call = data;
 
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 9cd5c8b..f3265ed 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -68,7 +68,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 
 	/* Obtain host handle */
 	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
-	 || (argp->monitor && nsm_monitor(host) < 0))
+	 || (argp->monitor && nsm_monitor(host, current->cred) < 0))
 		goto no_locks;
 	*hostp = host;
 
@@ -272,7 +272,7 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
 			-task->tk_status);
 }
 
-static void nlmsvc_callback_release(void *data)
+static void nlmsvc_callback_release(struct cred *acred, void *data)
 {
 	nlm_release_call(data);
 }
@@ -290,6 +290,7 @@ static const struct rpc_call_ops nlmsvc_callback_ops = {
 static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
 		__be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res  *))
 {
+	struct cred *acred = current->cred;
 	struct nlm_host	*host;
 	struct nlm_rqst	*call;
 	__be32 stat;
@@ -300,7 +301,7 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args
 	if (host == NULL)
 		return rpc_system_err;
 
-	call = nlm_alloc_call(host);
+	call = nlm_alloc_call(host, acred);
 	if (call == NULL)
 		return rpc_system_err;
 
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a796be5..bca7d28 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -107,7 +107,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
 /*
  * Bring up the server process if it is not already up.
  */
-int nfs_callback_up(void)
+int nfs_callback_up(struct cred *acred)
 {
 	struct svc_serv *serv;
 	int ret = 0;
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index c2bb14e..8425611 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -63,7 +63,7 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getat
 extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
 
 #ifdef CONFIG_NFS_V4
-extern int nfs_callback_up(void);
+extern int nfs_callback_up(struct cred *acred);
 extern void nfs_callback_down(void);
 #else
 #define nfs_callback_up()	(0)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index a204484..61a1b20 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -99,7 +99,8 @@ struct rpc_program		nfsacl_program = {
  */
 static struct nfs_client *nfs_alloc_client(const char *hostname,
 					   const struct sockaddr_in *addr,
-					   int nfsversion)
+					   int nfsversion,
+					   struct cred *acred)
 {
 	struct nfs_client *clp;
 
@@ -107,7 +108,7 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
 		goto error_0;
 
 	if (nfsversion == 4) {
-		if (nfs_callback_up() < 0)
+		if (nfs_callback_up(acred) < 0)
 			goto error_2;
 		__set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
 	}
@@ -257,7 +258,8 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio
  */
 static struct nfs_client *nfs_get_client(const char *hostname,
 					 const struct sockaddr_in *addr,
-					 int nfsversion)
+					 int nfsversion,
+					 struct cred *acred)
 {
 	struct nfs_client *clp, *new = NULL;
 	int error;
@@ -278,7 +280,7 @@ static struct nfs_client *nfs_get_client(const char *hostname,
 
 		spin_unlock(&nfs_client_lock);
 
-		new = nfs_alloc_client(hostname, addr, nfsversion);
+		new = nfs_alloc_client(hostname, addr, nfsversion, acred);
 	} while (new);
 
 	return ERR_PTR(-ENOMEM);
@@ -368,7 +370,8 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
 						unsigned int timeo,
 						unsigned int retrans,
 						rpc_authflavor_t flavor,
-						int flags)
+						int flags,
+						struct cred *acred)
 {
 	struct rpc_timeout	timeparms;
 	struct rpc_clnt		*clnt = NULL;
@@ -391,7 +394,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
 	clp->retrans_timeo = timeparms.to_initval;
 	clp->retrans_count = timeparms.to_retries;
 
-	clnt = rpc_create(&args);
+	clnt = rpc_create(&args, acred);
 	if (IS_ERR(clnt)) {
 		dprintk("%s: cannot create RPC client. Error = %ld\n",
 				__FUNCTION__, PTR_ERR(clnt));
@@ -417,7 +420,7 @@ static void nfs_destroy_server(struct nfs_server *server)
 /*
  * Version 2 or 3 lockd setup
  */
-static int nfs_start_lockd(struct nfs_server *server)
+static int nfs_start_lockd(struct nfs_server *server, struct cred *acred)
 {
 	int error = 0;
 
@@ -426,7 +429,7 @@ static int nfs_start_lockd(struct nfs_server *server)
 	if (server->flags & NFS_MOUNT_NONLM)
 		goto out;
 	error = lockd_up((server->flags & NFS_MOUNT_TCP) ?
-			IPPROTO_TCP : IPPROTO_UDP);
+			IPPROTO_TCP : IPPROTO_UDP, acred);
 	if (error < 0)
 		server->flags |= NFS_MOUNT_NONLM;
 	else
@@ -439,14 +442,16 @@ out:
  * Initialise an NFSv3 ACL client connection
  */
 #ifdef CONFIG_NFS_V3_ACL
-static void nfs_init_server_aclclient(struct nfs_server *server)
+static void nfs_init_server_aclclient(struct nfs_server *server,
+				      struct cred *acred)
 {
 	if (server->nfs_client->cl_nfsversion != 3)
 		goto out_noacl;
 	if (server->flags & NFS_MOUNT_NOACL)
 		goto out_noacl;
 
-	server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
+	server->client_acl = rpc_bind_new_program(server->client,
+						  &nfsacl_program, 3, acred);
 	if (IS_ERR(server->client_acl))
 		goto out_noacl;
 
@@ -501,7 +506,9 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t
 /*
  * Initialise an NFS2 or NFS3 client
  */
-static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data)
+static int nfs_init_client(struct nfs_client *clp,
+			   const struct nfs_mount_data *data,
+			   struct cred *acred)
 {
 	int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
 	int error;
@@ -523,7 +530,7 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *
 	 * - RFC 2623, sec 2.3.2
 	 */
 	error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
-					RPC_AUTH_UNIX, 0);
+					RPC_AUTH_UNIX, 0, acred);
 	if (error < 0)
 		goto error;
 	nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -538,7 +545,9 @@ error:
 /*
  * Create a version 2 or 3 client
  */
-static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data)
+static int nfs_init_server(struct nfs_server *server,
+			   const struct nfs_mount_data *data,
+			   struct cred *acred)
 {
 	struct nfs_client *clp;
 	int error, nfsvers = 2;
@@ -551,13 +560,13 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
 #endif
 
 	/* Allocate or find a client reference we can use */
-	clp = nfs_get_client(data->hostname, &data->addr, nfsvers);
+	clp = nfs_get_client(data->hostname, &data->addr, nfsvers, acred);
 	if (IS_ERR(clp)) {
 		dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
 		return PTR_ERR(clp);
 	}
 
-	error = nfs_init_client(clp, data);
+	error = nfs_init_client(clp, data, acred);
 	if (error < 0)
 		goto error;
 
@@ -577,7 +586,7 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
 	server->acdirmax = data->acdirmax * HZ;
 
 	/* Start lockd here, before we might error out */
-	error = nfs_start_lockd(server);
+	error = nfs_start_lockd(server, acred);
 	if (error < 0)
 		goto error;
 
@@ -587,7 +596,7 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
 
 	server->namelen  = data->namlen;
 	/* Create a client RPC handle for the NFSv3 ACL management interface */
-	nfs_init_server_aclclient(server);
+	nfs_init_server_aclclient(server, acred);
 	dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
 	return 0;
 
@@ -651,7 +660,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
 /*
  * Probe filesystem information, including the FSID on v2/v3
  */
-static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
+static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh,
+			    struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct nfs_fsinfo fsinfo;
 	struct nfs_client *clp = server->nfs_client;
@@ -660,14 +670,14 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
 	dprintk("--> nfs_probe_fsinfo()\n");
 
 	if (clp->rpc_ops->set_capabilities != NULL) {
-		error = clp->rpc_ops->set_capabilities(server, mntfh);
+		error = clp->rpc_ops->set_capabilities(server, mntfh, acred);
 		if (error < 0)
 			goto out_error;
 	}
 
 	fsinfo.fattr = fattr;
 	nfs_fattr_init(fattr);
-	error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
+	error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo, acred);
 	if (error < 0)
 		goto out_error;
 
@@ -680,7 +690,8 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
 		pathinfo.fattr = fattr;
 		nfs_fattr_init(fattr);
 
-		if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
+		if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo,
+					   acred) >= 0)
 			server->namelen = pathinfo.max_namelen;
 	}
 
@@ -761,7 +772,7 @@ void nfs_free_server(struct nfs_server *server)
  * - keyed on server and FSID
  */
 struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
-				     struct nfs_fh *mntfh)
+				     struct nfs_fh *mntfh, struct cred *acred)
 {
 	struct nfs_server *server;
 	struct nfs_fattr fattr;
@@ -772,7 +783,7 @@ struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
 		return ERR_PTR(-ENOMEM);
 
 	/* Get a client representation */
-	error = nfs_init_server(server, data);
+	error = nfs_init_server(server, data, acred);
 	if (error < 0)
 		goto error;
 
@@ -781,7 +792,7 @@ struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
 	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
 
 	/* Probe the root fh to retrieve its FSID */
-	error = nfs_probe_fsinfo(server, mntfh, &fattr);
+	error = nfs_probe_fsinfo(server, mntfh, &fattr, acred);
 	if (error < 0)
 		goto error;
 	if (server->nfs_client->rpc_ops->version == 3) {
@@ -795,7 +806,8 @@ struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
 	}
 
 	if (!(fattr.valid & NFS_ATTR_FATTR)) {
-		error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
+		error = server->nfs_client->rpc_ops->getattr(server, mntfh,
+							     &fattr, acred);
 		if (error < 0) {
 			dprintk("nfs_create_server: getattr error = %d\n", -error);
 			goto error;
@@ -831,7 +843,8 @@ error:
 static int nfs4_init_client(struct nfs_client *clp,
 		int proto, int timeo, int retrans,
 		const char *ip_addr,
-		rpc_authflavor_t authflavour)
+		rpc_authflavor_t authflavour,
+		struct cred *acred)
 {
 	int error;
 
@@ -845,7 +858,7 @@ static int nfs4_init_client(struct nfs_client *clp,
 	clp->rpc_ops = &nfs_v4_clientops;
 
 	error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour,
-					RPC_CLNT_CREATE_DISCRTRY);
+					RPC_CLNT_CREATE_DISCRTRY, acred);
 	if (error < 0)
 		goto error;
 	memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
@@ -874,7 +887,8 @@ static int nfs4_set_client(struct nfs_server *server,
 		const char *hostname, const struct sockaddr_in *addr,
 		const char *ip_addr,
 		rpc_authflavor_t authflavour,
-		int proto, int timeo, int retrans)
+		int proto, int timeo, int retrans,
+		struct cred *acred)
 {
 	struct nfs_client *clp;
 	int error;
@@ -882,12 +896,13 @@ static int nfs4_set_client(struct nfs_server *server,
 	dprintk("--> nfs4_set_client()\n");
 
 	/* Allocate or find a client reference we can use */
-	clp = nfs_get_client(hostname, addr, 4);
+	clp = nfs_get_client(hostname, addr, 4, acred);
 	if (IS_ERR(clp)) {
 		error = PTR_ERR(clp);
 		goto error;
 	}
-	error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr, authflavour);
+	error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr,
+				 authflavour, acred);
 	if (error < 0)
 		goto error_put;
 
@@ -943,7 +958,8 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
 				      const char *mntpath,
 				      const char *ip_addr,
 				      rpc_authflavor_t authflavour,
-				      struct nfs_fh *mntfh)
+				      struct nfs_fh *mntfh,
+				      struct cred *acred)
 {
 	struct nfs_fattr fattr;
 	struct nfs_server *server;
@@ -957,7 +973,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
 
 	/* Get a client record */
 	error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour,
-			data->proto, data->timeo, data->retrans);
+			data->proto, data->timeo, data->retrans, acred);
 	if (error < 0)
 		goto error;
 
@@ -971,7 +987,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
 	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
 
 	/* Probe the root fh to retrieve its FSID */
-	error = nfs4_path_walk(server, mntfh, mntpath);
+	error = nfs4_path_walk(server, mntfh, mntpath, acred);
 	if (error < 0)
 		goto error;
 
@@ -980,7 +996,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
 		(unsigned long long) server->fsid.minor);
 	dprintk("Mount FH: %d\n", mntfh->size);
 
-	error = nfs_probe_fsinfo(server, mntfh, &fattr);
+	error = nfs_probe_fsinfo(server, mntfh, &fattr, acred);
 	if (error < 0)
 		goto error;
 
@@ -1010,7 +1026,8 @@ error:
  * Create an NFS4 referral server record
  */
 struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
-					       struct nfs_fh *mntfh)
+					       struct nfs_fh *mntfh,
+					       struct cred *acred)
 {
 	struct nfs_client *parent_client;
 	struct nfs_server *server, *parent_server;
@@ -1033,7 +1050,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 			data->authflavor,
 			parent_server->client->cl_xprt->prot,
 			parent_client->retrans_timeo,
-			parent_client->retrans_count);
+			parent_client->retrans_count,
+			acred);
 	if (error < 0)
 		goto error;
 
@@ -1050,12 +1068,12 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
 
 	/* Probe the root fh to retrieve its FSID and filehandle */
-	error = nfs4_path_walk(server, mntfh, data->mnt_path);
+	error = nfs4_path_walk(server, mntfh, data->mnt_path, acred);
 	if (error < 0)
 		goto error;
 
 	/* probe the filesystem info for this server filesystem */
-	error = nfs_probe_fsinfo(server, mntfh, &fattr);
+	error = nfs_probe_fsinfo(server, mntfh, &fattr, acred);
 	if (error < 0)
 		goto error;
 
@@ -1089,7 +1107,8 @@ error:
  */
 struct nfs_server *nfs_clone_server(struct nfs_server *source,
 				    struct nfs_fh *fh,
-				    struct nfs_fattr *fattr)
+				    struct nfs_fattr *fattr,
+				    struct cred *acred)
 {
 	struct nfs_server *server;
 	struct nfs_fattr fattr_fsinfo;
@@ -1114,10 +1133,10 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 	if (error < 0)
 		goto out_free_server;
 	if (!IS_ERR(source->client_acl))
-		nfs_init_server_aclclient(server);
+		nfs_init_server_aclclient(server, acred);
 
 	/* probe the filesystem info for this server filesystem */
-	error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo);
+	error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo, acred);
 	if (error < 0)
 		goto out_free_server;
 
@@ -1128,7 +1147,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 		(unsigned long long) server->fsid.major,
 		(unsigned long long) server->fsid.minor);
 
-	error = nfs_start_lockd(server);
+	error = nfs_start_lockd(server, acred);
 	if (error < 0)
 		goto out_free_server;
 
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index c55a761..3686cc0 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -29,6 +29,7 @@ static void nfs_free_delegation_callback(struct rcu_head *head)
 {
 	struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
 
+	put_cred(delegation->acred);
 	nfs_do_free_delegation(delegation);
 }
 
@@ -106,7 +107,8 @@ again:
 /*
  * Set up a delegation on an inode
  */
-void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
+void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
+				  struct nfs_openres *res, struct cred *acred)
 {
 	struct nfs_delegation *delegation = NFS_I(inode)->delegation;
 
@@ -118,6 +120,8 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st
 	delegation->maxsize = res->maxsize;
 	put_rpccred(cred);
 	delegation->cred = get_rpccred(cred);
+	put_cred(delegation->acred);
+	delegation->acred = get_cred(acred);
 	delegation->flags &= ~NFS_DELEGATION_NEED_RECLAIM;
 	NFS_I(inode)->delegation_state = delegation->type;
 	smp_wmb();
@@ -126,7 +130,8 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st
 /*
  * Set up a delegation on an inode
  */
-int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
+int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
+			     struct nfs_openres *res, struct cred *acred)
 {
 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
 	struct nfs_inode *nfsi = NFS_I(inode);
@@ -142,6 +147,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
 	delegation->maxsize = res->maxsize;
 	delegation->change_attr = nfsi->change_attr;
 	delegation->cred = get_rpccred(cred);
+	delegation->acred = get_cred(acred);
 	delegation->inode = inode;
 
 	spin_lock(&clp->cl_lock);
@@ -170,11 +176,14 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
 	return status;
 }
 
-static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation)
+static int nfs_do_return_delegation(struct inode *inode,
+				    struct nfs_delegation *delegation,
+				    struct cred *acred)
 {
 	int res = 0;
 
-	res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
+	res = nfs4_proc_delegreturn(inode, delegation->cred,
+				    &delegation->stateid, acred);
 	nfs_free_delegation(delegation);
 	return res;
 }
@@ -190,7 +199,8 @@ static void nfs_msync_inode(struct inode *inode)
 /*
  * Basic procedure for returning a delegation to the server
  */
-static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation)
+static int __nfs_inode_return_delegation(struct inode *inode,
+					 struct nfs_delegation *delegation)
 {
 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
 	struct nfs_inode *nfsi = NFS_I(inode);
@@ -204,7 +214,7 @@ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegat
 	up_read(&clp->cl_sem);
 	nfs_msync_inode(inode);
 
-	return nfs_do_return_delegation(inode, delegation);
+	return nfs_do_return_delegation(inode, delegation, delegation->acred);
 }
 
 static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
@@ -383,7 +393,7 @@ static int recall_thread(void *data)
 	nfs_msync_inode(inode);
 
 	if (delegation != NULL)
-		nfs_do_return_delegation(inode, delegation);
+		nfs_do_return_delegation(inode, delegation, &init_cred);
 	iput(inode);
 	module_put_and_exit(0);
 }
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 5874ce7..6319594 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -15,6 +15,7 @@
 struct nfs_delegation {
 	struct list_head super_list;
 	struct rpc_cred *cred;
+	struct cred *acred;
 	struct inode *inode;
 	nfs4_stateid stateid;
 	int type;
@@ -25,8 +26,10 @@ struct nfs_delegation {
 	struct rcu_head rcu;
 };
 
-int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
-void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
+int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
+			     struct nfs_openres *res, struct cred *acred);
+void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
+				  struct nfs_openres *res, struct cred *acred);
 int nfs_inode_return_delegation(struct inode *inode);
 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
 
@@ -39,7 +42,8 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp);
 void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
 
 /* NFSv4 delegation-related procedures */
-int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
+int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred,
+			  const nfs4_stateid *stateid, struct cred *acred);
 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid);
 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 53b9e24..35a63cf 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -175,6 +175,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
 {
 	struct file	*file = desc->file;
 	struct inode	*inode = file->f_path.dentry->d_inode;
+	struct cred	*acred = file->f_cred;
 	struct rpc_cred	*cred = nfs_file_cred(file);
 	unsigned long	timestamp;
 	int		error;
@@ -186,7 +187,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
  again:
 	timestamp = jiffies;
 	error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page,
-					  NFS_SERVER(inode)->dtsize, desc->plus);
+					  NFS_SERVER(inode)->dtsize, desc->plus,
+					  acred);
 	if (error < 0) {
 		/* We requested READDIRPLUS, but the server doesn't grok it */
 		if (error == -ENOTSUPP && desc->plus) {
@@ -472,6 +474,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
 {
 	struct file	*file = desc->file;
 	struct inode	*inode = file->f_path.dentry->d_inode;
+	struct cred	*acred = file->f_cred;
 	struct rpc_cred	*cred = nfs_file_cred(file);
 	struct page	*page = NULL;
 	int		status;
@@ -489,7 +492,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
 	desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie,
 						page,
 						NFS_SERVER(inode)->dtsize,
-						desc->plus);
+						desc->plus, acred);
 	spin_lock(&inode->i_lock);
 	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
 	spin_unlock(&inode->i_lock);
@@ -527,6 +530,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
  */
 static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
+	struct cred	*acred = filp->f_cred;
 	struct dentry	*dentry = filp->f_path.dentry;
 	struct inode	*inode = dentry->d_inode;
 	nfs_readdir_descriptor_t my_desc,
@@ -543,7 +547,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 
 	lock_kernel();
 
-	res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping);
+	res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping, acred);
 	if (res < 0) {
 		unlock_kernel();
 		return res;
@@ -703,7 +707,8 @@ static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigne
  *
  */
 static inline
-int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
+int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd,
+			    struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 
@@ -718,9 +723,9 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
 				 S_ISDIR(inode->i_mode)))
 			goto out_force;
 	}
-	return nfs_revalidate_inode(server, inode);
+	return nfs_revalidate_inode(server, inode, acred);
 out_force:
-	return __nfs_revalidate_inode(server, inode);
+	return __nfs_revalidate_inode(server, inode, acred);
 }
 
 /*
@@ -753,6 +758,7 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
  */
 static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
 {
+	struct cred *acred = current->cred;
 	struct inode *dir;
 	struct inode *inode;
 	struct dentry *parent;
@@ -768,7 +774,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
 	inode = dentry->d_inode;
 
 	/* Revalidate parent directory attribute cache */
-	if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
+	if (nfs_revalidate_inode(NFS_SERVER(dir), dir, acred) < 0)
 		goto out_zap_parent;
 
 	if (!inode) {
@@ -786,7 +792,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
 
 	/* Force a full look up iff the parent directory has changed */
 	if (nfs_check_verifier(dir, dentry)) {
-		if (nfs_lookup_verify_inode(inode, nd))
+		if (nfs_lookup_verify_inode(inode, nd, acred))
 			goto out_zap_parent;
 		goto out_valid;
 	}
@@ -795,7 +801,8 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
 		goto out_bad;
 
 	verifier = nfs_save_change_attribute(dir);
-	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr,
+				       acred);
 	if (error)
 		goto out_bad;
 	if (nfs_compare_fh(NFS_FH(inode), &fhandle))
@@ -869,7 +876,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
 	if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
 		lock_kernel();
 		drop_nlink(inode);
-		nfs_complete_unlink(dentry, inode);
+		nfs_complete_unlink(dentry, inode, &init_cred);
 		unlock_kernel();
 	}
 	/* When creating a negative dentry, we want to renew d_time */
@@ -897,18 +904,20 @@ int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
 	return (nd->intent.open.flags & O_EXCL) != 0;
 }
 
-static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr)
+static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr,
+				 struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(dir);
 
 	if (!nfs_fsid_equal(&server->fsid, &fattr->fsid))
 		/* Revalidate fsid using the parent directory */
-		return __nfs_revalidate_inode(server, dir);
+		return __nfs_revalidate_inode(server, dir, acred);
 	return 0;
 }
 
 static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
+	struct cred *acred = current->cred;
 	struct dentry *res;
 	struct inode *inode = NULL;
 	int error;
@@ -938,14 +947,15 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
 		goto out_unlock;
 	}
 
-	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr,
+				       acred);
 	if (error == -ENOENT)
 		goto no_entry;
 	if (error < 0) {
 		res = ERR_PTR(error);
 		goto out_unlock;
 	}
-	error = nfs_reval_fsid(dir, &fattr);
+	error = nfs_reval_fsid(dir, &fattr, acred);
 	if (error < 0) {
 		res = ERR_PTR(error);
 		goto out_unlock;
@@ -1004,6 +1014,7 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd)
 
 static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
+	struct cred *acred = current->cred;
 	struct dentry *res = NULL;
 	int error;
 
@@ -1029,7 +1040,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 	/* Open the file on the server */
 	lock_kernel();
 	/* Revalidate parent directory attribute cache */
-	error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
+	error = nfs_revalidate_inode(NFS_SERVER(dir), dir, acred);
 	if (error < 0) {
 		res = ERR_PTR(error);
 		unlock_kernel();
@@ -1038,10 +1049,10 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 
 	if (nd->intent.open.flags & O_CREAT) {
 		nfs_begin_data_update(dir);
-		res = nfs4_atomic_open(dir, dentry, nd);
+		res = nfs4_atomic_open(dir, dentry, nd, acred);
 		nfs_end_data_update(dir);
 	} else
-		res = nfs4_atomic_open(dir, dentry, nd);
+		res = nfs4_atomic_open(dir, dentry, nd, acred);
 	unlock_kernel();
 	if (IS_ERR(res)) {
 		error = PTR_ERR(res);
@@ -1073,6 +1084,7 @@ no_open:
 
 static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
+	struct cred *acred = current->cred;
 	struct dentry *parent = NULL;
 	struct inode *inode = dentry->d_inode;
 	struct inode *dir;
@@ -1105,7 +1117,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
 	 */
 	lock_kernel();
 	verifier = nfs_save_change_attribute(dir);
-	ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
+	ret = nfs4_open_revalidate(dir, dentry, openflags, nd, acred);
 	if (!ret)
 		nfs_refresh_verifier(dentry, verifier);
 	unlock_kernel();
@@ -1196,7 +1208,7 @@ out_renew:
  * Code common to create, mkdir, and mknod.
  */
 int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
-				struct nfs_fattr *fattr)
+				struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct inode *inode;
 	int error = -EACCES;
@@ -1206,13 +1218,15 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
 		return 0;
 	if (fhandle->size == 0) {
 		struct inode *dir = dentry->d_parent->d_inode;
-		error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
+		error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle,
+					       fattr, acred);
 		if (error)
 			return error;
 	}
 	if (!(fattr->valid & NFS_ATTR_FATTR)) {
 		struct nfs_server *server = NFS_SB(dentry->d_sb);
-		error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr);
+		error = server->nfs_client->rpc_ops->getattr(server, fhandle,
+							     fattr, acred);
 		if (error < 0)
 			return error;
 	}
@@ -1235,6 +1249,7 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
 static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
 		struct nameidata *nd)
 {
+	struct cred *acred = current->cred;
 	struct iattr attr;
 	int error;
 	int open_flags = 0;
@@ -1250,7 +1265,8 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
 
 	lock_kernel();
 	nfs_begin_data_update(dir);
-	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
+	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd,
+				       acred);
 	nfs_end_data_update(dir);
 	if (error != 0)
 		goto out_err;
@@ -1270,6 +1286,7 @@ out_err:
 static int
 nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 {
+	struct cred *acred = current->cred;
 	struct iattr attr;
 	int status;
 
@@ -1284,7 +1301,7 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 
 	lock_kernel();
 	nfs_begin_data_update(dir);
-	status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
+	status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev, acred);
 	nfs_end_data_update(dir);
 	if (status != 0)
 		goto out_err;
@@ -1303,6 +1320,7 @@ out_err:
  */
 static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
+	struct cred *acred = current->cred;
 	struct iattr attr;
 	int error;
 
@@ -1314,7 +1332,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
 	lock_kernel();
 	nfs_begin_data_update(dir);
-	error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
+	error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr, acred);
 	nfs_end_data_update(dir);
 	if (error != 0)
 		goto out_err;
@@ -1330,6 +1348,7 @@ out_err:
 
 static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
+	struct cred *acred = current->cred;
 	int error;
 
 	dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
@@ -1337,7 +1356,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
 
 	lock_kernel();
 	nfs_begin_data_update(dir);
-	error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
+	error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name, acred);
 	/* Ensure the VFS deletes this inode */
 	if (error == 0 && dentry->d_inode != NULL)
 		clear_nlink(dentry->d_inode);
@@ -1347,7 +1366,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
 	return error;
 }
 
-static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
+static int nfs_sillyrename(struct inode *dir, struct dentry *dentry,
+			   struct cred *acred)
 {
 	static unsigned int sillycounter;
 	const int      i_inosize  = sizeof(dir->i_ino)*2;
@@ -1402,18 +1422,18 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
 	if (dentry->d_inode) {
 		nfs_begin_data_update(dentry->d_inode);
 		error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
-				dir, &qsilly);
+				dir, &qsilly, acred);
 		nfs_mark_for_revalidate(dentry->d_inode);
 		nfs_end_data_update(dentry->d_inode);
 	} else
 		error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
-				dir, &qsilly);
+				dir, &qsilly, acred);
 	nfs_end_data_update(dir);
 	if (!error) {
 		nfs_renew_times(dentry);
 		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 		d_move(dentry, sdentry);
-		error = nfs_async_unlink(dir, dentry);
+		error = nfs_async_unlink(dir, dentry, acred);
  		/* If we return 0 we don't unlink */
 	}
 	dput(sdentry);
@@ -1428,7 +1448,7 @@ out:
  * We invalidate the attribute cache and free the inode prior to the operation
  * to avoid possible races if the server reuses the inode.
  */
-static int nfs_safe_remove(struct dentry *dentry)
+static int nfs_safe_remove(struct dentry *dentry, struct cred *acred)
 {
 	struct inode *dir = dentry->d_parent->d_inode;
 	struct inode *inode = dentry->d_inode;
@@ -1447,14 +1467,14 @@ static int nfs_safe_remove(struct dentry *dentry)
 	if (inode != NULL) {
 		nfs_inode_return_delegation(inode);
 		nfs_begin_data_update(inode);
-		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
+		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name, acred);
 		/* The VFS may want to delete this inode */
 		if (error == 0)
 			drop_nlink(inode);
 		nfs_mark_for_revalidate(inode);
 		nfs_end_data_update(inode);
 	} else
-		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
+		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name, acred);
 	nfs_end_data_update(dir);
 out:
 	return error;
@@ -1467,6 +1487,7 @@ out:
  */
 static int nfs_unlink(struct inode *dir, struct dentry *dentry)
 {
+	struct cred *acred = current->cred;
 	int error;
 	int need_rehash = 0;
 
@@ -1481,7 +1502,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
 		spin_unlock(&dcache_lock);
 		/* Start asynchronous writeout of the inode */
 		write_inode_now(dentry->d_inode, 0);
-		error = nfs_sillyrename(dir, dentry);
+		error = nfs_sillyrename(dir, dentry, acred);
 		unlock_kernel();
 		return error;
 	}
@@ -1491,7 +1512,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
 	}
 	spin_unlock(&dentry->d_lock);
 	spin_unlock(&dcache_lock);
-	error = nfs_safe_remove(dentry);
+	error = nfs_safe_remove(dentry, acred);
 	if (!error) {
 		nfs_renew_times(dentry);
 		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
@@ -1518,6 +1539,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
  */
 static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
 {
+	struct cred *acred = current->cred;
 	struct pagevec lru_pvec;
 	struct page *page;
 	char *kaddr;
@@ -1549,7 +1571,8 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
 	kunmap_atomic(kaddr, KM_USER0);
 
 	nfs_begin_data_update(dir);
-	error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
+	error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr,
+					acred);
 	nfs_end_data_update(dir);
 	if (error != 0) {
 		dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n",
@@ -1582,6 +1605,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
 static int 
 nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = old_dentry->d_inode;
 	int error;
 
@@ -1592,7 +1616,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 	lock_kernel();
 	nfs_begin_data_update(dir);
 	nfs_begin_data_update(inode);
-	error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
+	error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name, acred);
 	if (error == 0) {
 		atomic_inc(&inode->i_count);
 		d_instantiate(dentry, inode);
@@ -1630,6 +1654,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		      struct inode *new_dir, struct dentry *new_dentry)
 {
+	struct cred *acred = current->cred;
 	struct inode *old_inode = old_dentry->d_inode;
 	struct inode *new_inode = new_dentry->d_inode;
 	struct dentry *dentry = NULL, *rehash = NULL;
@@ -1673,7 +1698,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 			goto out;
 
 		/* silly-rename the existing target ... */
-		err = nfs_sillyrename(new_dir, new_dentry);
+		err = nfs_sillyrename(new_dir, new_dentry, acred);
 		if (!err) {
 			new_dentry = rehash = dentry;
 			new_inode = NULL;
@@ -1705,7 +1730,8 @@ go_ahead:
 	nfs_begin_data_update(new_dir);
 	nfs_begin_data_update(old_inode);
 	error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
-					   new_dir, &new_dentry->d_name);
+					   new_dir, &new_dentry->d_name,
+					   acred);
 	nfs_mark_for_revalidate(old_inode);
 	nfs_end_data_update(old_inode);
 	nfs_end_data_update(new_dir);
@@ -1934,7 +1960,8 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
 	}
 }
 
-static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
+static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask,
+			 struct cred *acred)
 {
 	struct nfs_access_entry cache;
 	int status;
@@ -1947,7 +1974,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
 	cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
 	cache.cred = cred;
 	cache.jiffies = jiffies;
-	status = NFS_PROTO(inode)->access(inode, &cache);
+	status = NFS_PROTO(inode)->access(inode, &cache, acred);
 	if (status != 0)
 		return status;
 	nfs_access_add_cache(inode, &cache);
@@ -1998,7 +2025,7 @@ force_lookup:
 
 	cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0, acred);
 	if (!IS_ERR(cred)) {
-		res = nfs_do_access(inode, cred, mask);
+		res = nfs_do_access(inode, cred, mask, acred);
 		put_rpccred(cred);
 	} else
 		res = PTR_ERR(cred);
@@ -2008,7 +2035,7 @@ out:
 		inode->i_sb->s_id, inode->i_ino, mask, res);
 	return res;
 out_notsup:
-	res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+	res = nfs_revalidate_inode(NFS_SERVER(inode), inode, acred);
 	if (res == 0)
 		res = generic_permission(inode, mask, NULL);
 	unlock_kernel();
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index fcf4d38..6c9491b 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -291,14 +291,14 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
 					data->npages, 1, 0, data->pagevec, NULL);
 		up_read(&current->mm->mmap_sem);
 		if (result < 0) {
-			nfs_readdata_release(data);
+			nfs_readdata_release(ctx->acred, data);
 			break;
 		}
 		if ((unsigned)result < data->npages) {
 			bytes = result * PAGE_SIZE;
 			if (bytes <= pgbase) {
 				nfs_direct_release_pages(data->pagevec, result);
-				nfs_readdata_release(data);
+				nfs_readdata_release(ctx->acred, data);
 				break;
 			}
 			bytes -= pgbase;
@@ -321,8 +321,8 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
 		data->res.count = bytes;
 
 		rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC,
-				&nfs_read_direct_ops, data);
-		NFS_PROTO(inode)->read_setup(data);
+			      &nfs_read_direct_ops, data, ctx->acred);
+		NFS_PROTO(inode)->read_setup(data, ctx->acred);
 
 		data->task.tk_cookie = (unsigned long) inode;
 
@@ -389,7 +389,7 @@ static void nfs_direct_free_writedata(struct nfs_direct_req *dreq)
 		struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages);
 		list_del(&data->pages);
 		nfs_direct_release_pages(data->pagevec, data->npages);
-		nfs_writedata_release(data);
+		nfs_writedata_release(dreq->ctx->acred, data);
 	}
 }
 
@@ -420,8 +420,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
 		 * since the original request was sent.
 		 */
 		rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC,
-				&nfs_write_direct_ops, data);
-		NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE);
+				&nfs_write_direct_ops, data, dreq->ctx->acred);
+		NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE,
+					      dreq->ctx->acred);
 
 		data->task.tk_priority = RPC_PRIORITY_NORMAL;
 		data->task.tk_cookie = (unsigned long) inode;
@@ -484,8 +485,8 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
 	data->res.verf = &data->verf;
 
 	rpc_init_task(&data->task, NFS_CLIENT(dreq->inode), RPC_TASK_ASYNC,
-				&nfs_commit_direct_ops, data);
-	NFS_PROTO(data->inode)->commit_setup(data, 0);
+				&nfs_commit_direct_ops, data, dreq->ctx->acred);
+	NFS_PROTO(data->inode)->commit_setup(data, 0, dreq->ctx->acred);
 
 	data->task.tk_priority = RPC_PRIORITY_NORMAL;
 	data->task.tk_cookie = (unsigned long)data->inode;
@@ -582,7 +583,7 @@ out_unlock:
  * NB: Return the value of the first error return code.  Subsequent
  *     errors after the first one are ignored.
  */
-static void nfs_direct_write_release(void *calldata)
+static void nfs_direct_write_release(struct cred *acred, void *calldata)
 {
 	struct nfs_write_data *data = calldata;
 	struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
@@ -631,14 +632,14 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
 					data->npages, 0, 0, data->pagevec, NULL);
 		up_read(&current->mm->mmap_sem);
 		if (result < 0) {
-			nfs_writedata_release(data);
+			nfs_writedata_release(ctx->acred, data);
 			break;
 		}
 		if ((unsigned)result < data->npages) {
 			bytes = result * PAGE_SIZE;
 			if (bytes <= pgbase) {
 				nfs_direct_release_pages(data->pagevec, result);
-				nfs_writedata_release(data);
+				nfs_writedata_release(ctx->acred, data);
 				break;
 			}
 			bytes -= pgbase;
@@ -663,8 +664,8 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
 		data->res.verf = &data->verf;
 
 		rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC,
-				&nfs_write_direct_ops, data);
-		NFS_PROTO(inode)->write_setup(data, sync);
+				&nfs_write_direct_ops, data, ctx->acred);
+		NFS_PROTO(inode)->write_setup(data, sync, ctx->acred);
 
 		data->task.tk_priority = RPC_PRIORITY_NORMAL;
 		data->task.tk_cookie = (unsigned long) inode;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 579cf8a..72f0850 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -158,7 +158,7 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
 	if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
 		return 0;
 force_reval:
-	return __nfs_revalidate_inode(server, inode);
+	return __nfs_revalidate_inode(server, inode, filp->f_cred);
 }
 
 static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
@@ -196,7 +196,8 @@ nfs_file_flush(struct file *file, fl_owner_t id)
 		status = ctx->error;
 		ctx->error = 0;
 		if (!status)
-			nfs_revalidate_inode(NFS_SERVER(inode), inode);
+			nfs_revalidate_inode(NFS_SERVER(inode), inode,
+					     ctx->acred);
 	}
 	unlock_kernel();
 	return status;
@@ -208,6 +209,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
 {
 	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
 	struct inode * inode = dentry->d_inode;
+	struct cred *acred = iocb->ki_filp->f_cred;
 	ssize_t result;
 	size_t count = iov_length(iov, nr_segs);
 
@@ -220,7 +222,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
 		dentry->d_parent->d_name.name, dentry->d_name.name,
 		(unsigned long) count, (unsigned long) pos);
 
-	result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
+	result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping, acred);
 	nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
 	if (!result)
 		result = generic_file_aio_read(iocb, iov, nr_segs, pos);
@@ -234,13 +236,14 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
 {
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
+	struct cred *acred = filp->f_cred;
 	ssize_t res;
 
 	dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
 		(unsigned long) count, (unsigned long long) *ppos);
 
-	res = nfs_revalidate_mapping(inode, filp->f_mapping);
+	res = nfs_revalidate_mapping(inode, filp->f_mapping, acred);
 	if (!res)
 		res = generic_file_splice_read(filp, ppos, pipe, count, flags);
 	return res;
@@ -251,12 +254,13 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
 {
 	struct dentry *dentry = file->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
+	struct cred *acred = file->f_cred;
 	int	status;
 
 	dfprintk(VFS, "nfs: mmap(%s/%s)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name);
 
-	status = nfs_revalidate_mapping(inode, file->f_mapping);
+	status = nfs_revalidate_mapping(inode, file->f_mapping, acred);
 	if (!status)
 		status = generic_file_mmap(file, vma);
 	return status;
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 93d1479..17a0ac8 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -45,7 +45,8 @@
 /*
  * get an NFS2/NFS3 root dentry from the root filehandle
  */
-struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
+struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
+			    struct cred *acred)
 {
 	struct nfs_server *server = NFS_SB(sb);
 	struct nfs_fsinfo fsinfo;
@@ -84,7 +85,8 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
 	/* get the actual root for this mount */
 	fsinfo.fattr = &fattr;
 
-	error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
+	error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo,
+						     acred);
 	if (error < 0) {
 		dprintk("nfs_get_root: getattr error = %d\n", -error);
 		return ERR_PTR(error);
@@ -126,7 +128,8 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
  */
 int nfs4_path_walk(struct nfs_server *server,
 		   struct nfs_fh *mntfh,
-		   const char *path)
+		   const char *path,
+		   struct cred *acred)
 {
 	struct nfs_fsinfo fsinfo;
 	struct nfs_fattr fattr;
@@ -144,7 +147,8 @@ int nfs4_path_walk(struct nfs_server *server,
 		path++;
 
 	/* Start by getting the root filehandle from the server */
-	ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
+	ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo,
+						   acred);
 	if (ret < 0) {
 		dprintk("nfs4_get_root: getroot error = %d\n", -ret);
 		return ret;
@@ -201,7 +205,7 @@ eat_dot_dir:
 	dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path);
 
 	ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name,
-						    mntfh, &fattr);
+						    mntfh, &fattr, acred);
 	if (ret < 0) {
 		dprintk("nfs4_get_root: getroot error = %d\n", -ret);
 		return ret;
@@ -231,7 +235,8 @@ path_walk_complete:
 /*
  * get an NFS4 root dentry from the root filehandle
  */
-struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
+struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh,
+			     struct cred *acred)
 {
 	struct nfs_server *server = NFS_SB(sb);
 	struct nfs_fattr fattr;
@@ -269,7 +274,7 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
 	}
 
 	/* get the info about the server and filesystem */
-	error = nfs4_server_capabilities(server, mntfh);
+	error = nfs4_server_capabilities(server, mntfh, acred);
 	if (error < 0) {
 		dprintk("nfs_get_root: getcaps error = %d\n",
 			-error);
@@ -277,7 +282,8 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
 	}
 
 	/* get the actual root for this mount */
-	error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
+	error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr,
+						     acred);
 	if (error < 0) {
 		dprintk("nfs_get_root: getattr error = %d\n", -error);
 		return ERR_PTR(error);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 0dd2ac3..300560f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -321,6 +321,7 @@ out_no_inode:
 int
 nfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	struct nfs_fattr fattr;
 	int error;
@@ -349,7 +350,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
 	 */
 	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
 		nfs_inode_return_delegation(inode);
-	error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
+	error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr, acred);
 	if (error == 0)
 		nfs_refresh_inode(inode, &fattr);
 	nfs_end_data_update(inode);
@@ -425,6 +426,7 @@ static void nfs_wake_up_inode(struct inode *inode)
 
 int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
 	int err;
@@ -447,15 +449,18 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 		need_atime = 0;
 
 	if (need_atime)
-		err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+		err = __nfs_revalidate_inode(NFS_SERVER(inode), inode, acred);
 	else
-		err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+		err = nfs_revalidate_inode(NFS_SERVER(inode), inode, acred);
 	if (!err)
 		generic_fillattr(inode, stat);
 	return err;
 }
 
-static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred)
+static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt,
+						       struct dentry *dentry,
+						       struct rpc_cred *cred,
+						       struct cred *acred)
 {
 	struct nfs_open_context *ctx;
 
@@ -463,6 +468,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
 	if (ctx != NULL) {
 		ctx->path.dentry = dget(dentry);
 		ctx->path.mnt = mntget(mnt);
+		ctx->acred = get_cred(acred);
 		ctx->cred = get_rpccred(cred);
 		ctx->state = NULL;
 		ctx->lockowner = current->files;
@@ -489,9 +495,10 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
 	list_del(&ctx->list);
 	spin_unlock(&inode->i_lock);
 	if (ctx->state != NULL)
-		nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+		nfs4_close_state(&ctx->path, ctx->state, ctx->mode, ctx->acred);
 	if (ctx->cred != NULL)
 		put_rpccred(ctx->cred);
+	put_cred(ctx->acred);
 	dput(ctx->path.dentry);
 	mntput(ctx->path.mnt);
 	kfree(ctx);
@@ -558,7 +565,8 @@ int nfs_open(struct inode *inode, struct file *filp)
 	cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0, filp->f_cred);
 	if (IS_ERR(cred))
 		return PTR_ERR(cred);
-	ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred);
+	ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred,
+				     filp->f_cred);
 	put_rpccred(cred);
 	if (ctx == NULL)
 		return -ENOMEM;
@@ -579,7 +587,8 @@ int nfs_release(struct inode *inode, struct file *filp)
  * the cached attributes have to be refreshed.
  */
 int
-__nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
+__nfs_revalidate_inode(struct nfs_server *server, struct inode *inode,
+		       struct cred *acred)
 {
 	int		 status = -ESTALE;
 	struct nfs_fattr fattr;
@@ -609,7 +618,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 		}
 	}
 
-	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
+	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr,
+					   acred);
 	if (status != 0) {
 		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
 			 inode->i_sb->s_id,
@@ -661,15 +671,17 @@ int nfs_attribute_timeout(struct inode *inode)
  * nfs_revalidate_inode - Revalidate the inode attributes
  * @server - pointer to nfs_server struct
  * @inode - pointer to inode struct
+ * @acred - the credentials to use
  *
  * Updates inode attribute information by retrieving the data from the server.
  */
-int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
+int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode,
+			 struct cred *acred)
 {
 	if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR)
 			&& !nfs_attribute_timeout(inode))
 		return NFS_STALE(inode) ? -ESTALE : 0;
-	return __nfs_revalidate_inode(server, inode);
+	return __nfs_revalidate_inode(server, inode, acred);
 }
 
 static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
@@ -713,15 +725,18 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
  * nfs_revalidate_mapping_nolock - Revalidate the pagecache
  * @inode - pointer to host inode
  * @mapping - pointer to mapping
+ * @acred - the credentials to use
  */
-int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
+int nfs_revalidate_mapping_nolock(struct inode *inode,
+				  struct address_space *mapping,
+				  struct cred *acred)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 	int ret = 0;
 
 	if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
 			|| nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
-		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode, acred);
 		if (ret < 0)
 			goto out;
 	}
@@ -735,18 +750,20 @@ out:
  * nfs_revalidate_mapping - Revalidate the pagecache
  * @inode - pointer to host inode
  * @mapping - pointer to mapping
+ * @acred - the credentials to use
  *
  * This version of the function will take the inode->i_mutex and attempt to
  * flush out all dirty data if it needs to invalidate the page cache.
  */
-int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
+int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping,
+			   struct cred *acred)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 	int ret = 0;
 
 	if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
 			|| nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
-		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode, acred);
 		if (ret < 0)
 			goto out;
 	}
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 76cf55d..777f1ac 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -33,20 +33,23 @@ extern struct rpc_program nfs_program;
 extern void nfs_put_client(struct nfs_client *);
 extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
 extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *,
-					    struct nfs_fh *);
+					    struct nfs_fh *, struct cred *);
 extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *,
 					     const char *,
 					     const struct sockaddr_in *,
 					     const char *,
 					     const char *,
 					     rpc_authflavor_t,
-					     struct nfs_fh *);
+					     struct nfs_fh *,
+					     struct cred *);
 extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
-						      struct nfs_fh *);
+						      struct nfs_fh *,
+						      struct cred *);
 extern void nfs_free_server(struct nfs_server *server);
 extern struct nfs_server *nfs_clone_server(struct nfs_server *,
 					   struct nfs_fh *,
-					   struct nfs_fattr *);
+					   struct nfs_fattr *,
+					   struct cred *);
 #ifdef CONFIG_PROC_FS
 extern int __init nfs_fs_proc_init(void);
 extern void nfs_fs_proc_exit(void);
@@ -62,7 +65,9 @@ static inline void nfs_fs_proc_exit(void)
 
 /* nfs4namespace.c */
 #ifdef CONFIG_NFS_V4
-extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
+extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
+					struct dentry *dentry,
+					struct cred *acred);
 #else
 static inline
 struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
@@ -140,13 +145,16 @@ extern char *nfs_path(const char *base,
 		      char *buffer, ssize_t buflen);
 
 /* getroot.c */
-extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *);
+extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
+				   struct cred *);
 #ifdef CONFIG_NFS_V4
-extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *);
+extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
+				    struct cred *);
 
 extern int nfs4_path_walk(struct nfs_server *server,
 			  struct nfs_fh *mntfh,
-			  const char *path);
+			  const char *path,
+			  struct cred *acred);
 #endif
 
 /*
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 8afd9f7..50da910 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -35,11 +35,12 @@ struct mnt_fhstatus {
  * @version: mount version to use for this request
  * @protocol: transport protocol to use for thie request
  * @fh: pointer to location to place returned file handle
+ * @cred: the credentials to use
  *
  * Uses default timeout parameters specified by underlying transport.
  */
 int nfs_mount(struct sockaddr *addr, size_t len, char *hostname, char *path,
-	      int version, int protocol, struct nfs_fh *fh)
+	      int version, int protocol, struct nfs_fh *fh, struct cred *acred)
 {
 	struct mnt_fhstatus	result = {
 		.fh		= fh
@@ -64,7 +65,7 @@ int nfs_mount(struct sockaddr *addr, size_t len, char *hostname, char *path,
 	dprintk("NFS: sending MNT request for %s:%s\n",
 		(hostname ? hostname : "server"), path);
 
-	mnt_clnt = rpc_create(&args);
+	mnt_clnt = rpc_create(&args, acred);
 	if (IS_ERR(mnt_clnt))
 		goto out_clnt_err;
 
@@ -73,7 +74,7 @@ int nfs_mount(struct sockaddr *addr, size_t len, char *hostname, char *path,
 	else
 		msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT];
 
-	status = rpc_call_sync(mnt_clnt, &msg, 0);
+	status = rpc_call_sync(mnt_clnt, &msg, 0, acred);
 	rpc_shutdown_client(mnt_clnt);
 
 	if (status < 0)
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index acfc56f..b8d3576 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -96,6 +96,7 @@ Elong:
  */
 static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 {
+	struct cred *acred = current->cred;
 	struct vfsmount *mnt;
 	struct nfs_server *server = NFS_SERVER(dentry->d_inode);
 	struct dentry *parent;
@@ -114,13 +115,13 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 	parent = dget_parent(nd->dentry);
 	err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
 						  &nd->dentry->d_name,
-						  &fh, &fattr);
+						  &fh, &fattr, acred);
 	dput(parent);
 	if (err != 0)
 		goto out_err;
 
 	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
-		mnt = nfs_do_refmount(nd->mnt, nd->dentry);
+		mnt = nfs_do_refmount(nd->mnt, nd->dentry, acred);
 	else
 		mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr);
 	err = PTR_ERR(mnt);
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 7322da4..0fefed1 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -9,6 +9,7 @@
 
 ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	struct posix_acl *acl;
 	int pos=0, len=0;
@@ -21,7 +22,7 @@ ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
 			len += sizeof(s);				\
 		} while(0)
 
-	acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS);
+	acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS, acred);
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
 	if (acl) {
@@ -30,7 +31,7 @@ ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
 	}
 
 	if (S_ISDIR(inode->i_mode)) {
-		acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT);
+		acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT, acred);
 		if (IS_ERR(acl))
 			return PTR_ERR(acl);
 		if (acl) {
@@ -49,6 +50,7 @@ ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
 ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
 		void *buffer, size_t size)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	struct posix_acl *acl;
 	int type, error = 0;
@@ -60,7 +62,7 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
 	else
 		return -EOPNOTSUPP;
 
-	acl = nfs3_proc_getacl(inode, type);
+	acl = nfs3_proc_getacl(inode, type, acred);
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
 	else if (acl) {
@@ -78,6 +80,7 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
 int nfs3_setxattr(struct dentry *dentry, const char *name,
 	     const void *value, size_t size, int flags)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	struct posix_acl *acl;
 	int type, error;
@@ -92,7 +95,7 @@ int nfs3_setxattr(struct dentry *dentry, const char *name,
 	acl = posix_acl_from_xattr(value, size);
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
-	error = nfs3_proc_setacl(inode, type, acl);
+	error = nfs3_proc_setacl(inode, type, acl, acred);
 	posix_acl_release(acl);
 
 	return error;
@@ -100,6 +103,7 @@ int nfs3_setxattr(struct dentry *dentry, const char *name,
 
 int nfs3_removexattr(struct dentry *dentry, const char *name)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	int type;
 
@@ -110,7 +114,7 @@ int nfs3_removexattr(struct dentry *dentry, const char *name)
 	else
 		return -EOPNOTSUPP;
 
-	return nfs3_proc_setacl(inode, type, NULL);
+	return nfs3_proc_setacl(inode, type, NULL, acred);
 }
 
 static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
@@ -179,7 +183,8 @@ static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
 	spin_unlock(&inode->i_lock);
 }
 
-struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
+struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type,
+				   struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_fattr fattr;
@@ -202,7 +207,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
 	if (!nfs_server_capable(inode, NFS_CAP_ACLS))
 		return ERR_PTR(-EOPNOTSUPP);
 
-	status = nfs_revalidate_inode(server, inode);
+	status = nfs_revalidate_inode(server, inode, acred);
 	if (status < 0)
 		return ERR_PTR(status);
 	acl = nfs3_get_cached_acl(inode, type);
@@ -225,7 +230,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
 
 	dprintk("NFS call getacl\n");
 	msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL];
-	status = rpc_call_sync(server->client_acl, &msg, 0);
+	status = rpc_call_sync(server->client_acl, &msg, 0, acred);
 	dprintk("NFS reply getacl: %d\n", status);
 
 	/* pages may have been allocated at the xdr layer. */
@@ -283,7 +288,7 @@ getout:
 }
 
 static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
-		  struct posix_acl *dfacl)
+		  struct posix_acl *dfacl, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_fattr fattr;
@@ -319,7 +324,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
 	dprintk("NFS call setacl\n");
 	nfs_begin_data_update(inode);
 	msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
-	status = rpc_call_sync(server->client_acl, &msg, 0);
+	status = rpc_call_sync(server->client_acl, &msg, 0, acred);
 	spin_lock(&inode->i_lock);
 	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS;
 	spin_unlock(&inode->i_lock);
@@ -347,7 +352,8 @@ out:
 	return status;
 }
 
-int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
+int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl,
+		     struct cred *acred)
 {
 	struct posix_acl *alloc = NULL, *dfacl = NULL;
 	int status;
@@ -356,7 +362,7 @@ int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
 		switch(type) {
 			case ACL_TYPE_ACCESS:
 				alloc = dfacl = nfs3_proc_getacl(inode,
-						ACL_TYPE_DEFAULT);
+						ACL_TYPE_DEFAULT, acred);
 				if (IS_ERR(alloc))
 					goto fail;
 				break;
@@ -364,7 +370,7 @@ int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
 			case ACL_TYPE_DEFAULT:
 				dfacl = acl;
 				alloc = acl = nfs3_proc_getacl(inode,
-						ACL_TYPE_ACCESS);
+						ACL_TYPE_ACCESS, acred);
 				if (IS_ERR(alloc))
 					goto fail;
 				break;
@@ -380,7 +386,7 @@ int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
 		if (IS_ERR(alloc))
 			goto fail;
 	}
-	status = nfs3_proc_setacls(inode, acl, dfacl);
+	status = nfs3_proc_setacls(inode, acl, dfacl, acred);
 	posix_acl_release(alloc);
 	return status;
 
@@ -389,12 +395,12 @@ fail:
 }
 
 int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
-		mode_t mode)
+		mode_t mode, struct cred *acred)
 {
 	struct posix_acl *dfacl, *acl;
 	int error = 0;
 
-	dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT);
+	dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT, acred);
 	if (IS_ERR(dfacl)) {
 		error = PTR_ERR(dfacl);
 		return (error == -EOPNOTSUPP) ? 0 : error;
@@ -408,8 +414,9 @@ int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
 	error = posix_acl_create_masq(acl, &mode);
 	if (error < 0)
 		goto out_release_acl;
-	error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
-						      dfacl : NULL);
+	error = nfs3_proc_setacls(inode, acl,
+				  S_ISDIR(inode->i_mode) ? dfacl : NULL,
+				  acred);
 out_release_acl:
 	posix_acl_release(acl);
 out_release_dfacl:
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 329e6a2..4d66cfd 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -25,13 +25,14 @@
 
 /* A wrapper to handle the EJUKEBOX error message */
 static int
-nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
+nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
+		 struct cred *acred)
 {
 	sigset_t oldset;
 	int res;
 	rpc_clnt_sigmask(clnt, &oldset);
 	do {
-		res = rpc_call_sync(clnt, msg, flags);
+		res = rpc_call_sync(clnt, msg, flags, acred);
 		if (res != -EJUKEBOX)
 			break;
 		schedule_timeout_interruptible(NFS_JUKEBOX_RETRY_TIME);
@@ -41,7 +42,8 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
 	return res;
 }
 
-#define rpc_call_sync(clnt, msg, flags)	nfs3_rpc_wrapper(clnt, msg, flags)
+#define rpc_call_sync(clnt, msg, flags, acred) \
+	nfs3_rpc_wrapper(clnt, msg, flags, acred)
 
 static int
 nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
@@ -57,7 +59,7 @@ nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
 
 static int
 do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
-		 struct nfs_fsinfo *info)
+		 struct nfs_fsinfo *info, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_FSINFO],
@@ -68,12 +70,12 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
 
 	dprintk("%s: call  fsinfo\n", __FUNCTION__);
 	nfs_fattr_init(info->fattr);
-	status = rpc_call_sync(client, &msg, 0);
+	status = rpc_call_sync(client, &msg, 0, acred);
 	dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
 	if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
 		msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
 		msg.rpc_resp = info->fattr;
-		status = rpc_call_sync(client, &msg, 0);
+		status = rpc_call_sync(client, &msg, 0, acred);
 		dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
 	}
 	return status;
@@ -84,13 +86,14 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
  */
 static int
 nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
-		   struct nfs_fsinfo *info)
+		   struct nfs_fsinfo *info, struct cred *acred)
 {
 	int	status;
 
-	status = do_proc_get_root(server->client, fhandle, info);
+	status = do_proc_get_root(server->client, fhandle, info, acred);
 	if (status && server->nfs_client->cl_rpcclient != server->client)
-		status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info);
+		status = do_proc_get_root(server->nfs_client->cl_rpcclient,
+					  fhandle, info, acred);
 	return status;
 }
 
@@ -99,7 +102,7 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  */
 static int
 nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_fattr *fattr)
+		struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_GETATTR],
@@ -110,14 +113,14 @@ nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  getattr\n");
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply getattr: %d\n", status);
 	return status;
 }
 
 static int
 nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
-			struct iattr *sattr)
+			struct iattr *sattr, struct cred *acred)
 {
 	struct inode *inode = dentry->d_inode;
 	struct nfs3_sattrargs	arg = {
@@ -133,7 +136,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 	dprintk("NFS call  setattr\n");
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	if (status == 0)
 		nfs_setattr_update_inode(inode, sattr);
 	dprintk("NFS reply setattr: %d\n", status);
@@ -142,7 +145,8 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 static int
 nfs3_proc_lookup(struct inode *dir, struct qstr *name,
-		 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+		 struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+		 struct cred *acred)
 {
 	struct nfs_fattr	dir_attr;
 	struct nfs3_diropargs	arg = {
@@ -165,12 +169,12 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
 	dprintk("NFS call  lookup %s\n", name->name);
 	nfs_fattr_init(&dir_attr);
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
 		msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
 		msg.rpc_argp = fhandle;
 		msg.rpc_resp = fattr;
-		status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+		status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	}
 	dprintk("NFS reply lookup: %d\n", status);
 	if (status >= 0)
@@ -178,7 +182,8 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
 	return status;
 }
 
-static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
+static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry,
+			    struct cred *acred)
 {
 	struct nfs_fattr	fattr;
 	struct nfs3_accessargs	arg = {
@@ -212,7 +217,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 			arg.access |= NFS3_ACCESS_EXECUTE;
 	}
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	nfs_refresh_inode(inode, &fattr);
 	if (status == 0) {
 		entry->mask = 0;
@@ -228,7 +233,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 }
 
 static int nfs3_proc_readlink(struct inode *inode, struct page *page,
-		unsigned int pgbase, unsigned int pglen)
+		unsigned int pgbase, unsigned int pglen, struct cred *acred)
 {
 	struct nfs_fattr	fattr;
 	struct nfs3_readlinkargs args = {
@@ -246,7 +251,7 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
 
 	dprintk("NFS call  readlink\n");
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	nfs_refresh_inode(inode, &fattr);
 	dprintk("NFS reply readlink: %d\n", status);
 	return status;
@@ -258,7 +263,7 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
  */
 static int
 nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-		 int flags, struct nameidata *nd)
+		 int flags, struct nameidata *nd, struct cred *acred)
 {
 	struct nfs_fh		fhandle;
 	struct nfs_fattr	fattr;
@@ -295,7 +300,7 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 again:
 	nfs_fattr_init(&dir_attr);
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_refresh_inode(dir, &dir_attr);
 
 	/* If the server doesn't support the exclusive creation semantics,
@@ -317,7 +322,7 @@ again:
 	}
 
 	if (status == 0)
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	if (status != 0)
 		goto out;
 
@@ -334,20 +339,20 @@ again:
 		/* Note: we could use a guarded setattr here, but I'm
 		 * not sure this buys us anything (and I'd have
 		 * to revamp the NFSv3 XDR code) */
-		status = nfs3_proc_setattr(dentry, &fattr, sattr);
+		status = nfs3_proc_setattr(dentry, &fattr, sattr, acred);
 		nfs_post_op_update_inode(dentry->d_inode, &fattr);
 		dprintk("NFS reply setattr (post-create): %d\n", status);
 	}
 	if (status != 0)
 		goto out;
-	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
+	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode, acred);
 out:
 	dprintk("NFS reply create: %d\n", status);
 	return status;
 }
 
 static int
-nfs3_proc_remove(struct inode *dir, struct qstr *name)
+nfs3_proc_remove(struct inode *dir, struct qstr *name, struct cred *acred)
 {
 	struct nfs_removeargs arg = {
 		.fh = NFS_FH(dir),
@@ -364,7 +369,7 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name)
 
 	dprintk("NFS call  remove %s\n", name->name);
 	nfs_fattr_init(&res.dir_attr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_post_op_update_inode(dir, &res.dir_attr);
 	dprintk("NFS reply remove: %d\n", status);
 	return status;
@@ -389,7 +394,8 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
 
 static int
 nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
-		 struct inode *new_dir, struct qstr *new_name)
+		 struct inode *new_dir, struct qstr *new_name,
+		 struct cred *acred)
 {
 	struct nfs_fattr	old_dir_attr, new_dir_attr;
 	struct nfs3_renameargs	arg = {
@@ -414,7 +420,7 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
 	dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
 	nfs_fattr_init(&old_dir_attr);
 	nfs_fattr_init(&new_dir_attr);
-	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0, acred);
 	nfs_post_op_update_inode(old_dir, &old_dir_attr);
 	nfs_post_op_update_inode(new_dir, &new_dir_attr);
 	dprintk("NFS reply rename: %d\n", status);
@@ -422,7 +428,8 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
 }
 
 static int
-nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
+nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name,
+	       struct cred *acred)
 {
 	struct nfs_fattr	dir_attr, fattr;
 	struct nfs3_linkargs	arg = {
@@ -445,7 +452,7 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 	dprintk("NFS call  link %s\n", name->name);
 	nfs_fattr_init(&dir_attr);
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	nfs_post_op_update_inode(dir, &dir_attr);
 	nfs_post_op_update_inode(inode, &fattr);
 	dprintk("NFS reply link: %d\n", status);
@@ -454,7 +461,7 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 
 static int
 nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
-		  unsigned int len, struct iattr *sattr)
+		  unsigned int len, struct iattr *sattr, struct cred *acred)
 {
 	struct nfs_fh fhandle;
 	struct nfs_fattr fattr, dir_attr;
@@ -485,18 +492,18 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
 
 	nfs_fattr_init(&dir_attr);
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_post_op_update_inode(dir, &dir_attr);
 	if (status != 0)
 		goto out;
-	status = nfs_instantiate(dentry, &fhandle, &fattr);
+	status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 out:
 	dprintk("NFS reply symlink: %d\n", status);
 	return status;
 }
 
 static int
-nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
+nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr, struct cred *acred)
 {
 	struct nfs_fh fhandle;
 	struct nfs_fattr fattr, dir_attr;
@@ -525,21 +532,21 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
 
 	nfs_fattr_init(&dir_attr);
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_post_op_update_inode(dir, &dir_attr);
 	if (status != 0)
 		goto out;
-	status = nfs_instantiate(dentry, &fhandle, &fattr);
+	status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	if (status != 0)
 		goto out;
-	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
+	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode, acred);
 out:
 	dprintk("NFS reply mkdir: %d\n", status);
 	return status;
 }
 
 static int
-nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
+nfs3_proc_rmdir(struct inode *dir, struct qstr *name, struct cred *acred)
 {
 	struct nfs_fattr	dir_attr;
 	struct nfs3_diropargs	arg = {
@@ -556,7 +563,7 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
 
 	dprintk("NFS call  rmdir %s\n", name->name);
 	nfs_fattr_init(&dir_attr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_post_op_update_inode(dir, &dir_attr);
 	dprintk("NFS reply rmdir: %d\n", status);
 	return status;
@@ -573,7 +580,8 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
  */
 static int
 nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
-		  u64 cookie, struct page *page, unsigned int count, int plus)
+		  u64 cookie, struct page *page, unsigned int count, int plus,
+		  struct cred *acred)
 {
 	struct inode		*dir = dentry->d_inode;
 	struct nfs_fattr	dir_attr;
@@ -606,7 +614,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 			plus? "plus" : "", (unsigned int) cookie);
 
 	nfs_fattr_init(&dir_attr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_refresh_inode(dir, &dir_attr);
 	dprintk("NFS reply readdir: %d\n", status);
 	return status;
@@ -614,7 +622,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 
 static int
 nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-		dev_t rdev)
+		dev_t rdev, struct cred *acred)
 {
 	struct nfs_fh fh;
 	struct nfs_fattr fattr, dir_attr;
@@ -653,14 +661,14 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 
 	nfs_fattr_init(&dir_attr);
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_post_op_update_inode(dir, &dir_attr);
 	if (status != 0)
 		goto out;
-	status = nfs_instantiate(dentry, &fh, &fattr);
+	status = nfs_instantiate(dentry, &fh, &fattr, acred);
 	if (status != 0)
 		goto out;
-	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
+	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode, acred);
 out:
 	dprintk("NFS reply mknod: %d\n", status);
 	return status;
@@ -668,7 +676,7 @@ out:
 
 static int
 nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
-		 struct nfs_fsstat *stat)
+		 struct nfs_fsstat *stat, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_FSSTAT],
@@ -679,14 +687,14 @@ nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  fsstat\n");
 	nfs_fattr_init(stat->fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply statfs: %d\n", status);
 	return status;
 }
 
 static int
 nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
-		 struct nfs_fsinfo *info)
+		 struct nfs_fsinfo *info, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_FSINFO],
@@ -697,14 +705,15 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  fsinfo\n");
 	nfs_fattr_init(info->fattr);
-	status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
+	status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0,
+			       acred);
 	dprintk("NFS reply fsinfo: %d\n", status);
 	return status;
 }
 
 static int
 nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
-		   struct nfs_pathconf *info)
+		   struct nfs_pathconf *info, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_PATHCONF],
@@ -715,7 +724,7 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  pathconf\n");
 	nfs_fattr_init(info->fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply pathconf: %d\n", status);
 	return status;
 }
@@ -730,7 +739,7 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
 	return 0;
 }
 
-static void nfs3_proc_read_setup(struct nfs_read_data *data)
+static void nfs3_proc_read_setup(struct nfs_read_data *data, struct cred *acred)
 {
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_READ],
@@ -739,7 +748,7 @@ static void nfs3_proc_read_setup(struct nfs_read_data *data)
 		.rpc_cred	= data->cred,
 	};
 
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -751,7 +760,8 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
 	return 0;
 }
 
-static void nfs3_proc_write_setup(struct nfs_write_data *data, int how)
+static void nfs3_proc_write_setup(struct nfs_write_data *data, int how,
+				  struct cred *acred)
 {
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_WRITE],
@@ -768,7 +778,7 @@ static void nfs3_proc_write_setup(struct nfs_write_data *data, int how)
 	}
 
 	/* Finalize the task. */
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -780,7 +790,8 @@ static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
 	return 0;
 }
 
-static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
+static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how,
+				   struct cred *acred)
 {
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_COMMIT],
@@ -789,13 +800,14 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
 		.rpc_cred	= data->cred,
 	};
 
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static int
 nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
 {
-	return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl);
+	return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl,
+			    filp->f_cred);
 }
 
 const struct nfs_rpc_ops nfs_v3_clientops = {
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index d2802b1..007329e 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -174,16 +174,25 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
 
 /* nfs4proc.c */
 extern int nfs4_map_errors(int err);
-extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
-extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
-extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
-extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
+extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short,
+				 struct rpc_cred *, struct cred *);
+extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *,
+					 struct cred *);
+extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *,
+				 struct cred *);
+extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *,
+			   struct cred *);
+extern int nfs4_do_close(struct path *path, struct nfs4_state *state,
+			 struct cred *acred);
+extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *,
+				       struct nameidata *, struct cred *);
+extern int nfs4_open_revalidate(struct inode *, struct dentry *, int,
+				struct nameidata *, struct cred *);
+extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle,
+				    struct cred *acred);
 extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
-		struct nfs4_fs_locations *fs_locations, struct page *page);
+		struct nfs4_fs_locations *fs_locations, struct page *page,
+		struct cred *acred);
 
 extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
 extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
@@ -208,7 +217,8 @@ extern void nfs4_put_state_owner(struct nfs4_state_owner *);
 extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
 extern void nfs4_put_open_state(struct nfs4_state *);
-extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
+extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t,
+			     struct cred *);
 extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
 extern void nfs4_schedule_state_recovery(struct nfs_client *);
 extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index dd5fef2..1d2f2f2 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -212,9 +212,11 @@ out:
  * nfs_do_refmount - handle crossing a referral on server
  * @dentry - dentry of referral
  * @nd - nameidata info
+ * @acred - the credentials to use
  *
  */
-struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
+struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent,
+				 struct dentry *dentry, struct cred *acred)
 {
 	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
 	struct dentry *parent;
@@ -240,7 +242,8 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
 	dprintk("%s: getting locations for %s/%s\n",
 		__FUNCTION__, parent->d_name.name, dentry->d_name.name);
 
-	err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page);
+	err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name,
+				     fs_locations, page, acred);
 	dput(parent);
 	if (err != 0 ||
 	    fs_locations->nlocations <= 0 ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 943095d..83c9b66 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -59,15 +59,22 @@
 #define NFS4_POLL_RETRY_MAX	(15*HZ)
 
 struct nfs4_opendata;
-static int _nfs4_proc_open(struct nfs4_opendata *data);
-static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
+static int _nfs4_proc_open(struct nfs4_opendata *data, struct cred *acred);
+static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *,
+			  struct nfs_fsinfo *, struct cred *);
 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
-static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
+static int _nfs4_proc_access(struct inode *inode,
+			     struct nfs_access_entry *entry,
+			     struct cred *acred);
 static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
 static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
-static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags);
-static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
-static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
+static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred,
+			   int openflags, struct cred *acred);
+static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name,
+			     struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+			     struct cred *acred);
+static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+			      struct nfs_fattr *fattr, struct cred *acred);
 
 /* Prevent leaks of NFSv4 errors into userland */
 int nfs4_map_errors(int err)
@@ -424,7 +431,8 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, mode_t open
 	nfs_inode_return_delegation(inode);
 }
 
-static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
+static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata,
+					       struct cred *acred)
 {
 	struct nfs4_state *state = opendata->state;
 	struct nfs_inode *nfsi = NFS_I(state->inode);
@@ -454,7 +462,8 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
 		memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data));
 		rcu_read_unlock();
 		lock_kernel();
-		ret = _nfs4_do_access(state->inode, state->owner->so_cred, open_mode);
+		ret = _nfs4_do_access(state->inode, state->owner->so_cred,
+				      open_mode, acred);
 		unlock_kernel();
 		if (ret != 0)
 			goto out;
@@ -479,7 +488,8 @@ out_return_state:
 	return state;
 }
 
-static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
+static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data,
+						      struct cred *acred)
 {
 	struct inode *inode;
 	struct nfs4_state *state = NULL;
@@ -488,7 +498,7 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
 	int ret;
 
 	if (!data->rpc_done) {
-		state = nfs4_try_open_cached(data);
+		state = nfs4_try_open_cached(data, acred);
 		goto out;
 	}
 
@@ -514,11 +524,11 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
 		if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM))
 			nfs_inode_set_delegation(state->inode,
 					data->owner->so_cred,
-					&data->o_res);
+					&data->o_res, acred);
 		else
 			nfs_inode_reclaim_delegation(state->inode,
 					data->owner->so_cred,
-					&data->o_res);
+					&data->o_res, acred);
 	}
 	rcu_read_lock();
 	delegation = rcu_dereference(NFS_I(inode)->delegation);
@@ -564,7 +574,9 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
 	return opendata;
 }
 
-static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res)
+static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
+				    mode_t openflags, struct nfs4_state **res,
+				    struct cred *acred)
 {
 	struct nfs4_state *newstate;
 	int ret;
@@ -573,18 +585,19 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openf
 	memset(&opendata->o_res, 0, sizeof(opendata->o_res));
 	memset(&opendata->c_res, 0, sizeof(opendata->c_res));
 	nfs4_init_opendata_res(opendata);
-	ret = _nfs4_proc_open(opendata);
+	ret = _nfs4_proc_open(opendata, acred);
 	if (ret != 0)
 		return ret; 
-	newstate = nfs4_opendata_to_nfs4_state(opendata);
+	newstate = nfs4_opendata_to_nfs4_state(opendata, acred);
 	if (IS_ERR(newstate))
 		return PTR_ERR(newstate);
-	nfs4_close_state(&opendata->path, newstate, openflags);
+	nfs4_close_state(&opendata->path, newstate, openflags, acred);
 	*res = newstate;
 	return 0;
 }
 
-static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *state)
+static int nfs4_open_recover(struct nfs4_opendata *opendata,
+			     struct nfs4_state *state, struct cred *acred)
 {
 	struct nfs4_state *newstate;
 	int ret;
@@ -593,21 +606,24 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
 	clear_bit(NFS_DELEGATED_STATE, &state->flags);
 	smp_rmb();
 	if (state->n_rdwr != 0) {
-		ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate);
+		ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE,
+					       &newstate, acred);
 		if (ret != 0)
 			return ret;
 		if (newstate != state)
 			return -ESTALE;
 	}
 	if (state->n_wronly != 0) {
-		ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate);
+		ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate,
+					       acred);
 		if (ret != 0)
 			return ret;
 		if (newstate != state)
 			return -ESTALE;
 	}
 	if (state->n_rdonly != 0) {
-		ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate);
+		ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate,
+					       acred);
 		if (ret != 0)
 			return ret;
 		if (newstate != state)
@@ -631,7 +647,8 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
  * OPEN_RECLAIM:
  * 	reclaim state on the server after a reboot.
  */
-static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
+static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx,
+				 struct nfs4_state *state, struct cred *acred)
 {
 	struct nfs_delegation *delegation;
 	struct nfs4_opendata *opendata;
@@ -649,18 +666,19 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
 		delegation_type = delegation->type;
 	rcu_read_unlock();
 	opendata->o_arg.u.delegation_type = delegation_type;
-	status = nfs4_open_recover(opendata, state);
+	status = nfs4_open_recover(opendata, state, acred);
 	nfs4_opendata_put(opendata);
 	return status;
 }
 
-static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
+static int nfs4_do_open_reclaim(struct nfs_open_context *ctx,
+				struct nfs4_state *state, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	struct nfs4_exception exception = { };
 	int err;
 	do {
-		err = _nfs4_do_open_reclaim(ctx, state);
+		err = _nfs4_do_open_reclaim(ctx, state, acred);
 		if (err != -NFS4ERR_DELAY)
 			break;
 		nfs4_handle_exception(server, err, &exception);
@@ -668,7 +686,8 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
 	return err;
 }
 
-static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
+static int nfs4_open_reclaim(struct nfs4_state_owner *sp,
+			     struct nfs4_state *state)
 {
 	struct nfs_open_context *ctx;
 	int ret;
@@ -676,7 +695,7 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
 	ctx = nfs4_state_find_open_context(state);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
-	ret = nfs4_do_open_reclaim(ctx, state);
+	ret = nfs4_do_open_reclaim(ctx, state, ctx->acred);
 	put_nfs_open_context(ctx);
 	return ret;
 }
@@ -692,7 +711,7 @@ static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs
 	opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR;
 	memcpy(opendata->o_arg.u.delegation.data, stateid->data,
 			sizeof(opendata->o_arg.u.delegation.data));
-	ret = nfs4_open_recover(opendata, state);
+	ret = nfs4_open_recover(opendata, state, ctx->acred);
 	nfs4_opendata_put(opendata);
 	return ret;
 }
@@ -749,7 +768,7 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
 	nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
 }
 
-static void nfs4_open_confirm_release(void *calldata)
+static void nfs4_open_confirm_release(struct cred *acred, void *calldata)
 {
 	struct nfs4_opendata *data = calldata;
 	struct nfs4_state *state = NULL;
@@ -761,9 +780,10 @@ static void nfs4_open_confirm_release(void *calldata)
 	if (!data->rpc_done)
 		goto out_free;
 	nfs_confirm_seqid(&data->owner->so_seqid, 0);
-	state = nfs4_opendata_to_nfs4_state(data);
+	state = nfs4_opendata_to_nfs4_state(data, acred);
 	if (!IS_ERR(state))
-		nfs4_close_state(&data->path, state, data->o_arg.open_flags);
+		nfs4_close_state(&data->path, state, data->o_arg.open_flags,
+				 acred);
 out_free:
 	nfs4_opendata_put(data);
 }
@@ -777,7 +797,8 @@ static const struct rpc_call_ops nfs4_open_confirm_ops = {
 /*
  * Note: On error, nfs4_proc_open_confirm will free the struct nfs4_opendata
  */
-static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
+static int _nfs4_proc_open_confirm(struct nfs4_opendata *data,
+				   struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(data->dir->d_inode);
 	struct rpc_task *task;
@@ -786,7 +807,8 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
 	kref_get(&data->kref);
 	data->rpc_done = 0;
 	data->rpc_status = 0;
-	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_confirm_ops, data);
+	task = rpc_run_task(server->client, RPC_TASK_ASYNC,
+			    &nfs4_open_confirm_ops, data, acred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	status = nfs4_wait_for_completion_rpc_task(task);
@@ -873,7 +895,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
 	data->rpc_done = 1;
 }
 
-static void nfs4_open_release(void *calldata)
+static void nfs4_open_release(struct cred *acred, void *calldata)
 {
 	struct nfs4_opendata *data = calldata;
 	struct nfs4_state *state = NULL;
@@ -888,9 +910,10 @@ static void nfs4_open_release(void *calldata)
 	if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
 		goto out_free;
 	nfs_confirm_seqid(&data->owner->so_seqid, 0);
-	state = nfs4_opendata_to_nfs4_state(data);
+	state = nfs4_opendata_to_nfs4_state(data, acred);
 	if (!IS_ERR(state))
-		nfs4_close_state(&data->path, state, data->o_arg.open_flags);
+		nfs4_close_state(&data->path, state, data->o_arg.open_flags,
+				 acred);
 out_free:
 	nfs4_opendata_put(data);
 }
@@ -904,7 +927,7 @@ static const struct rpc_call_ops nfs4_open_ops = {
 /*
  * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
  */
-static int _nfs4_proc_open(struct nfs4_opendata *data)
+static int _nfs4_proc_open(struct nfs4_opendata *data, struct cred *acred)
 {
 	struct inode *dir = data->dir->d_inode;
 	struct nfs_server *server = NFS_SERVER(dir);
@@ -917,7 +940,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
 	data->rpc_done = 0;
 	data->rpc_status = 0;
 	data->cancelled = 0;
-	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_ops, data);
+	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_ops,
+			    data, acred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	status = nfs4_wait_for_completion_rpc_task(task);
@@ -931,7 +955,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
 		return status;
 
 	if (o_res->fh.size == 0)
-		_nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr);
+		_nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr,
+				  acred);
 
 	if (o_arg->open_flags & O_CREAT) {
 		update_changeattr(dir, &o_res->cinfo);
@@ -939,16 +964,17 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
 	} else
 		nfs_refresh_inode(dir, o_res->dir_attr);
 	if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
-		status = _nfs4_proc_open_confirm(data);
+		status = _nfs4_proc_open_confirm(data, acred);
 		if (status != 0)
 			return status;
 	}
 	if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
-		_nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr);
+		_nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, acred);
 	return 0;
 }
 
-static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags)
+static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred,
+			   int openflags, struct cred *acred)
 {
 	struct nfs_access_entry cache;
 	int mask = 0;
@@ -968,7 +994,7 @@ static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openf
 	cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
 	cache.cred = cred;
 	cache.jiffies = jiffies;
-	status = _nfs4_proc_access(inode, &cache);
+	status = _nfs4_proc_access(inode, &cache, acred);
 	if (status != 0)
 		return status;
 	nfs_access_add_cache(inode, &cache);
@@ -1007,7 +1033,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
 	opendata = nfs4_open_recoverdata_alloc(ctx, state);
 	if (IS_ERR(opendata))
 		return PTR_ERR(opendata);
-	ret = nfs4_open_recover(opendata, state);
+	ret = nfs4_open_recover(opendata, state, ctx->acred);
 	if (ret == -ESTALE) {
 		/* Invalidate the state owner so we don't ever use it again */
 		nfs4_drop_state_owner(state->owner);
@@ -1063,7 +1089,9 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
 /*
  * Returns a referenced nfs4_state
  */
-static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
+static int _nfs4_do_open(struct inode *dir, struct path *path, int flags,
+			 struct iattr *sattr, struct rpc_cred *cred,
+			 struct nfs4_state **res, struct cred *acred)
 {
 	struct nfs4_state_owner  *sp;
 	struct nfs4_state     *state = NULL;
@@ -1092,14 +1120,14 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
 	if (path->dentry->d_inode != NULL)
 		opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp);
 
-	status = _nfs4_proc_open(opendata);
+	status = _nfs4_proc_open(opendata, acred);
 	if (status != 0)
 		goto err_opendata_put;
 
 	if (opendata->o_arg.open_flags & O_EXCL)
 		nfs4_exclusive_attrset(opendata, sattr);
 
-	state = nfs4_opendata_to_nfs4_state(opendata);
+	state = nfs4_opendata_to_nfs4_state(opendata, acred);
 	status = PTR_ERR(state);
 	if (IS_ERR(state))
 		goto err_opendata_put;
@@ -1120,14 +1148,18 @@ out_err:
 }
 
 
-static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
+static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path,
+				       int flags, struct iattr *sattr,
+				       struct rpc_cred *cred,
+				       struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	struct nfs4_state *res;
 	int status;
 
 	do {
-		status = _nfs4_do_open(dir, path, flags, sattr, cred, &res);
+		status = _nfs4_do_open(dir, path, flags, sattr, cred, &res,
+				       acred);
 		if (status == 0)
 			break;
 		/* NOTE: BAD_SEQID means the server and client disagree about the
@@ -1170,7 +1202,8 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int
 }
 
 static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr,
-                struct iattr *sattr, struct nfs4_state *state)
+                struct iattr *sattr, struct nfs4_state *state,
+		struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
         struct nfs_setattrargs  arg = {
@@ -1201,21 +1234,23 @@ static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr,
 	} else
 		memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
 
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	if (status == 0 && state != NULL)
 		renew_lease(server, timestamp);
 	return status;
 }
 
 static int nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr,
-                struct iattr *sattr, struct nfs4_state *state)
+                struct iattr *sattr, struct nfs4_state *state,
+		struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_do_setattr(inode, fattr, sattr, state),
+				_nfs4_do_setattr(inode, fattr, sattr, state,
+						 acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -1231,7 +1266,7 @@ struct nfs4_closedata {
 	unsigned long timestamp;
 };
 
-static void nfs4_free_closedata(void *data)
+static void nfs4_free_closedata(struct cred *acred, void *data)
 {
 	struct nfs4_closedata *calldata = data;
 	struct nfs4_state_owner *sp = calldata->state->owner;
@@ -1336,7 +1371,8 @@ static const struct rpc_call_ops nfs4_close_ops = {
  *
  * NOTE: Caller must be holding the sp->so_owner semaphore!
  */
-int nfs4_do_close(struct path *path, struct nfs4_state *state)
+int nfs4_do_close(struct path *path, struct nfs4_state *state,
+		  struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	struct nfs4_closedata *calldata;
@@ -1361,7 +1397,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state)
 	calldata->path.mnt = mntget(path->mnt);
 	calldata->path.dentry = dget(path->dentry);
 
-	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
+	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops,
+			    calldata, acred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	rpc_put_task(task);
@@ -1374,7 +1411,8 @@ out:
 	return status;
 }
 
-static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state)
+static int nfs4_intent_set_file(struct nameidata *nd, struct path *path,
+				struct nfs4_state *state, struct cred *acred)
 {
 	struct file *filp;
 	int ret;
@@ -1383,7 +1421,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
 	if (nd->intent.open.flags & FMODE_EXEC) {
 		ret = _nfs4_do_access(state->inode,
 				state->owner->so_cred,
-				nd->intent.open.flags);
+				      nd->intent.open.flags, acred);
 		if (ret < 0)
 			goto out_close;
 	}
@@ -1396,14 +1434,14 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
 	}
 	ret = PTR_ERR(filp);
 out_close:
-	nfs4_close_state(path, state, nd->intent.open.flags);
+	nfs4_close_state(path, state, nd->intent.open.flags, acred);
 	return ret;
 }
 
 struct dentry *
-nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd,
+		 struct cred *acred)
 {
-	struct cred *acred = current->cred;
 	struct path path = {
 		.mnt = nd->mnt,
 		.dentry = dentry,
@@ -1426,7 +1464,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 	cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0, acred);
 	if (IS_ERR(cred))
 		return (struct dentry *)cred;
-	state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
+	state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred,
+			     acred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
 		if (PTR_ERR(state) == -ENOENT)
@@ -1436,14 +1475,14 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 	res = d_add_unique(dentry, igrab(state->inode));
 	if (res != NULL)
 		path.dentry = res;
-	nfs4_intent_set_file(nd, &path, state);
+	nfs4_intent_set_file(nd, &path, state, acred);
 	return res;
 }
 
 int
-nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
+nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags,
+		     struct nameidata *nd, struct cred *acred)
 {
-	struct cred *acred = current->cred;
 	struct path path = {
 		.mnt = nd->mnt,
 		.dentry = dentry,
@@ -1454,7 +1493,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
 	cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0, acred);
 	if (IS_ERR(cred))
 		return PTR_ERR(cred);
-	state = nfs4_do_open(dir, &path, openflags, NULL, cred);
+	state = nfs4_do_open(dir, &path, openflags, NULL, cred, acred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
 		switch (PTR_ERR(state)) {
@@ -1470,17 +1509,18 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
 		}
 	}
 	if (state->inode == dentry->d_inode) {
-		nfs4_intent_set_file(nd, &path, state);
+		nfs4_intent_set_file(nd, &path, state, acred);
 		return 1;
 	}
-	nfs4_close_state(&path, state, openflags);
+	nfs4_close_state(&path, state, openflags, acred);
 out_drop:
 	d_drop(dentry);
 	return 0;
 }
 
 
-static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
+static int _nfs4_server_capabilities(struct nfs_server *server,
+				     struct nfs_fh *fhandle, struct cred *acred)
 {
 	struct nfs4_server_caps_res res = {};
 	struct rpc_message msg = {
@@ -1490,7 +1530,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 	};
 	int status;
 
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	if (status == 0) {
 		memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
 		if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
@@ -1504,20 +1544,22 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 	return status;
 }
 
-int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
+int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle,
+			     struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_server_capabilities(server, fhandle),
+				_nfs4_server_capabilities(server, fhandle,
+							  acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_fsinfo *info)
+		struct nfs_fsinfo *info, struct cred *acred)
 {
 	struct nfs4_lookup_root_arg args = {
 		.bitmask = nfs4_fattr_bitmap,
@@ -1533,17 +1575,17 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
 		.rpc_resp = &res,
 	};
 	nfs_fattr_init(info->fattr);
-	return rpc_call_sync(server->client, &msg, 0);
+	return rpc_call_sync(server->client, &msg, 0, acred);
 }
 
 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_fsinfo *info)
+		struct nfs_fsinfo *info, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_lookup_root(server, fhandle, info),
+				_nfs4_lookup_root(server, fhandle, info, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -1553,15 +1595,15 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
  * get the file handle for the "/" directory on the server
  */
 static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
-			      struct nfs_fsinfo *info)
+			      struct nfs_fsinfo *info, struct cred *acred)
 {
 	int status;
 
-	status = nfs4_lookup_root(server, fhandle, info);
+	status = nfs4_lookup_root(server, fhandle, info, acred);
 	if (status == 0)
-		status = nfs4_server_capabilities(server, fhandle);
+		status = nfs4_server_capabilities(server, fhandle, acred);
 	if (status == 0)
-		status = nfs4_do_fsinfo(server, fhandle, info);
+		status = nfs4_do_fsinfo(server, fhandle, info, acred);
 	return nfs4_map_errors(status);
 }
 
@@ -1570,7 +1612,9 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  * Note that we'll actually follow the referral later when
  * we detect fsid mismatch in inode revalidation
  */
-static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle)
+static int nfs4_get_referral(struct inode *dir, const struct qstr *name,
+			     struct nfs_fattr *fattr, struct nfs_fh *fhandle,
+			     struct cred *acred)
 {
 	int status = -ENOMEM;
 	struct page *page = NULL;
@@ -1583,7 +1627,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct
 	if (locations == NULL)
 		goto out;
 
-	status = nfs4_proc_fs_locations(dir, name, locations, page);
+	status = nfs4_proc_fs_locations(dir, name, locations, page, acred);
 	if (status != 0)
 		goto out;
 	/* Make sure server returned a different fsid for the referral */
@@ -1606,7 +1650,8 @@ out:
 	return status;
 }
 
-static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+			      struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct nfs4_getattr_arg args = {
 		.fh = fhandle,
@@ -1623,16 +1668,18 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
 	};
 	
 	nfs_fattr_init(fattr);
-	return rpc_call_sync(server->client, &msg, 0);
+	return rpc_call_sync(server->client, &msg, 0, acred);
 }
 
-static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+			     struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_proc_getattr(server, fhandle, fattr),
+				_nfs4_proc_getattr(server, fhandle, fattr,
+						   acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -1657,9 +1704,8 @@ static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
  */
 static int
 nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
-		  struct iattr *sattr)
+		  struct iattr *sattr, struct cred *acred)
 {
-	struct cred *acred = current->cred;
 	struct rpc_cred *cred;
 	struct inode *inode = dentry->d_inode;
 	struct nfs_open_context *ctx;
@@ -1677,7 +1723,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 	if (ctx != NULL)
 		state = ctx->state;
 
-	status = nfs4_do_setattr(inode, fattr, sattr, state);
+	status = nfs4_do_setattr(inode, fattr, sattr, state, acred);
 	if (status == 0)
 		nfs_setattr_update_inode(inode, sattr);
 	if (ctx != NULL)
@@ -1688,7 +1734,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *dirfh,
 		const struct qstr *name, struct nfs_fh *fhandle,
-		struct nfs_fattr *fattr)
+		struct nfs_fattr *fattr, struct cred *acred)
 {
 	int		       status;
 	struct nfs4_lookup_arg args = {
@@ -1710,19 +1756,20 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d
 	nfs_fattr_init(fattr);
 
 	dprintk("NFS call  lookupfh %s\n", name->name);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply lookupfh: %d\n", status);
 	return status;
 }
 
 static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
 			      struct qstr *name, struct nfs_fh *fhandle,
-			      struct nfs_fattr *fattr)
+			      struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
-		err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
+		err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr,
+					  acred);
 		/* FIXME: !!!! */
 		if (err == -NFS4ERR_MOVED) {
 			err = -EREMOTE;
@@ -1734,31 +1781,37 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
 }
 
 static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name,
-		struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+		struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+		struct cred *acred)
 {
 	int status;
 	
 	dprintk("NFS call  lookup %s\n", name->name);
-	status = _nfs4_proc_lookupfh(NFS_SERVER(dir), NFS_FH(dir), name, fhandle, fattr);
+	status = _nfs4_proc_lookupfh(NFS_SERVER(dir), NFS_FH(dir), name,
+				     fhandle, fattr, acred);
 	if (status == -NFS4ERR_MOVED)
-		status = nfs4_get_referral(dir, name, fattr, fhandle);
+		status = nfs4_get_referral(dir, name, fattr, fhandle, acred);
 	dprintk("NFS reply lookup: %d\n", status);
 	return status;
 }
 
-static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+static int nfs4_proc_lookup(struct inode *dir, struct qstr *name,
+			    struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+			    struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(dir),
-				_nfs4_proc_lookup(dir, name, fhandle, fattr),
+				_nfs4_proc_lookup(dir, name, fhandle, fattr,
+						  acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
-static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
+static int _nfs4_proc_access(struct inode *inode,
+			     struct nfs_access_entry *entry, struct cred *acred)
 {
 	struct nfs4_accessargs args = {
 		.fh = NFS_FH(inode),
@@ -1789,7 +1842,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
 		if (mode & MAY_EXEC)
 			args.access |= NFS4_ACCESS_EXECUTE;
 	}
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	if (!status) {
 		entry->mask = 0;
 		if (res.access & NFS4_ACCESS_READ)
@@ -1802,13 +1855,14 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
 	return status;
 }
 
-static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
+static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry,
+			    struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(inode),
-				_nfs4_proc_access(inode, entry),
+				_nfs4_proc_access(inode, entry, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -1839,7 +1893,7 @@ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
  * minor, but I decided to leave them for a subsequent patch.
  */
 static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
-		unsigned int pgbase, unsigned int pglen)
+		unsigned int pgbase, unsigned int pglen, struct cred *acred)
 {
 	struct nfs4_readlink args = {
 		.fh       = NFS_FH(inode),
@@ -1853,17 +1907,17 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
 		.rpc_resp = NULL,
 	};
 
-	return rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	return rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 }
 
 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
-		unsigned int pgbase, unsigned int pglen)
+		unsigned int pgbase, unsigned int pglen, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(inode),
-				_nfs4_proc_readlink(inode, page, pgbase, pglen),
+				_nfs4_proc_readlink(inode, page, pgbase, pglen, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -1886,9 +1940,8 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
 
 static int
 nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-                 int flags, struct nameidata *nd)
+                 int flags, struct nameidata *nd, struct cred *acred)
 {
-	struct cred *acred = current->cred;
 	struct path path = {
 		.mnt = nd->mnt,
 		.dentry = dentry,
@@ -1902,7 +1955,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 		status = PTR_ERR(cred);
 		goto out;
 	}
-	state = nfs4_do_open(dir, &path, flags, sattr, cred);
+	state = nfs4_do_open(dir, &path, flags, sattr, cred, acred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
 		status = PTR_ERR(state);
@@ -1911,20 +1964,22 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 	d_instantiate(dentry, igrab(state->inode));
 	if (flags & O_EXCL) {
 		struct nfs_fattr fattr;
-		status = nfs4_do_setattr(state->inode, &fattr, sattr, state);
+		status = nfs4_do_setattr(state->inode, &fattr, sattr, state,
+					 acred);
 		if (status == 0)
 			nfs_setattr_update_inode(state->inode, sattr);
 		nfs_post_op_update_inode(state->inode, &fattr);
 	}
 	if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
-		status = nfs4_intent_set_file(nd, &path, state);
+		status = nfs4_intent_set_file(nd, &path, state, acred);
 	else
-		nfs4_close_state(&path, state, flags);
+		nfs4_close_state(&path, state, flags, acred);
 out:
 	return status;
 }
 
-static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
+static int _nfs4_proc_remove(struct inode *dir, struct qstr *name,
+			     struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(dir);
 	struct nfs_removeargs args = {
@@ -1944,7 +1999,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
 	int			status;
 
 	nfs_fattr_init(&res.dir_attr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	if (status == 0) {
 		update_changeattr(dir, &res.cinfo);
 		nfs_post_op_update_inode(dir, &res.dir_attr);
@@ -1952,13 +2007,14 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
 	return status;
 }
 
-static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
+static int nfs4_proc_remove(struct inode *dir, struct qstr *name,
+			    struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(dir),
-				_nfs4_proc_remove(dir, name),
+				_nfs4_proc_remove(dir, name, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -1987,7 +2043,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
 }
 
 static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
-		struct inode *new_dir, struct qstr *new_name)
+		struct inode *new_dir, struct qstr *new_name,
+		struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(old_dir);
 	struct nfs4_rename_arg arg = {
@@ -2012,7 +2069,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
 	
 	nfs_fattr_init(res.old_fattr);
 	nfs_fattr_init(res.new_fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 
 	if (!status) {
 		update_changeattr(old_dir, &res.old_cinfo);
@@ -2024,20 +2081,22 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
 }
 
 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
-		struct inode *new_dir, struct qstr *new_name)
+		struct inode *new_dir, struct qstr *new_name,
+		struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(old_dir),
 				_nfs4_proc_rename(old_dir, old_name,
-					new_dir, new_name),
+					new_dir, new_name, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
-static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
+static int _nfs4_proc_link(struct inode *inode, struct inode *dir,
+			   struct qstr *name, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs4_link_arg arg = {
@@ -2061,7 +2120,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
 
 	nfs_fattr_init(res.fattr);
 	nfs_fattr_init(res.dir_attr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	if (!status) {
 		update_changeattr(dir, &res.cinfo);
 		nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2071,20 +2130,22 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
 	return status;
 }
 
-static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
+static int nfs4_proc_link(struct inode *inode, struct inode *dir,
+			  struct qstr *name, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(inode),
-				_nfs4_proc_link(inode, dir, name),
+				_nfs4_proc_link(inode, dir, name, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
-		struct page *page, unsigned int len, struct iattr *sattr)
+		struct page *page, unsigned int len, struct iattr *sattr,
+		struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(dir);
 	struct nfs_fh fhandle;
@@ -2118,31 +2179,32 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
 	nfs_fattr_init(&fattr);
 	nfs_fattr_init(&dir_fattr);
 	
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	if (!status) {
 		update_changeattr(dir, &res.dir_cinfo);
 		nfs_post_op_update_inode(dir, res.dir_fattr);
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	}
 	return status;
 }
 
 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
-		struct page *page, unsigned int len, struct iattr *sattr)
+		struct page *page, unsigned int len, struct iattr *sattr,
+		struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(dir),
 				_nfs4_proc_symlink(dir, dentry, page,
-							len, sattr),
+							len, sattr, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
-		struct iattr *sattr)
+		struct iattr *sattr, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(dir);
 	struct nfs_fh fhandle;
@@ -2171,30 +2233,31 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
 	nfs_fattr_init(&fattr);
 	nfs_fattr_init(&dir_fattr);
 	
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	if (!status) {
 		update_changeattr(dir, &res.dir_cinfo);
 		nfs_post_op_update_inode(dir, res.dir_fattr);
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	}
 	return status;
 }
 
 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
-		struct iattr *sattr)
+		struct iattr *sattr, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(dir),
-				_nfs4_proc_mkdir(dir, dentry, sattr),
+				_nfs4_proc_mkdir(dir, dentry, sattr, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
-                  u64 cookie, struct page *page, unsigned int count, int plus)
+                  u64 cookie, struct page *page, unsigned int count, int plus,
+		  struct cred *acred)
 {
 	struct inode		*dir = dentry->d_inode;
 	struct nfs4_readdir_arg args = {
@@ -2219,7 +2282,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 			(unsigned long long)cookie);
 	nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
 	res.pgbase = args.pgbase;
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	if (status == 0)
 		memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
 	dprintk("%s: returns %d\n", __FUNCTION__, status);
@@ -2227,21 +2290,22 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 }
 
 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
-                  u64 cookie, struct page *page, unsigned int count, int plus)
+                  u64 cookie, struct page *page, unsigned int count, int plus,
+		  struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
 				_nfs4_proc_readdir(dentry, cred, cookie,
-					page, count, plus),
+					page, count, plus, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
-		struct iattr *sattr, dev_t rdev)
+		struct iattr *sattr, dev_t rdev, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(dir);
 	struct nfs_fh fh;
@@ -2287,30 +2351,31 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
 	else
 		arg.ftype = NF4SOCK;
 	
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	if (status == 0) {
 		update_changeattr(dir, &res.dir_cinfo);
 		nfs_post_op_update_inode(dir, res.dir_fattr);
-		status = nfs_instantiate(dentry, &fh, &fattr);
+		status = nfs_instantiate(dentry, &fh, &fattr, acred);
 	}
 	return status;
 }
 
 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
-		struct iattr *sattr, dev_t rdev)
+		struct iattr *sattr, dev_t rdev, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(dir),
-				_nfs4_proc_mknod(dir, dentry, sattr, rdev),
+				_nfs4_proc_mknod(dir, dentry, sattr, rdev,
+						 acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
-		 struct nfs_fsstat *fsstat)
+		 struct nfs_fsstat *fsstat, struct cred *acred)
 {
 	struct nfs4_statfs_arg args = {
 		.fh = fhandle,
@@ -2323,23 +2388,25 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
 	};
 
 	nfs_fattr_init(fsstat->fattr);
-	return rpc_call_sync(server->client, &msg, 0);
+	return rpc_call_sync(server->client, &msg, 0, acred);
 }
 
-static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
+static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
+			    struct nfs_fsstat *fsstat, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_proc_statfs(server, fhandle, fsstat),
+				_nfs4_proc_statfs(server, fhandle, fsstat,
+						  acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
 static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_fsinfo *fsinfo)
+		struct nfs_fsinfo *fsinfo, struct cred *acred)
 {
 	struct nfs4_fsinfo_arg args = {
 		.fh = fhandle,
@@ -2351,30 +2418,32 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
 		.rpc_resp = fsinfo,
 	};
 
-	return rpc_call_sync(server->client, &msg, 0);
+	return rpc_call_sync(server->client, &msg, 0, acred);
 }
 
-static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
+static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
+			  struct nfs_fsinfo *fsinfo, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_do_fsinfo(server, fhandle, fsinfo),
+				_nfs4_do_fsinfo(server, fhandle, fsinfo, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
-static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
+static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
+			    struct nfs_fsinfo *fsinfo, struct cred *acred)
 {
 	nfs_fattr_init(fsinfo->fattr);
-	return nfs4_do_fsinfo(server, fhandle, fsinfo);
+	return nfs4_do_fsinfo(server, fhandle, fsinfo, acred);
 }
 
 static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_pathconf *pathconf)
+		struct nfs_pathconf *pathconf, struct cred *acred)
 {
 	struct nfs4_pathconf_arg args = {
 		.fh = fhandle,
@@ -2393,18 +2462,19 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
 	}
 
 	nfs_fattr_init(pathconf->fattr);
-	return rpc_call_sync(server->client, &msg, 0);
+	return rpc_call_sync(server->client, &msg, 0, acred);
 }
 
 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_pathconf *pathconf)
+		struct nfs_pathconf *pathconf, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_proc_pathconf(server, fhandle, pathconf),
+				_nfs4_proc_pathconf(server, fhandle, pathconf,
+						    acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -2423,7 +2493,7 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
 	return 0;
 }
 
-static void nfs4_proc_read_setup(struct nfs_read_data *data)
+static void nfs4_proc_read_setup(struct nfs_read_data *data, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
@@ -2434,7 +2504,7 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data)
 
 	data->timestamp   = jiffies;
 
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -2452,7 +2522,8 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
 	return 0;
 }
 
-static void nfs4_proc_write_setup(struct nfs_write_data *data, int how)
+static void nfs4_proc_write_setup(struct nfs_write_data *data, int how,
+				  struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
@@ -2478,7 +2549,7 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, int how)
 	data->timestamp   = jiffies;
 
 	/* Finalize the task. */
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -2494,7 +2565,8 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
 	return 0;
 }
 
-static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
+static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how,
+				   struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
@@ -2507,7 +2579,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
 	data->args.bitmask = server->attr_bitmask;
 	data->res.server = server;
 
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 /*
@@ -2538,7 +2610,8 @@ static const struct rpc_call_ops nfs4_renew_ops = {
 	.rpc_call_done = nfs4_renew_done,
 };
 
-int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred,
+			  struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2547,10 +2620,11 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
 	};
 
 	return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
-			&nfs4_renew_ops, (void *)jiffies);
+			&nfs4_renew_ops, (void *)jiffies, acred);
 }
 
-int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred,
+		    struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2560,7 +2634,7 @@ int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
 	unsigned long now = jiffies;
 	int status;
 
-	status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+	status = rpc_call_sync(clp->cl_rpcclient, &msg, 0, acred);
 	if (status < 0)
 		return status;
 	spin_lock(&clp->cl_lock);
@@ -2663,7 +2737,8 @@ out:
 	nfs4_set_cached_acl(inode, acl);
 }
 
-static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf,
+				       size_t buflen, struct cred *acred)
 {
 	struct page *pages[NFS4ACL_MAXPAGES];
 	struct nfs_getaclargs args = {
@@ -2695,7 +2770,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
 		resp_buf = buf;
 		buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
 	}
-	ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	if (ret)
 		goto out_free;
 	if (resp_len > args.acl_len)
@@ -2716,12 +2791,13 @@ out_free:
 	return ret;
 }
 
-static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf,
+				     size_t buflen, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	ssize_t ret;
 	do {
-		ret = __nfs4_get_acl_uncached(inode, buf, buflen);
+		ret = __nfs4_get_acl_uncached(inode, buf, buflen, acred);
 		if (ret >= 0)
 			break;
 		ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception);
@@ -2729,23 +2805,25 @@ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bufl
 	return ret;
 }
 
-static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
+static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen,
+				 struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	int ret;
 
 	if (!nfs4_server_supports_acls(server))
 		return -EOPNOTSUPP;
-	ret = nfs_revalidate_inode(server, inode);
+	ret = nfs_revalidate_inode(server, inode, acred);
 	if (ret < 0)
 		return ret;
 	ret = nfs4_read_cached_acl(inode, buf, buflen);
 	if (ret != -ENOENT)
 		return ret;
-	return nfs4_get_acl_uncached(inode, buf, buflen);
+	return nfs4_get_acl_uncached(inode, buf, buflen, acred);
 }
 
-static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
+static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
+			       size_t buflen, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct page *pages[NFS4ACL_MAXPAGES];
@@ -2765,18 +2843,19 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
 		return -EOPNOTSUPP;
 	nfs_inode_return_delegation(inode);
 	buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
-	ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	nfs_zap_caches(inode);
 	return ret;
 }
 
-static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
+static int nfs4_proc_set_acl(struct inode *inode, const void *buf,
+			     size_t buflen, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(inode),
-				__nfs4_proc_set_acl(inode, buf, buflen),
+				__nfs4_proc_set_acl(inode, buf, buflen, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -2897,7 +2976,9 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
 	return nfs4_map_errors(ret);
 }
 
-int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
+int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
+			  unsigned short port, struct rpc_cred *cred,
+			  struct cred *acred)
 {
 	nfs4_verifier sc_verifier;
 	struct nfs4_setclientid setclientid = {
@@ -2930,7 +3011,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
 				sizeof(setclientid.sc_uaddr), "%s.%d.%d",
 				clp->cl_ipaddr, port >> 8, port & 255);
 
-		status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+		status = rpc_call_sync(clp->cl_rpcclient, &msg, 0, acred);
 		if (status != -NFS4ERR_CLID_INUSE)
 			break;
 		if (signalled())
@@ -2944,7 +3025,9 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
 	return status;
 }
 
-static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+					  struct rpc_cred *cred,
+					  struct cred *acred)
 {
 	struct nfs_fsinfo fsinfo;
 	struct rpc_message msg = {
@@ -2957,7 +3040,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
 	int status;
 
 	now = jiffies;
-	status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+	status = rpc_call_sync(clp->cl_rpcclient, &msg, 0, acred);
 	if (status == 0) {
 		spin_lock(&clp->cl_lock);
 		clp->cl_lease_time = fsinfo.lease_time * HZ;
@@ -2968,12 +3051,13 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
 	return status;
 }
 
-int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred,
+				  struct cred *acred)
 {
 	long timeout;
 	int err;
 	do {
-		err = _nfs4_proc_setclientid_confirm(clp, cred);
+		err = _nfs4_proc_setclientid_confirm(clp, cred, acred);
 		switch (err) {
 			case 0:
 				return err;
@@ -3018,7 +3102,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
 		renew_lease(data->res.server, data->timestamp);
 }
 
-static void nfs4_delegreturn_release(void *calldata)
+static void nfs4_delegreturn_release(struct cred *acred, void *calldata)
 {
 	struct nfs4_delegreturndata *data = calldata;
 
@@ -3032,7 +3116,9 @@ static const struct rpc_call_ops nfs4_delegreturn_ops = {
 	.rpc_release = nfs4_delegreturn_release,
 };
 
-static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
+static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred,
+				  const nfs4_stateid *stateid,
+				  struct cred *acred)
 {
 	struct nfs4_delegreturndata *data;
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -3053,7 +3139,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
 	data->timestamp = jiffies;
 	data->rpc_status = 0;
 
-	task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data);
+	task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC,
+			    &nfs4_delegreturn_ops, data, acred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	status = nfs4_wait_for_completion_rpc_task(task);
@@ -3066,13 +3153,14 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
 	return status;
 }
 
-int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
+int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred,
+			  const nfs4_stateid *stateid, struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs4_exception exception = { };
 	int err;
 	do {
-		err = _nfs4_proc_delegreturn(inode, cred, stateid);
+		err = _nfs4_proc_delegreturn(inode, cred, stateid, acred);
 		switch (err) {
 			case -NFS4ERR_STALE_STATEID:
 			case -NFS4ERR_EXPIRED:
@@ -3100,7 +3188,8 @@ nfs4_set_lock_task_retry(unsigned long timeout)
 	return timeout;
 }
 
-static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
+static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd,
+			    struct file_lock *request, struct cred *acred)
 {
 	struct inode *inode = state->inode;
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -3128,7 +3217,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
 		goto out;
 	lsp = request->fl_u.nfs4_fl.owner;
 	arg.lock_owner.id = lsp->ls_id.id;
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	switch (status) {
 		case 0:
 			request->fl_type = F_UNLCK;
@@ -3142,14 +3231,15 @@ out:
 	return status;
 }
 
-static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
+static int nfs4_proc_getlk(struct nfs4_state *state, int cmd,
+			   struct file_lock *request, struct cred *acred)
 {
 	struct nfs4_exception exception = { };
 	int err;
 
 	do {
 		err = nfs4_handle_exception(NFS_SERVER(state->inode),
-				_nfs4_proc_getlk(state, cmd, request),
+				_nfs4_proc_getlk(state, cmd, request, acred),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -3205,7 +3295,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
 	return p;
 }
 
-static void nfs4_locku_release_calldata(void *data)
+static void nfs4_locku_release_calldata(struct cred *acred, void *data)
 {
 	struct nfs4_unlockdata *calldata = data;
 	nfs_free_seqid(calldata->arg.seqid);
@@ -3282,7 +3372,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
 		return ERR_PTR(-ENOMEM);
 	}
 
-	return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data);
+	return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC,
+			    &nfs4_locku_ops, data, ctx->acred);
 }
 
 static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
@@ -3416,7 +3507,7 @@ out:
 	dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status);
 }
 
-static void nfs4_lock_release(void *calldata)
+static void nfs4_lock_release(struct cred *acred, void *calldata)
 {
 	struct nfs4_lockdata *data = calldata;
 
@@ -3460,7 +3551,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
 	if (reclaim != 0)
 		data->arg.reclaim = 1;
 	task = rpc_run_task(NFS_CLIENT(state->inode), RPC_TASK_ASYNC,
-			&nfs4_lock_ops, data);
+			&nfs4_lock_ops, data, fl->fl_file->f_cred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	ret = nfs4_wait_for_completion_rpc_task(task);
@@ -3584,7 +3675,7 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
 		return -EINVAL;
 
 	if (IS_GETLK(cmd))
-		return nfs4_proc_getlk(state, F_GETLK, request);
+		return nfs4_proc_getlk(state, F_GETLK, request, filp->f_cred);
 
 	if (!(IS_SETLK(cmd) || IS_SETLKW(cmd)))
 		return -EINVAL;
@@ -3628,6 +3719,7 @@ out:
 int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
 		size_t buflen, int flags)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 
 	if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
@@ -3637,7 +3729,7 @@ int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
 	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
 		return -EPERM;
 
-	return nfs4_proc_set_acl(inode, buf, buflen);
+	return nfs4_proc_set_acl(inode, buf, buflen, acred);
 }
 
 /* The getxattr man page suggests returning -ENODATA for unknown attributes,
@@ -3647,12 +3739,13 @@ int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
 ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
 		size_t buflen)
 {
+	struct cred *acred = current->cred;
 	struct inode *inode = dentry->d_inode;
 
 	if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
 		return -EOPNOTSUPP;
 
-	return nfs4_proc_get_acl(inode, buf, buflen);
+	return nfs4_proc_get_acl(inode, buf, buflen, acred);
 }
 
 ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
@@ -3669,7 +3762,8 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
 }
 
 int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
-		struct nfs4_fs_locations *fs_locations, struct page *page)
+		struct nfs4_fs_locations *fs_locations, struct page *page,
+		struct cred *acred)
 {
 	struct nfs_server *server = NFS_SERVER(dir);
 	u32 bitmask[2] = {
@@ -3693,7 +3787,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
 	nfs_fattr_init(&fs_locations->fattr);
 	fs_locations->server = server;
 	fs_locations->nlocations = 0;
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("%s: returned status = %d\n", __FUNCTION__, status);
 	return status;
 }
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 3ea352d..9d648c8 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -86,7 +86,7 @@ nfs4_renew_state(struct work_struct *work)
 		}
 		spin_unlock(&clp->cl_lock);
 		/* Queue an asynchronous RENEW. */
-		nfs4_proc_async_renew(clp, cred);
+		nfs4_proc_async_renew(clp, cred, &init_cred);
 		put_rpccred(cred);
 		timeout = (2 * lease) / 3;
 		spin_lock(&clp->cl_lock);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 3e4adf8..8ffdc68 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -60,12 +60,13 @@ const nfs4_stateid zero_stateid;
 
 static LIST_HEAD(nfs4_clientid_list);
 
-static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
+static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred,
+			    struct cred *acred)
 {
 	int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK,
-			nfs_callback_tcpport, cred);
+			nfs_callback_tcpport, cred, acred);
 	if (status == 0)
-		status = nfs4_proc_setclientid_confirm(clp, cred);
+		status = nfs4_proc_setclientid_confirm(clp, cred, acred);
 	if (status == 0)
 		nfs4_schedule_state_renewal(clp);
 	return status;
@@ -425,7 +426,8 @@ void nfs4_put_open_state(struct nfs4_state *state)
 /*
  * Close the current file.
  */
-void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode,
+		      struct cred *acred)
 {
 	struct nfs4_state_owner *owner = state->owner;
 	int call_close = 0;
@@ -466,7 +468,7 @@ void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
 		nfs4_put_open_state(state);
 		nfs4_put_state_owner(owner);
 	} else
-		nfs4_do_close(path, state);
+		nfs4_do_close(path, state, acred);
 }
 
 /*
@@ -905,7 +907,7 @@ restart_loop:
 	cred = nfs4_get_renew_cred(clp);
 	if (cred != NULL) {
 		/* Yes there are: try to renew the old lease */
-		status = nfs4_proc_renew(clp, cred);
+		status = nfs4_proc_renew(clp, cred, &init_cred);
 		switch (status) {
 			case 0:
 			case -NFS4ERR_CB_PATH_DOWN:
@@ -924,7 +926,7 @@ restart_loop:
 	nfs4_state_mark_reclaim(clp);
 	status = -ENOENT;
 	if (cred != NULL) {
-		status = nfs4_init_client(clp, cred);
+		status = nfs4_init_client(clp, cred, &init_cred);
 		put_rpccred(cred);
 	}
 	if (status)
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index d6baeb4..aeb7e38 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -52,7 +52,7 @@
  */
 static int
 nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
-		  struct nfs_fsinfo *info)
+		  struct nfs_fsinfo *info, struct cred *acred)
 {
 	struct nfs_fattr *fattr = info->fattr;
 	struct nfs2_fsstat fsinfo;
@@ -65,14 +65,16 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("%s: call getattr\n", __FUNCTION__);
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
+	status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0,
+			       acred);
 	dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
 	if (status)
 		return status;
 	dprintk("%s: call statfs\n", __FUNCTION__);
 	msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS];
 	msg.rpc_resp = &fsinfo;
-	status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
+	status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0,
+			       acred);
 	dprintk("%s: reply statfs: %d\n", __FUNCTION__, status);
 	if (status)
 		return status;
@@ -93,7 +95,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  */
 static int
 nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-		struct nfs_fattr *fattr)
+		struct nfs_fattr *fattr, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs_procedures[NFSPROC_GETATTR],
@@ -104,14 +106,14 @@ nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  getattr\n");
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply getattr: %d\n", status);
 	return status;
 }
 
 static int
 nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
-		 struct iattr *sattr)
+		 struct iattr *sattr, struct cred *acred)
 {
 	struct inode *inode = dentry->d_inode;
 	struct nfs_sattrargs	arg = { 
@@ -130,7 +132,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 	dprintk("NFS call  setattr\n");
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	if (status == 0)
 		nfs_setattr_update_inode(inode, sattr);
 	dprintk("NFS reply setattr: %d\n", status);
@@ -139,7 +141,8 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 static int
 nfs_proc_lookup(struct inode *dir, struct qstr *name,
-		struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+		struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+		struct cred *acred)
 {
 	struct nfs_diropargs	arg = {
 		.fh		= NFS_FH(dir),
@@ -159,13 +162,13 @@ nfs_proc_lookup(struct inode *dir, struct qstr *name,
 
 	dprintk("NFS call  lookup %s\n", name->name);
 	nfs_fattr_init(fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	dprintk("NFS reply lookup: %d\n", status);
 	return status;
 }
 
 static int nfs_proc_readlink(struct inode *inode, struct page *page,
-		unsigned int pgbase, unsigned int pglen)
+		unsigned int pgbase, unsigned int pglen, struct cred *acred)
 {
 	struct nfs_readlinkargs	args = {
 		.fh		= NFS_FH(inode),
@@ -180,14 +183,14 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page,
 	int			status;
 
 	dprintk("NFS call  readlink\n");
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	dprintk("NFS reply readlink: %d\n", status);
 	return status;
 }
 
 static int
 nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-		int flags, struct nameidata *nd)
+		int flags, struct nameidata *nd, struct cred *acred)
 {
 	struct nfs_fh		fhandle;
 	struct nfs_fattr	fattr;
@@ -210,9 +213,9 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 
 	nfs_fattr_init(&fattr);
 	dprintk("NFS call  create %s\n", dentry->d_name.name);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	if (status == 0)
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	dprintk("NFS reply create: %d\n", status);
 	return status;
 }
@@ -222,7 +225,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
  */
 static int
 nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-	       dev_t rdev)
+	       dev_t rdev, struct cred *acred)
 {
 	struct nfs_fh fhandle;
 	struct nfs_fattr fattr;
@@ -255,22 +258,22 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 	}
 
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_mark_for_revalidate(dir);
 
 	if (status == -EINVAL && S_ISFIFO(mode)) {
 		sattr->ia_mode = mode;
 		nfs_fattr_init(&fattr);
-		status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+		status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	}
 	if (status == 0)
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	dprintk("NFS reply mknod: %d\n", status);
 	return status;
 }
   
 static int
-nfs_proc_remove(struct inode *dir, struct qstr *name)
+nfs_proc_remove(struct inode *dir, struct qstr *name, struct cred *acred)
 {
 	struct nfs_removeargs arg = {
 		.fh = NFS_FH(dir),
@@ -284,7 +287,7 @@ nfs_proc_remove(struct inode *dir, struct qstr *name)
 	int			status;
 
 	dprintk("NFS call  remove %s\n", name->name);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_mark_for_revalidate(dir);
 
 	dprintk("NFS reply remove: %d\n", status);
@@ -305,7 +308,8 @@ static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
 
 static int
 nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
-		struct inode *new_dir, struct qstr *new_name)
+		struct inode *new_dir, struct qstr *new_name,
+		struct cred *acred)
 {
 	struct nfs_renameargs	arg = {
 		.fromfh		= NFS_FH(old_dir),
@@ -322,7 +326,7 @@ nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
 	int			status;
 
 	dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
-	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0, acred);
 	nfs_mark_for_revalidate(old_dir);
 	nfs_mark_for_revalidate(new_dir);
 	dprintk("NFS reply rename: %d\n", status);
@@ -330,7 +334,8 @@ nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
 }
 
 static int
-nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
+nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name,
+	      struct cred *acred)
 {
 	struct nfs_linkargs	arg = {
 		.fromfh		= NFS_FH(inode),
@@ -345,7 +350,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 	int			status;
 
 	dprintk("NFS call  link %s\n", name->name);
-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0, acred);
 	nfs_mark_for_revalidate(inode);
 	nfs_mark_for_revalidate(dir);
 	dprintk("NFS reply link: %d\n", status);
@@ -354,7 +359,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 
 static int
 nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
-		 unsigned int len, struct iattr *sattr)
+		 unsigned int len, struct iattr *sattr, struct cred *acred)
 {
 	struct nfs_fh fhandle;
 	struct nfs_fattr fattr;
@@ -377,7 +382,7 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
 
 	dprintk("NFS call  symlink %s\n", dentry->d_name.name);
 
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_mark_for_revalidate(dir);
 
 	/*
@@ -388,7 +393,7 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
 	if (status == 0) {
 		nfs_fattr_init(&fattr);
 		fhandle.size = 0;
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	}
 
 	dprintk("NFS reply symlink: %d\n", status);
@@ -396,7 +401,8 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
 }
 
 static int
-nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
+nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+	       struct cred *acred)
 {
 	struct nfs_fh fhandle;
 	struct nfs_fattr fattr;
@@ -419,16 +425,16 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
 
 	dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
 	nfs_fattr_init(&fattr);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_mark_for_revalidate(dir);
 	if (status == 0)
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+		status = nfs_instantiate(dentry, &fhandle, &fattr, acred);
 	dprintk("NFS reply mkdir: %d\n", status);
 	return status;
 }
 
 static int
-nfs_proc_rmdir(struct inode *dir, struct qstr *name)
+nfs_proc_rmdir(struct inode *dir, struct qstr *name, struct cred *acred)
 {
 	struct nfs_diropargs	arg = {
 		.fh		= NFS_FH(dir),
@@ -442,7 +448,7 @@ nfs_proc_rmdir(struct inode *dir, struct qstr *name)
 	int			status;
 
 	dprintk("NFS call  rmdir %s\n", name->name);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 	nfs_mark_for_revalidate(dir);
 	dprintk("NFS reply rmdir: %d\n", status);
 	return status;
@@ -457,7 +463,8 @@ nfs_proc_rmdir(struct inode *dir, struct qstr *name)
  */
 static int
 nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
-		 u64 cookie, struct page *page, unsigned int count, int plus)
+		 u64 cookie, struct page *page, unsigned int count, int plus,
+		 struct cred *acred)
 {
 	struct inode		*dir = dentry->d_inode;
 	struct nfs_readdirargs	arg = {
@@ -474,7 +481,7 @@ nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 	int			status;
 
 	dprintk("NFS call  readdir %d\n", (unsigned int)cookie);
-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0, acred);
 
 	dprintk("NFS reply readdir: %d\n", status);
 	return status;
@@ -482,7 +489,7 @@ nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 
 static int
 nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
-			struct nfs_fsstat *stat)
+			struct nfs_fsstat *stat, struct cred *acred)
 {
 	struct nfs2_fsstat fsinfo;
 	struct rpc_message msg = {
@@ -494,7 +501,7 @@ nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  statfs\n");
 	nfs_fattr_init(stat->fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply statfs: %d\n", status);
 	if (status)
 		goto out;
@@ -510,7 +517,7 @@ out:
 
 static int
 nfs_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
-			struct nfs_fsinfo *info)
+			struct nfs_fsinfo *info, struct cred *acred)
 {
 	struct nfs2_fsstat fsinfo;
 	struct rpc_message msg = {
@@ -522,7 +529,7 @@ nfs_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	dprintk("NFS call  fsinfo\n");
 	nfs_fattr_init(info->fattr);
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0, acred);
 	dprintk("NFS reply fsinfo: %d\n", status);
 	if (status)
 		goto out;
@@ -541,7 +548,7 @@ out:
 
 static int
 nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
-		  struct nfs_pathconf *info)
+		  struct nfs_pathconf *info, struct cred *acred)
 {
 	info->max_link = 0;
 	info->max_namelen = NFS2_MAXNAMLEN;
@@ -561,7 +568,7 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
 	return 0;
 }
 
-static void nfs_proc_read_setup(struct nfs_read_data *data)
+static void nfs_proc_read_setup(struct nfs_read_data *data, struct cred *acred)
 {
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs_procedures[NFSPROC_READ],
@@ -570,7 +577,7 @@ static void nfs_proc_read_setup(struct nfs_read_data *data)
 		.rpc_cred	= data->cred,
 	};
 
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -580,7 +587,8 @@ static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
 	return 0;
 }
 
-static void nfs_proc_write_setup(struct nfs_write_data *data, int how)
+static void nfs_proc_write_setup(struct nfs_write_data *data, int how,
+				 struct cred *acred)
 {
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs_procedures[NFSPROC_WRITE],
@@ -593,11 +601,11 @@ static void nfs_proc_write_setup(struct nfs_write_data *data, int how)
 	data->args.stable = NFS_FILE_SYNC;
 
 	/* Finalize the task. */
-	rpc_call_setup(&data->task, &msg, 0, current->cred);
+	rpc_call_setup(&data->task, &msg, 0, acred);
 }
 
 static void
-nfs_proc_commit_setup(struct nfs_write_data *data, int how)
+nfs_proc_commit_setup(struct nfs_write_data *data, int how, struct cred *acred)
 {
 	BUG();
 }
@@ -605,7 +613,8 @@ nfs_proc_commit_setup(struct nfs_write_data *data, int how)
 static int
 nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
 {
-	return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl);
+	return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl,
+			    filp->f_cred);
 }
 
 
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 19e0563..8cde60c 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -71,7 +71,7 @@ static void nfs_readdata_free(struct nfs_read_data *rdata)
 	call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free);
 }
 
-void nfs_readdata_release(void *data)
+void nfs_readdata_release(struct cred *acred, void *data)
 {
         nfs_readdata_free(data);
 }
@@ -181,8 +181,9 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
 
 	/* Set up the initial task struct. */
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
-	rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data);
-	NFS_PROTO(inode)->read_setup(data);
+	rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data,
+		      req->wb_context->acred);
+	NFS_PROTO(inode)->read_setup(data, req->wb_context->acred);
 
 	data->task.tk_cookie = (unsigned long)inode;
 
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index b878528..0988df4 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -355,6 +355,7 @@ void __exit unregister_nfs_fs(void)
  */
 static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
+	struct cred *acred = current->cred;
 	struct nfs_server *server = NFS_SB(dentry->d_sb);
 	unsigned char blockbits;
 	unsigned long blockres;
@@ -367,7 +368,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 	lock_kernel();
 
-	error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
+	error = server->nfs_client->rpc_ops->statfs(server, fh, &res, acred);
 	if (error < 0)
 		goto out_err;
 	buf->f_type = NFS_SUPER_MAGIC;
@@ -1008,7 +1009,7 @@ out_unknown:
  * corresponding to the provided path.
  */
 static int nfs_try_mount(struct nfs_parsed_mount_data *args,
-			 struct nfs_fh *root_fh)
+			 struct nfs_fh *root_fh, struct cred *acred)
 {
 	struct sockaddr_in sin;
 	int status;
@@ -1048,7 +1049,8 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
 			   args->nfs_server.export_path,
 			   args->mount_server.version,
 			   args->mount_server.protocol,
-			   root_fh);
+			   root_fh,
+			   acred);
 	if (status < 0)
 		goto out_err;
 
@@ -1081,7 +1083,8 @@ out_err:
  */
 static int nfs_validate_mount_data(struct nfs_mount_data **options,
 				   struct nfs_fh *mntfh,
-				   const char *dev_name)
+				   const char *dev_name,
+				   struct cred *acred)
 {
 	struct nfs_mount_data *data = *options;
 
@@ -1164,7 +1167,7 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options,
 			return -ENAMETOOLONG;
 		args.nfs_server.export_path = c;
 
-		status = nfs_try_mount(&args, mntfh);
+		status = nfs_try_mount(&args, mntfh, acred);
 		if (status)
 			return status;
 
@@ -1376,6 +1379,7 @@ static int nfs_compare_super(struct super_block *sb, void *data)
 static int nfs_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
+	struct cred *acred = current->cred;
 	struct nfs_server *server = NULL;
 	struct super_block *s;
 	struct nfs_fh mntfh;
@@ -1388,12 +1392,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
 	int error;
 
 	/* Validate the mount data */
-	error = nfs_validate_mount_data(&data, &mntfh, dev_name);
+	error = nfs_validate_mount_data(&data, &mntfh, dev_name, acred);
 	if (error < 0)
 		goto out;
 
 	/* Get a volume representation */
-	server = nfs_create_server(data, &mntfh);
+	server = nfs_create_server(data, &mntfh, acred);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out;
@@ -1420,7 +1424,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
 		nfs_fill_super(s, data);
 	}
 
-	mntroot = nfs_get_root(s, &mntfh);
+	mntroot = nfs_get_root(s, &mntfh, acred);
 	if (IS_ERR(mntroot)) {
 		error = PTR_ERR(mntroot);
 		goto error_splat_super;
@@ -1464,6 +1468,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
 			   const char *dev_name, void *raw_data,
 			   struct vfsmount *mnt)
 {
+	struct cred *acred = current->cred;
 	struct nfs_clone_mount *data = raw_data;
 	struct super_block *s;
 	struct nfs_server *server;
@@ -1477,7 +1482,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
 	dprintk("--> nfs_xdev_get_sb()\n");
 
 	/* create a new volume representation */
-	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, acred);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out_err_noserver;
@@ -1504,7 +1509,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
 		nfs_clone_super(s, data->sb);
 	}
 
-	mntroot = nfs_get_root(s, data->fh);
+	mntroot = nfs_get_root(s, data->fh, acred);
 	if (IS_ERR(mntroot)) {
 		error = PTR_ERR(mntroot);
 		goto error_splat_super;
@@ -1729,6 +1734,7 @@ out_no_client_address:
 static int nfs4_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
+	struct cred *acred = current->cred;
 	struct nfs4_mount_data *data = raw_data;
 	struct super_block *s;
 	struct nfs_server *server;
@@ -1751,7 +1757,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
 
 	/* Get a volume representation */
 	server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
-				    authflavour, &mntfh);
+				    authflavour, &mntfh, acred);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out;
@@ -1778,7 +1784,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
 		nfs4_fill_super(s);
 	}
 
-	mntroot = nfs4_get_root(s, &mntfh);
+	mntroot = nfs4_get_root(s, &mntfh, acred);
 	if (IS_ERR(mntroot)) {
 		error = PTR_ERR(mntroot);
 		goto error_splat_super;
@@ -1823,6 +1829,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
 			    const char *dev_name, void *raw_data,
 			    struct vfsmount *mnt)
 {
+	struct cred *acred = current->cred;
 	struct nfs_clone_mount *data = raw_data;
 	struct super_block *s;
 	struct nfs_server *server;
@@ -1836,7 +1843,8 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
 	dprintk("--> nfs4_xdev_get_sb()\n");
 
 	/* create a new volume representation */
-	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr,
+				  acred);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out_err_noserver;
@@ -1863,7 +1871,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
 		nfs4_clone_super(s, data->sb);
 	}
 
-	mntroot = nfs4_get_root(s, data->fh);
+	mntroot = nfs4_get_root(s, data->fh, acred);
 	if (IS_ERR(mntroot)) {
 		error = PTR_ERR(mntroot);
 		goto error_splat_super;
@@ -1896,6 +1904,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
 				const char *dev_name, void *raw_data,
 				struct vfsmount *mnt)
 {
+	struct cred *acred = current->cred;
 	struct nfs_clone_mount *data = raw_data;
 	struct super_block *s;
 	struct nfs_server *server;
@@ -1910,7 +1919,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
 	dprintk("--> nfs4_referral_get_sb()\n");
 
 	/* create a new volume representation */
-	server = nfs4_create_referral_server(data, &mntfh);
+	server = nfs4_create_referral_server(data, &mntfh, acred);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out_err_noserver;
@@ -1937,7 +1946,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
 		nfs4_fill_super(s);
 	}
 
-	mntroot = nfs4_get_root(s, &mntfh);
+	mntroot = nfs4_get_root(s, &mntfh, acred);
 	if (IS_ERR(mntroot)) {
 		error = PTR_ERR(mntroot);
 		goto error_splat_super;
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 83e865a..cd1df31 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -24,15 +24,23 @@
 #include <linux/string.h>
 #include <linux/namei.h>
 
+struct nfs_symlink_filler_data {
+	struct inode	*inode;
+	struct cred	*acred;
+};
+
 /* Symlink caching in the page cache is even more simplistic
  * and straight-forward than readdir caching.
  */
 
-static int nfs_symlink_filler(struct inode *inode, struct page *page)
+static int nfs_symlink_filler(void *_data, struct page *page)
 {
+	struct nfs_symlink_filler_data *data = _data;
+	struct inode *inode = data->inode;
+	struct cred *acred = data->acred;
 	int error;
 
-	error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE);
+	error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE, acred);
 	if (error < 0)
 		goto error;
 	SetPageUptodate(page);
@@ -48,14 +56,20 @@ error:
 static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct inode *inode = dentry->d_inode;
+	struct cred *acred = current->cred;
 	struct page *page;
 	void *err;
 
-	err = ERR_PTR(nfs_revalidate_mapping_nolock(inode, inode->i_mapping));
+	struct nfs_symlink_filler_data data = {
+		.inode = inode,
+		.acred = acred,
+	};
+
+	err = ERR_PTR(nfs_revalidate_mapping_nolock(inode, inode->i_mapping,
+						    acred));
 	if (err)
 		goto read_failed;
-	page = read_cache_page(&inode->i_data, 0,
-				(filler_t *)nfs_symlink_filler, inode);
+	page = read_cache_page(&inode->i_data, 0, nfs_symlink_filler, &data);
 	if (IS_ERR(page)) {
 		err = page;
 		goto read_failed;
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index d4e7d09..0d1700b 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -95,7 +95,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
  * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
  * rpc_task would be freed too.
  */
-static void nfs_async_unlink_release(void *calldata)
+static void nfs_async_unlink_release(struct cred *acred, void *calldata)
 {
 	struct nfs_unlinkdata	*data = calldata;
 	nfs_free_unlinkdata(data);
@@ -107,7 +107,8 @@ static const struct rpc_call_ops nfs_unlink_ops = {
 	.rpc_release = nfs_async_unlink_release,
 };
 
-static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data,
+			   struct cred *acred)
 {
 	struct rpc_task *task;
 	struct dentry *parent;
@@ -128,7 +129,8 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
 	data->args.fh = NFS_FH(dir);
 	nfs_fattr_init(&data->res.dir_attr);
 
-	task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data);
+	task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops,
+			    data, acred);
 	if (!IS_ERR(task))
 		rpc_put_task(task);
 	return 1;
@@ -142,9 +144,8 @@ out_free:
  * @dentry: dentry to unlink
  */
 int
-nfs_async_unlink(struct inode *dir, struct dentry *dentry)
+nfs_async_unlink(struct inode *dir, struct dentry *dentry, struct cred *acred)
 {
-	struct cred *acred = current->cred;
 	struct nfs_unlinkdata *data;
 	int status = -ENOMEM;
 
@@ -179,13 +180,15 @@ out:
  * nfs_complete_unlink - Initialize completion of the sillydelete
  * @dentry: dentry to delete
  * @inode: inode
+ * @acred: the credentials to use
  *
  * Since we're most likely to be called by dentry_iput(), we
  * only use the dentry to find the sillydelete. We then copy the name
  * into the qstr.
  */
 void
-nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
+nfs_complete_unlink(struct dentry *dentry, struct inode *inode,
+		    struct cred *acred)
 {
 	struct nfs_unlinkdata	*data = NULL;
 
@@ -196,6 +199,7 @@ nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
 	}
 	spin_unlock(&dentry->d_lock);
 
-	if (data != NULL && (NFS_STALE(inode) || !nfs_call_unlink(dentry, data)))
+	if (data != NULL &&
+	    (NFS_STALE(inode) || !nfs_call_unlink(dentry, data, acred)))
 		nfs_free_unlinkdata(data);
 }
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0d7a77c..42f5b5d 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -105,7 +105,7 @@ static void nfs_writedata_free(struct nfs_write_data *wdata)
 	call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free);
 }
 
-void nfs_writedata_release(void *wdata)
+void nfs_writedata_release(struct cred *acred, void *wdata)
 {
 	nfs_writedata_free(wdata);
 }
@@ -806,8 +806,9 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
 
 	/* Set up the initial task struct.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
-	rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data);
-	NFS_PROTO(inode)->write_setup(data, how);
+	rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data,
+		      req->wb_context->acred);
+	NFS_PROTO(inode)->write_setup(data, how, req->wb_context->acred);
 
 	data->task.tk_priority = flush_task_priority(how);
 	data->task.tk_cookie = (unsigned long)inode;
@@ -837,6 +838,7 @@ static void nfs_execute_write(struct nfs_write_data *data)
  */
 static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how)
 {
+	struct cred *acred = &writeback_cred;
 	struct nfs_page *req = nfs_list_entry(head->next);
 	struct page *page = req->wb_page;
 	struct nfs_write_data *data;
@@ -884,7 +886,7 @@ out_bad:
 	while (!list_empty(&list)) {
 		data = list_entry(list.next, struct nfs_write_data, pages);
 		list_del(&data->pages);
-		nfs_writedata_release(data);
+		nfs_writedata_release(acred, data);
 	}
 	nfs_redirty_request(req);
 	nfs_end_page_writeback(req->wb_page);
@@ -1141,7 +1143,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-void nfs_commit_release(void *wdata)
+void nfs_commit_release(struct cred *acred, void *wdata)
 {
 	nfs_commit_free(wdata);
 }
@@ -1178,8 +1180,9 @@ static void nfs_commit_rpcsetup(struct list_head *head,
 
 	/* Set up the initial task struct.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
-	rpc_init_task(&data->task, NFS_CLIENT(inode), flags, &nfs_commit_ops, data);
-	NFS_PROTO(inode)->commit_setup(data, how);
+	rpc_init_task(&data->task, NFS_CLIENT(inode), flags, &nfs_commit_ops,
+		      data, first->wb_context->acred);
+	NFS_PROTO(inode)->commit_setup(data, how, first->wb_context->acred);
 
 	data->task.tk_priority = flush_task_priority(how);
 	data->task.tk_cookie = (unsigned long)inode;
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 6f1637c..aacb15c 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -35,8 +35,9 @@ extern struct nlmsvc_binding *	nlmsvc_ops;
 /*
  * Functions exported by the lockd module
  */
-extern int	nlmclnt_proc(struct inode *, int, struct file_lock *);
-extern int	lockd_up(int proto);
+extern int	nlmclnt_proc(struct inode *, int, struct file_lock *,
+			     struct cred *);
+extern int	lockd_up(int proto, struct cred *acred);
 extern void	lockd_down(void);
 
 unsigned long get_nfs_grace_period(void);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index e2d1ce3..fc5b04e 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -96,6 +96,7 @@ struct nlm_rqst {
 	struct nlm_args		a_args;		/* arguments */
 	struct nlm_res		a_res;		/* result */
 	struct nlm_block *	a_block;
+	struct cred *		a_acred;	/* credentials to use */
 	unsigned int		a_retries;	/* Retry count */
 	u8			a_owner[NLMCLNT_OHSIZE];
 };
@@ -158,7 +159,7 @@ extern int			nsm_use_hostnames;
 /*
  * Lockd client functions
  */
-struct nlm_rqst * nlm_alloc_call(struct nlm_host *host);
+struct nlm_rqst * nlm_alloc_call(struct nlm_host *host, struct cred *acred);
 void		  nlm_release_call(struct nlm_rqst *);
 int		  nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
 int		  nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
@@ -175,7 +176,7 @@ void		  nlmclnt_next_cookie(struct nlm_cookie *);
  */
 struct nlm_host * nlmclnt_lookup_host(const struct sockaddr_in *, int, int, const char *, int);
 struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *, const char *, int);
-struct rpc_clnt * nlm_bind_host(struct nlm_host *);
+struct rpc_clnt * nlm_bind_host(struct nlm_host *, struct cred *);
 void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void		  nlm_release_host(struct nlm_host *);
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index 22a6458..a7dc1c6 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -40,8 +40,8 @@ struct nsm_res {
 	u32		state;
 };
 
-int		nsm_monitor(struct nlm_host *);
-int		nsm_unmonitor(struct nlm_host *);
+int		nsm_monitor(struct nlm_host *, struct cred *);
+int		nsm_unmonitor(struct nlm_host *, struct cred *);
 extern int	nsm_local_state;
 
 #endif /* LINUX_LOCKD_SM_INTER_H */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 7250eea..f7ab86c 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -73,6 +73,7 @@ struct nfs4_state;
 struct nfs_open_context {
 	atomic_t count;
 	struct path path;
+	struct cred *acred;
 	struct rpc_cred *cred;
 	struct nfs4_state *state;
 	fl_owner_t lockowner;
@@ -295,10 +296,16 @@ extern void nfs_access_zap_cache(struct inode *inode);
 extern int nfs_open(struct inode *, struct file *);
 extern int nfs_release(struct inode *, struct file *);
 extern int nfs_attribute_timeout(struct inode *inode);
-extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
-extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
-extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
-extern int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping);
+extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode,
+				struct cred *acred);
+extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *,
+				  struct cred *);
+extern int nfs_revalidate_mapping(struct inode *inode,
+				  struct address_space *mapping,
+				  struct cred *acred);
+extern int nfs_revalidate_mapping_nolock(struct inode *inode,
+					 struct address_space *mapping,
+					 struct cred *acred);
 extern int nfs_setattr(struct dentry *, struct iattr *);
 extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
 extern void nfs_begin_attr_update(struct inode *);
@@ -377,7 +384,8 @@ extern const struct inode_operations nfs3_dir_inode_operations;
 extern const struct file_operations nfs_dir_operations;
 extern struct dentry_operations nfs_dentry_operations;
 
-extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr);
+extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
+			   struct nfs_fattr *fattr, struct cred *acred);
 
 /*
  * linux/fs/nfs/symlink.c
@@ -407,8 +415,9 @@ extern void nfs_release_automount_timer(void);
 /*
  * linux/fs/nfs/unlink.c
  */
-extern int  nfs_async_unlink(struct inode *dir, struct dentry *dentry);
-extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
+extern int  nfs_async_unlink(struct inode *dir, struct dentry *dentry,
+			     struct cred *);
+extern void nfs_complete_unlink(struct dentry *, struct inode *, struct cred *);
 
 /*
  * linux/fs/nfs/write.c
@@ -419,7 +428,7 @@ extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
 extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
-extern void nfs_writedata_release(void *);
+extern void nfs_writedata_release(struct cred *, void *);
 extern int nfs_set_page_dirty(struct page *);
 
 /*
@@ -436,7 +445,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
 extern int  nfs_commit_inode(struct inode *, int);
 extern struct nfs_write_data *nfs_commit_alloc(void);
 extern void nfs_commit_free(struct nfs_write_data *wdata);
-extern void nfs_commit_release(void *wdata);
+extern void nfs_commit_release(struct cred *acred, void *wdata);
 #else
 static inline int
 nfs_commit_inode(struct inode *inode, int how)
@@ -463,7 +472,7 @@ extern int  nfs_readpage(struct file *, struct page *);
 extern int  nfs_readpages(struct file *, struct address_space *,
 		struct list_head *, unsigned);
 extern int  nfs_readpage_result(struct rpc_task *, struct nfs_read_data *);
-extern void nfs_readdata_release(void *data);
+extern void nfs_readdata_release(struct cred *acred, void *data);
 
 /*
  * Allocate nfs_read_data structures
@@ -474,11 +483,12 @@ extern struct nfs_read_data *nfs_readdata_alloc(unsigned int npages);
  * linux/fs/nfs3proc.c
  */
 #ifdef CONFIG_NFS_V3_ACL
-extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type);
+extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type,
+					  struct cred *acred);
 extern int nfs3_proc_setacl(struct inode *inode, int type,
-			    struct posix_acl *acl);
+			    struct posix_acl *acl, struct cred *acred);
 extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
-		mode_t mode);
+		mode_t mode, struct cred *acred);
 extern void nfs3_forget_cached_acls(struct inode *inode);
 #else
 static inline int nfs3_proc_set_default_acl(struct inode *dir,
@@ -497,7 +507,7 @@ static inline void nfs3_forget_cached_acls(struct inode *inode)
  * linux/fs/mount_clnt.c
  */
 extern int  nfs_mount(struct sockaddr *, size_t, char *, char *,
-		      int, int, struct nfs_fh *);
+		      int, int, struct nfs_fh *, struct cred *);
 
 /*
  * inline functions
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index cf74a4d..e82a5db 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -775,48 +775,56 @@ struct nfs_rpc_ops {
 	const struct inode_operations *file_inode_ops;
 
 	int	(*getroot) (struct nfs_server *, struct nfs_fh *,
-			    struct nfs_fsinfo *);
+			    struct nfs_fsinfo *, struct cred *);
 	int	(*lookupfh)(struct nfs_server *, struct nfs_fh *,
 			    struct qstr *, struct nfs_fh *,
-			    struct nfs_fattr *);
+			    struct nfs_fattr *, struct cred *);
 	int	(*getattr) (struct nfs_server *, struct nfs_fh *,
-			    struct nfs_fattr *);
+			    struct nfs_fattr *, struct cred *);
 	int	(*setattr) (struct dentry *, struct nfs_fattr *,
-			    struct iattr *);
+			    struct iattr *, struct cred *);
 	int	(*lookup)  (struct inode *, struct qstr *,
-			    struct nfs_fh *, struct nfs_fattr *);
-	int	(*access)  (struct inode *, struct nfs_access_entry *);
+			    struct nfs_fh *, struct nfs_fattr *, struct cred *);
+	int	(*access)  (struct inode *, struct nfs_access_entry *,
+			    struct cred *);
 	int	(*readlink)(struct inode *, struct page *, unsigned int,
-			    unsigned int);
+			    unsigned int, struct cred *);
 	int	(*create)  (struct inode *, struct dentry *,
-			    struct iattr *, int, struct nameidata *);
-	int	(*remove)  (struct inode *, struct qstr *);
+			    struct iattr *, int, struct nameidata *,
+			    struct cred *);
+	int	(*remove)  (struct inode *, struct qstr *, struct cred *);
 	void	(*unlink_setup)  (struct rpc_message *, struct inode *dir);
 	int	(*unlink_done) (struct rpc_task *, struct inode *);
 	int	(*rename)  (struct inode *, struct qstr *,
-			    struct inode *, struct qstr *);
-	int	(*link)    (struct inode *, struct inode *, struct qstr *);
+			    struct inode *, struct qstr *, struct cred *);
+	int	(*link)    (struct inode *, struct inode *, struct qstr *,
+			    struct cred *);
 	int	(*symlink) (struct inode *, struct dentry *, struct page *,
-			    unsigned int, struct iattr *);
-	int	(*mkdir)   (struct inode *, struct dentry *, struct iattr *);
-	int	(*rmdir)   (struct inode *, struct qstr *);
+			    unsigned int, struct iattr *, struct cred *);
+	int	(*mkdir)   (struct inode *, struct dentry *, struct iattr *,
+			    struct cred *);
+	int	(*rmdir)   (struct inode *, struct qstr *, struct cred *);
 	int	(*readdir) (struct dentry *, struct rpc_cred *,
-			    u64, struct page *, unsigned int, int);
+			    u64, struct page *, unsigned int, int,
+			    struct cred *);
 	int	(*mknod)   (struct inode *, struct dentry *, struct iattr *,
-			    dev_t);
+			    dev_t, struct cred *);
 	int	(*statfs)  (struct nfs_server *, struct nfs_fh *,
-			    struct nfs_fsstat *);
+			    struct nfs_fsstat *, struct cred *);
 	int	(*fsinfo)  (struct nfs_server *, struct nfs_fh *,
-			    struct nfs_fsinfo *);
+			    struct nfs_fsinfo *, struct cred *);
 	int	(*pathconf) (struct nfs_server *, struct nfs_fh *,
-			     struct nfs_pathconf *);
-	int	(*set_capabilities)(struct nfs_server *, struct nfs_fh *);
+			     struct nfs_pathconf *, struct cred *);
+	int	(*set_capabilities)(struct nfs_server *, struct nfs_fh *,
+				    struct cred *);
 	__be32 *(*decode_dirent)(__be32 *, struct nfs_entry *, int plus);
-	void	(*read_setup)   (struct nfs_read_data *);
+	void	(*read_setup)   (struct nfs_read_data *, struct cred *);
 	int	(*read_done)  (struct rpc_task *, struct nfs_read_data *);
-	void	(*write_setup)  (struct nfs_write_data *, int how);
+	void	(*write_setup)  (struct nfs_write_data *, int how,
+				 struct cred *);
 	int	(*write_done)  (struct rpc_task *, struct nfs_write_data *);
-	void	(*commit_setup) (struct nfs_write_data *, int how);
+	void	(*commit_setup) (struct nfs_write_data *, int how,
+				 struct cred *);
 	int	(*commit_done) (struct rpc_task *, struct nfs_write_data *);
 	int	(*file_open)   (struct inode *, struct file *);
 	int	(*file_release) (struct inode *, struct file *);
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index ae52668..3b68540 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -115,9 +115,9 @@ struct rpc_create_args {
 #define RPC_CLNT_CREATE_NOPING		(1UL << 4)
 #define RPC_CLNT_CREATE_DISCRTRY	(1UL << 5)
 
-struct rpc_clnt *rpc_create(struct rpc_create_args *args);
+struct rpc_clnt *rpc_create(struct rpc_create_args *args, struct cred *acred);
 struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
-				struct rpc_program *, int);
+				struct rpc_program *, int, struct cred *);
 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
 void		rpc_shutdown_client(struct rpc_clnt *);
 void		rpc_release_client(struct rpc_clnt *);
@@ -131,11 +131,11 @@ 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, const struct rpc_call_ops *tk_ops,
-			       void *calldata);
+			       void *calldata, struct cred *acred);
 int		rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
-			      int flags);
+			      int flags, struct cred *acred);
 struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
-			       int flags);
+			       int flags, struct cred *acred);
 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);
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index fed97e0..a7764bb 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -115,7 +115,7 @@ typedef void			(*rpc_action)(struct rpc_task *);
 struct rpc_call_ops {
 	void (*rpc_call_prepare)(struct rpc_task *, void *);
 	void (*rpc_call_done)(struct rpc_task *, void *);
-	void (*rpc_release)(void *);
+	void (*rpc_release)(struct cred *, void *);
 };
 
 
@@ -238,15 +238,18 @@ struct rpc_wait_queue {
  * Function prototypes
  */
 struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags,
-				const struct rpc_call_ops *ops, void *data);
+				const struct rpc_call_ops *ops, void *data,
+				struct cred *acred);
 struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
-				const struct rpc_call_ops *ops, void *data);
+				const struct rpc_call_ops *ops, void *data,
+			        struct cred *acred);
 void		rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt,
 				int flags, const struct rpc_call_ops *ops,
-				void *data);
+				void *data, struct cred *cred);
 void		rpc_put_task(struct rpc_task *);
 void		rpc_exit_task(struct rpc_task *);
-void		rpc_release_calldata(const struct rpc_call_ops *, void *);
+void		rpc_release_calldata(const struct rpc_call_ops *, void *,
+				     struct cred *);
 void		rpc_killall_tasks(struct rpc_clnt *);
 void		rpc_execute(struct rpc_task *);
 void		rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index bad2698..26c1913 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -720,7 +720,7 @@ gss_destroying_context(struct rpc_cred *cred)
 	 * by the RPC call or by the put_rpccred() below */
 	get_rpccred(cred);
 
-	task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC);
+	task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC, &init_cred);
 	if (!IS_ERR(task))
 		rpc_put_task(task);
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index a02a776..952e2eb 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -72,7 +72,7 @@ static void	call_connect_status(struct rpc_task *task);
 static __be32 *	call_header(struct rpc_task *task);
 static __be32 *	call_verify(struct rpc_task *task);
 
-static int	rpc_ping(struct rpc_clnt *clnt, int flags);
+static int	rpc_ping(struct rpc_clnt *clnt, int flags, struct cred *acred);
 
 static void rpc_register_client(struct rpc_clnt *clnt)
 {
@@ -223,6 +223,7 @@ out_no_rpciod:
 /*
  * rpc_create - create an RPC client and transport with one call
  * @args: rpc_clnt create argument structure
+ * @acred: the credentials to use
  *
  * Creates and initializes an RPC transport and an RPC client.
  *
@@ -230,7 +231,7 @@ out_no_rpciod:
  * it supports this program and version.  RPC_CLNT_CREATE_NOPING disables
  * this behavior so asynchronous tasks can also use rpc_create.
  */
-struct rpc_clnt *rpc_create(struct rpc_create_args *args)
+struct rpc_clnt *rpc_create(struct rpc_create_args *args, struct cred *acred)
 {
 	struct rpc_xprt *xprt;
 	struct rpc_clnt *clnt;
@@ -278,7 +279,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
 		return clnt;
 
 	if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
-		int err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
+		int err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR, acred);
 		if (err != 0) {
 			rpc_shutdown_client(clnt);
 			return ERR_PTR(err);
@@ -432,6 +433,7 @@ rpc_release_client(struct rpc_clnt *clnt)
  * @old - old rpc_client
  * @program - rpc program to set
  * @vers - rpc program version
+ * @acred - the credentials to use
  *
  * Clones the rpc client and sets up a new RPC program. This is mainly
  * of use for enabling different RPC programs to share the same transport.
@@ -439,7 +441,8 @@ rpc_release_client(struct rpc_clnt *clnt)
  */
 struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
 				      struct rpc_program *program,
-				      int vers)
+				      int vers,
+				      struct cred *acred)
 {
 	struct rpc_clnt *clnt;
 	struct rpc_version *version;
@@ -456,7 +459,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
 	clnt->cl_prog     = program->number;
 	clnt->cl_vers     = version->number;
 	clnt->cl_stats    = program->stats;
-	err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
+	err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR, acred);
 	if (err != 0) {
 		rpc_shutdown_client(clnt);
 		clnt = ERR_PTR(err);
@@ -520,21 +523,22 @@ struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt,
 		struct rpc_message *msg,
 		int flags,
 		const struct rpc_call_ops *ops,
-		void *data)
+		void *data,
+		struct cred *acred)
 {
 	struct rpc_task *task, *ret;
 	sigset_t oldset;
 
-	task = rpc_new_task(clnt, flags, ops, data);
+	task = rpc_new_task(clnt, flags, ops, data, acred);
 	if (task == NULL) {
-		rpc_release_calldata(ops, data);
+		rpc_release_calldata(ops, data, acred);
 		return ERR_PTR(-ENOMEM);
 	}
 
 	/* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */
 	rpc_task_sigmask(task, &oldset);
 	if (msg != NULL) {
-		rpc_call_setup(task, msg, 0, current->cred);
+		rpc_call_setup(task, msg, 0, acred);
 		if (task->tk_status != 0) {
 			ret = ERR_PTR(task->tk_status);
 			rpc_put_task(task);
@@ -554,15 +558,17 @@ out:
  * @clnt: pointer to RPC client
  * @msg: RPC call parameters
  * @flags: RPC call flags
+ * @acred: the credentials to use
  */
-int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
+int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
+		  struct cred *acred)
 {
 	struct rpc_task	*task;
 	int status;
 
 	BUG_ON(flags & RPC_TASK_ASYNC);
 
-	task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL);
+	task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL, acred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	status = task->tk_status;
@@ -577,14 +583,17 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
  * @flags: RPC call flags
  * @ops: RPC call ops
  * @data: user call data
+ * @acred: the credentials to use
  */
 int
 rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
-	       const struct rpc_call_ops *tk_ops, void *data)
+	       const struct rpc_call_ops *tk_ops, void *data,
+	       struct cred *acred)
 {
 	struct rpc_task	*task;
 
-	task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data);
+	task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data,
+			       acred);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
 	rpc_put_task(task);
@@ -597,12 +606,13 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
  * @flags: RPC flags
  * @ops: RPC call ops
  * @data: user call data
+ * @acred: the credentials to use
  */
 struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
 					const struct rpc_call_ops *tk_ops,
-					void *data)
+					void *data, struct cred *acred)
 {
-	return rpc_do_run_task(clnt, NULL, flags, tk_ops, data);
+	return rpc_do_run_task(clnt, NULL, flags, tk_ops, data, acred);
 }
 EXPORT_SYMBOL(rpc_run_task);
 
@@ -1485,25 +1495,27 @@ static struct rpc_procinfo rpcproc_null = {
 	.p_decode = rpcproc_decode_null,
 };
 
-static int rpc_ping(struct rpc_clnt *clnt, int flags)
+static int rpc_ping(struct rpc_clnt *clnt, int flags, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &rpcproc_null,
 	};
 	int err;
 	msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
-	err = rpc_call_sync(clnt, &msg, flags);
+	err = rpc_call_sync(clnt, &msg, flags, acred);
 	put_rpccred(msg.rpc_cred);
 	return err;
 }
 
-struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags)
+struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
+			       int flags, struct cred *acred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &rpcproc_null,
 		.rpc_cred = cred,
 	};
-	return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL);
+	return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL,
+			       acred);
 }
 EXPORT_SYMBOL(rpc_call_null);
 
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 82a863c..0a2404e 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -155,7 +155,7 @@ static void rpcb_getport_prepare(struct rpc_task *task, void *calldata)
 	rpc_call_setup(task, &msg, 0, task->tk_acred);
 }
 
-static void rpcb_map_release(void *data)
+static void rpcb_map_release(struct cred *acred, void *data)
 {
 	struct rpcbind_args *map = data;
 
@@ -193,7 +193,7 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
 	((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
 	if (!privileged)
 		args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
-	return rpc_create(&args);
+	return rpc_create(&args, &init_cred);
 }
 
 /**
@@ -238,7 +238,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
 	if (IS_ERR(rpcb_clnt))
 		return PTR_ERR(rpcb_clnt);
 
-	error = rpc_call_sync(rpcb_clnt, &msg, 0);
+	error = rpc_call_sync(rpcb_clnt, &msg, 0, &init_cred);
 
 	rpc_shutdown_client(rpcb_clnt);
 	if (error < 0)
@@ -287,7 +287,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog,
 	if (IS_ERR(rpcb_clnt))
 		return PTR_ERR(rpcb_clnt);
 
-	status = rpc_call_sync(rpcb_clnt, &msg, 0);
+	status = rpc_call_sync(rpcb_clnt, &msg, 0, &init_cred);
 	rpc_shutdown_client(rpcb_clnt);
 
 	if (status >= 0) {
@@ -374,7 +374,8 @@ void rpcb_getport_async(struct rpc_task *task)
 	map->r_owner = RPCB_OWNER_STRING;	/* ignored for GETADDR */
 
 	rpc_peeraddr(clnt, (void *)&addr, sizeof(addr));
-	rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0);
+	rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot,
+				bind_version, 0);
 	if (IS_ERR(rpcb_clnt)) {
 		status = PTR_ERR(rpcb_clnt);
 		dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
@@ -382,7 +383,8 @@ void rpcb_getport_async(struct rpc_task *task)
 		goto bailout;
 	}
 
-	child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map);
+	child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map,
+			     &init_cred);
 	rpc_release_client(rpcb_clnt);
 	if (IS_ERR(child)) {
 		status = -EIO;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index d9d4219..510ac24 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -616,11 +616,12 @@ void rpc_exit_task(struct rpc_task *task)
 }
 EXPORT_SYMBOL(rpc_exit_task);
 
-void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
+void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata,
+			  struct cred *acred)
 {
 	if (ops->rpc_release != NULL) {
 		lock_kernel();
-		ops->rpc_release(calldata);
+		ops->rpc_release(acred, calldata);
 		unlock_kernel();
 	}
 }
@@ -806,10 +807,10 @@ void rpc_free(void *buffer)
 /*
  * Creation and deletion of RPC task structures
  */
-void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
+void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags,
+		   const struct rpc_call_ops *tk_ops, void *calldata,
+		   struct cred *acred)
 {
-	struct cred *acred = current->cred;
-
 	memset(task, 0, sizeof(*task));
 	init_timer(&task->tk_timer);
 	task->tk_timer.data     = (unsigned long) task;
@@ -867,7 +868,9 @@ static void rpc_free_task(struct rcu_head *rcu)
 /*
  * Create a new task for the specified client.
  */
-struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
+struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags,
+			      const struct rpc_call_ops *tk_ops, void *calldata,
+			      struct cred *acred)
 {
 	struct rpc_task	*task;
 
@@ -875,7 +878,7 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
 	if (!task)
 		goto out;
 
-	rpc_init_task(task, clnt, flags, tk_ops, calldata);
+	rpc_init_task(task, clnt, flags, tk_ops, calldata, acred);
 
 	dprintk("RPC:       allocated task %p\n", task);
 	task->tk_flags |= RPC_TASK_DYNAMIC;
@@ -887,6 +890,7 @@ out:
 void rpc_put_task(struct rpc_task *task)
 {
 	const struct rpc_call_ops *tk_ops = task->tk_ops;
+	struct cred *acred = task->tk_acred;
 	void *calldata = task->tk_calldata;
 
 	if (!atomic_dec_and_test(&task->tk_count))
@@ -900,10 +904,10 @@ void rpc_put_task(struct rpc_task *task)
 		rpc_release_client(task->tk_client);
 		task->tk_client = NULL;
 	}
-	put_cred(task->tk_acred);
 	if (task->tk_flags & RPC_TASK_DYNAMIC)
 		call_rcu_bh(&task->u.tk_rcu, rpc_free_task);
-	rpc_release_calldata(tk_ops, calldata);
+	rpc_release_calldata(tk_ops, calldata, acred);
+	put_cred(acred);
 }
 EXPORT_SYMBOL(rpc_put_task);
 
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 55ea6df..b84573c 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -435,7 +435,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize,
 
 struct svc_serv *
 svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
-		void (*shutdown)(struct svc_serv *serv),
+		  void (*shutdown)(struct svc_serv *serv),
 		  svc_thread_fn func, int sig, struct module *mod)
 {
 	struct svc_serv *serv;
@@ -757,7 +757,8 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
 			if (progp->pg_vers[i]->vs_hidden)
 				continue;
 
-			error = rpcb_register(progp->pg_prog, i, proto, port, &dummy);
+			error = rpcb_register(progp->pg_prog, i, proto, port,
+					      &dummy);
 			if (error < 0)
 				break;
 			if (port && !dummy) {

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ