Pass credentials into rpc_init_task().
Signed-off-by: David Howells <dhowells@redhat.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(¤t->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(¤t->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(¤t->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 =
| Maciej Rutecki | [2.6.26.*] boot problem (ahci/irq related?) |
| Chuck Ebbert | Why do so many machines need "noapic"? |
| Tony Lindgren | [PATCH 32/90] ARM: OMAP: Basic support for siemens sx1 |
| Renato S. Yamane | Error -71 on device descriptor read/all |
git: | |
| Francis Moreau | What about git cp ? |
| Elijah Newren | Trying to use git-filter-branch to compress history by removing large, obsolete bi... |
| James B. Byrne | GiT and CentOS 5.2 |
| Matthieu Moy | git push to a non-bare repository |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Jim Razmus | Re: Trouble ticket system suggestions |
| Calomel | Re: Light HTTP servers. |
| Brian Keefer | Re: Testing in a virtual environment |
| Matt Mackall | [PATCH] Stop scaring users with "treason uncloaked!" |
| Kunsheng Chen | Is there any function similar to inet_ntoa() in Kernel or NetFilter ? |
| Saverio Mascolo | TCP default congestion control in linux should be newreno |
| Johann Baudy | [PATCH] Packet socket: mmapped IO: PACKET_TX_RING |
