diff options
author | Jeff Layton <jlayton@redhat.com> | 2014-01-04 07:18:03 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-01-06 15:14:16 -0500 |
commit | 1654a04cd702fd19c297c36300a6ab834cf8c072 (patch) | |
tree | d8d4a040c6614baa92b735a6b96dce962541cae7 /net | |
parent | 73ca65904c5abaa29b8d9699089292239564300f (diff) |
sunrpc: don't wait for write before allowing reads from use-gss-proxy file
It doesn't make much sense to make reads from this procfile hang. As
far as I can tell, only gssproxy itself will open this file and it
never reads from it. Change it to just give the present setting of
sn->use_gss_proxy without waiting for anything.
Note that we do not want to call use_gss_proxy() in this codepath
since an inopportune read of this file could cause it to be disabled
prematurely.
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_upcall.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 33 | ||||
-rw-r--r-- | net/sunrpc/netns.h | 1 |
3 files changed, 2 insertions, 34 deletions
diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index 458f85e9b0ba..abbb7dcd1689 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c | |||
@@ -137,7 +137,6 @@ void init_gssp_clnt(struct sunrpc_net *sn) | |||
137 | { | 137 | { |
138 | mutex_init(&sn->gssp_lock); | 138 | mutex_init(&sn->gssp_lock); |
139 | sn->gssp_clnt = NULL; | 139 | sn->gssp_clnt = NULL; |
140 | init_waitqueue_head(&sn->gssp_wq); | ||
141 | } | 140 | } |
142 | 141 | ||
143 | int set_gssp_clnt(struct net *net) | 142 | int set_gssp_clnt(struct net *net) |
@@ -154,7 +153,6 @@ int set_gssp_clnt(struct net *net) | |||
154 | sn->gssp_clnt = clnt; | 153 | sn->gssp_clnt = clnt; |
155 | } | 154 | } |
156 | mutex_unlock(&sn->gssp_lock); | 155 | mutex_unlock(&sn->gssp_lock); |
157 | wake_up(&sn->gssp_wq); | ||
158 | return ret; | 156 | return ret; |
159 | } | 157 | } |
160 | 158 | ||
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 008cdade5aae..1b94a9c8a242 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -1295,34 +1295,9 @@ static int set_gss_proxy(struct net *net, int type) | |||
1295 | else | 1295 | else |
1296 | ret = -EBUSY; | 1296 | ret = -EBUSY; |
1297 | spin_unlock(&use_gssp_lock); | 1297 | spin_unlock(&use_gssp_lock); |
1298 | wake_up(&sn->gssp_wq); | ||
1299 | return ret; | 1298 | return ret; |
1300 | } | 1299 | } |
1301 | 1300 | ||
1302 | static inline bool gssp_ready(struct sunrpc_net *sn) | ||
1303 | { | ||
1304 | switch (sn->use_gss_proxy) { | ||
1305 | case -1: | ||
1306 | return false; | ||
1307 | case 0: | ||
1308 | return true; | ||
1309 | case 1: | ||
1310 | return sn->gssp_clnt; | ||
1311 | } | ||
1312 | WARN_ON_ONCE(1); | ||
1313 | return false; | ||
1314 | } | ||
1315 | |||
1316 | static int wait_for_gss_proxy(struct net *net, struct file *file) | ||
1317 | { | ||
1318 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1319 | |||
1320 | if (file->f_flags & O_NONBLOCK && !gssp_ready(sn)) | ||
1321 | return -EAGAIN; | ||
1322 | return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn)); | ||
1323 | } | ||
1324 | |||
1325 | |||
1326 | static ssize_t write_gssp(struct file *file, const char __user *buf, | 1301 | static ssize_t write_gssp(struct file *file, const char __user *buf, |
1327 | size_t count, loff_t *ppos) | 1302 | size_t count, loff_t *ppos) |
1328 | { | 1303 | { |
@@ -1355,16 +1330,12 @@ static ssize_t read_gssp(struct file *file, char __user *buf, | |||
1355 | size_t count, loff_t *ppos) | 1330 | size_t count, loff_t *ppos) |
1356 | { | 1331 | { |
1357 | struct net *net = PDE_DATA(file_inode(file)); | 1332 | struct net *net = PDE_DATA(file_inode(file)); |
1333 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1358 | unsigned long p = *ppos; | 1334 | unsigned long p = *ppos; |
1359 | char tbuf[10]; | 1335 | char tbuf[10]; |
1360 | size_t len; | 1336 | size_t len; |
1361 | int ret; | ||
1362 | |||
1363 | ret = wait_for_gss_proxy(net, file); | ||
1364 | if (ret) | ||
1365 | return ret; | ||
1366 | 1337 | ||
1367 | snprintf(tbuf, sizeof(tbuf), "%d\n", use_gss_proxy(net)); | 1338 | snprintf(tbuf, sizeof(tbuf), "%d\n", sn->use_gss_proxy); |
1368 | len = strlen(tbuf); | 1339 | len = strlen(tbuf); |
1369 | if (p >= len) | 1340 | if (p >= len) |
1370 | return 0; | 1341 | return 0; |
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h index 779742cfc1ff..3a260e47fad2 100644 --- a/net/sunrpc/netns.h +++ b/net/sunrpc/netns.h | |||
@@ -26,7 +26,6 @@ struct sunrpc_net { | |||
26 | unsigned int rpcb_is_af_local : 1; | 26 | unsigned int rpcb_is_af_local : 1; |
27 | 27 | ||
28 | struct mutex gssp_lock; | 28 | struct mutex gssp_lock; |
29 | wait_queue_head_t gssp_wq; | ||
30 | struct rpc_clnt *gssp_clnt; | 29 | struct rpc_clnt *gssp_clnt; |
31 | int use_gss_proxy; | 30 | int use_gss_proxy; |
32 | int pipe_version; | 31 | int pipe_version; |