b51f668
Bugzilla: N/A
b51f668
Upstream-status: queued in NFS git tree (for 3.13/3.14?)
65bda0b
65bda0b
Now that we have a more reliable method to tell if gssd is running, we
65bda0b
can replace the sn->gssd_running flag with a function that will query to
65bda0b
see if it's up and running.
65bda0b
65bda0b
There's also no need to attempt an upcall that we know will fail, so
65bda0b
just return -EACCES if gssd isn't running. Finally, fix the warn_gss()
65bda0b
message not to claim that that the upcall timed out since we don't
65bda0b
necesarily perform one now when gssd isn't running, and remove the
65bda0b
extraneous newline from the message.
65bda0b
65bda0b
Signed-off-by: Jeff Layton <jlayton@redhat.com>
65bda0b
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
65bda0b
---
65bda0b
 Fixed up to apply to 3.12.1 by Josh Boyer <jwboyer@fedoraproject.org>
65bda0b
65bda0b
 include/linux/sunrpc/rpc_pipe_fs.h |    2 ++
65bda0b
 net/sunrpc/auth_gss/auth_gss.c     |   17 +++++++----------
65bda0b
 net/sunrpc/netns.h                 |    2 --
65bda0b
 net/sunrpc/rpc_pipe.c              |   14 ++++++++++----
65bda0b
 4 files changed, 19 insertions(+), 16 deletions(-)
65bda0b
65bda0b
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
65bda0b
index 85f1342..7f490be 100644
65bda0b
--- a/include/linux/sunrpc/rpc_pipe_fs.h
65bda0b
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
65bda0b
@@ -131,5 +131,7 @@ extern int rpc_unlink(struct dentry *);
65bda0b
 extern int register_rpc_pipefs(void);
65bda0b
 extern void unregister_rpc_pipefs(void);
65bda0b
 
65bda0b
+extern bool gssd_running(struct net *net);
65bda0b
+
65bda0b
 #endif
65bda0b
 #endif
65bda0b
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
65bda0b
index 0846566..1ada878 100644
65bda0b
--- a/net/sunrpc/auth_gss/auth_gss.c
65bda0b
+++ b/net/sunrpc/auth_gss/auth_gss.c
65bda0b
@@ -517,8 +517,7 @@ static void warn_gssd(void)
65bda0b
 	unsigned long now = jiffies;
65bda0b
 
65bda0b
 	if (time_after(now, ratelimit)) {
65bda0b
-		printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
65bda0b
-				"Please check user daemon is running.\n");
65bda0b
+		pr_warn("RPC: AUTH_GSS upcall failed. Please check user daemon is running.\n");
65bda0b
 		ratelimit = now + 15*HZ;
65bda0b
 	}
65bda0b
 }
65bda0b
@@ -581,7 +580,6 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
65bda0b
 	struct rpc_pipe *pipe;
65bda0b
 	struct rpc_cred *cred = &gss_cred->gc_base;
65bda0b
 	struct gss_upcall_msg *gss_msg;
65bda0b
-	unsigned long timeout;
65bda0b
 	DEFINE_WAIT(wait);
65bda0b
 	int err;
65bda0b
 
65bda0b
@@ -589,17 +587,16 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
65bda0b
 		__func__, from_kuid(&init_user_ns, cred->cr_uid));
65bda0b
 retry:
65bda0b
 	err = 0;
65bda0b
-	/* Default timeout is 15s unless we know that gssd is not running */
65bda0b
-	timeout = 15 * HZ;
65bda0b
-	if (!sn->gssd_running)
65bda0b
-		timeout = HZ >> 2;
65bda0b
+	/* if gssd is down, just skip upcalling altogether */
65bda0b
+	if (!gssd_running(net)) {
65bda0b
+		warn_gssd();
65bda0b
+		return -EACCES;
65bda0b
+	}
65bda0b
 	gss_msg = gss_setup_upcall(gss_auth, cred);
65bda0b
 	if (PTR_ERR(gss_msg) == -EAGAIN) {
65bda0b
 		err = wait_event_interruptible_timeout(pipe_version_waitqueue,
65bda0b
-				sn->pipe_version >= 0, timeout);
65bda0b
+				sn->pipe_version >= 0, 15 * HZ);
65bda0b
 		if (sn->pipe_version < 0) {
65bda0b
-			if (err == 0)
65bda0b
-				sn->gssd_running = 0;
65bda0b
 			warn_gssd();
65bda0b
 			err = -EACCES;
65bda0b
 		}
65bda0b
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
65bda0b
index 8a8e841..94e506f 100644
65bda0b
--- a/net/sunrpc/netns.h
65bda0b
+++ b/net/sunrpc/netns.h
65bda0b
@@ -33,8 +33,6 @@ struct sunrpc_net {
65bda0b
 	int pipe_version;
65bda0b
 	atomic_t pipe_users;
65bda0b
 	struct proc_dir_entry *use_gssp_proc;
65bda0b
-
65bda0b
-	unsigned int gssd_running;
65bda0b
 };
65bda0b
 
65bda0b
 extern int sunrpc_net_id;
65bda0b
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
65bda0b
index 40aef18..ad444f3 100644
65bda0b
--- a/net/sunrpc/rpc_pipe.c
65bda0b
+++ b/net/sunrpc/rpc_pipe.c
65bda0b
@@ -216,14 +216,11 @@ rpc_destroy_inode(struct inode *inode)
65bda0b
 static int
65bda0b
 rpc_pipe_open(struct inode *inode, struct file *filp)
65bda0b
 {
65bda0b
-	struct net *net = inode->i_sb->s_fs_info;
65bda0b
-	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
65bda0b
 	struct rpc_pipe *pipe;
65bda0b
 	int first_open;
65bda0b
 	int res = -ENXIO;
65bda0b
 
65bda0b
 	mutex_lock(&inode->i_mutex);
65bda0b
-	sn->gssd_running = 1;
65bda0b
 	pipe = RPC_I(inode)->pipe;
65bda0b
 	if (pipe == NULL)
65bda0b
 		goto out;
65bda0b
@@ -1231,7 +1228,6 @@ int rpc_pipefs_init_net(struct net *net)
65bda0b
 		return PTR_ERR(sn->gssd_dummy);
65bda0b
 
65bda0b
 	mutex_init(&sn->pipefs_sb_lock);
65bda0b
-	sn->gssd_running = 1;
65bda0b
 	sn->pipe_version = -1;
65bda0b
 	return 0;
65bda0b
 }
65bda0b
@@ -1385,6 +1381,16 @@ err_depopulate:
65bda0b
 	return err;
65bda0b
 }
65bda0b
 
65bda0b
+bool
65bda0b
+gssd_running(struct net *net)
65bda0b
+{
65bda0b
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
65bda0b
+	struct rpc_pipe *pipe = sn->gssd_dummy;
65bda0b
+
65bda0b
+	return pipe->nreaders || pipe->nwriters;
65bda0b
+}
65bda0b
+EXPORT_SYMBOL_GPL(gssd_running);
65bda0b
+
65bda0b
 static struct dentry *
65bda0b
 rpc_mount(struct file_system_type *fs_type,
65bda0b
 		int flags, const char *dev_name, void *data)