diff mbox

[4/8] sunrpc/auth: add 'rcu_walk' arg to rpc_lookup_cred.

Message ID 20140306165004.46c0d59e@notabene.brown (mailing list archive)
State New, archived
Headers show

Commit Message

NeilBrown March 6, 2014, 5:50 a.m. UTC
On Wed, 5 Mar 2014 09:43:03 -0500 Trond Myklebust
<trond.myklebust@primarydata.com> wrote:

> 
> On Mar 4, 2014, at 22:00, NeilBrown <neilb@suse.de> wrote:
> 
> > This arg causes rpc_lookup_cred to set RPCAUTH_LOOKUP_RCU when
> > performing the credential lookup.  Most callers pass '0',
> > except nfs_permission() which passes (mask & MAY_NOT_BLOCK).
> > 
> 
> Why not just add a function rpc_lookup_cred_rcu() or rpc_lookup_cred_noblock() to cater for that one exception?

That certainly makes the patch smaller, and is probably a net win.

Thanks.
NeilBrown

From b805a8f79a5527676b96b9654dd26d1b5bc03691 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 4 Mar 2014 15:28:43 +1100
Subject: [PATCH] sunrpc/auth: add rpc_lookup_cred_nonblock

This version of rpc_lookup_cred  sets RPCAUTH_LOOKUP_RCU when
performing the credential lookup.
nfs_permission() uses it in RCU-walk mode.

This doesn't speed up nfs_permission yet as it is not yet
safe to call nfs_do_access with the returned cred.

Signed-off-by: NeilBrown <neilb@suse.de>
diff mbox

Patch

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7530acdc5c42..ede873e88acc 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2318,10 +2318,12 @@  force_lookup:
 		goto out_notsup;
 
 	if (mask & MAY_NOT_BLOCK)
-		return -ECHILD;
-
-	cred = rpc_lookup_cred();
+		cred = rpc_lookup_cred_nonblock();
+	else
+		cred = rpc_lookup_cred();
 	if (!IS_ERR(cred)) {
+		if (mask & MAY_NOT_BLOCK)
+			return -ECHILD;
 		res = nfs_do_access(inode, cred, mask);
 		put_rpccred(cred);
 	} else
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 3f158ae1d6fd..28ffc8476875 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -154,6 +154,7 @@  void			rpc_destroy_generic_auth(void);
 void 			rpc_destroy_authunix(void);
 
 struct rpc_cred *	rpc_lookup_cred(void);
+struct rpc_cred *	rpc_lookup_cred_nonblock(void);
 struct rpc_cred *	rpc_lookup_machine_cred(const char *service_name);
 int			rpcauth_register(const struct rpc_authops *);
 int			rpcauth_unregister(const struct rpc_authops *);
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index ed04869b2d4f..632f6eec8111 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -38,6 +38,11 @@  struct rpc_cred *rpc_lookup_cred(void)
 }
 EXPORT_SYMBOL_GPL(rpc_lookup_cred);
 
+struct rpc_cred *rpc_lookup_cred_nonblock(void)
+{
+	return rpcauth_lookupcred(&generic_auth, 1);
+}
+
 /*
  * Public call interface for looking up machine creds.
  */