diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 46 | ||||
| -rw-r--r-- | net/sunrpc/netns.h | 2 | ||||
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 1 |
3 files changed, 30 insertions, 19 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 3aff72f78bf2..fc2f78d6a9b4 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -87,8 +87,6 @@ struct gss_auth { | |||
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | /* pipe_version >= 0 if and only if someone has a pipe open. */ | 89 | /* pipe_version >= 0 if and only if someone has a pipe open. */ |
| 90 | static int pipe_version = -1; | ||
| 91 | static atomic_t pipe_users = ATOMIC_INIT(0); | ||
| 92 | static DEFINE_SPINLOCK(pipe_version_lock); | 90 | static DEFINE_SPINLOCK(pipe_version_lock); |
| 93 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; | 91 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; |
| 94 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); | 92 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); |
| @@ -268,24 +266,27 @@ struct gss_upcall_msg { | |||
| 268 | char databuf[UPCALL_BUF_LEN]; | 266 | char databuf[UPCALL_BUF_LEN]; |
| 269 | }; | 267 | }; |
| 270 | 268 | ||
| 271 | static int get_pipe_version(void) | 269 | static int get_pipe_version(struct net *net) |
| 272 | { | 270 | { |
| 271 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
| 273 | int ret; | 272 | int ret; |
| 274 | 273 | ||
| 275 | spin_lock(&pipe_version_lock); | 274 | spin_lock(&pipe_version_lock); |
| 276 | if (pipe_version >= 0) { | 275 | if (sn->pipe_version >= 0) { |
| 277 | atomic_inc(&pipe_users); | 276 | atomic_inc(&sn->pipe_users); |
| 278 | ret = pipe_version; | 277 | ret = sn->pipe_version; |
| 279 | } else | 278 | } else |
| 280 | ret = -EAGAIN; | 279 | ret = -EAGAIN; |
| 281 | spin_unlock(&pipe_version_lock); | 280 | spin_unlock(&pipe_version_lock); |
| 282 | return ret; | 281 | return ret; |
| 283 | } | 282 | } |
| 284 | 283 | ||
| 285 | static void put_pipe_version(void) | 284 | static void put_pipe_version(struct net *net) |
| 286 | { | 285 | { |
| 287 | if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) { | 286 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
| 288 | pipe_version = -1; | 287 | |
| 288 | if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) { | ||
| 289 | sn->pipe_version = -1; | ||
| 289 | spin_unlock(&pipe_version_lock); | 290 | spin_unlock(&pipe_version_lock); |
| 290 | } | 291 | } |
| 291 | } | 292 | } |
| @@ -293,9 +294,10 @@ static void put_pipe_version(void) | |||
| 293 | static void | 294 | static void |
| 294 | gss_release_msg(struct gss_upcall_msg *gss_msg) | 295 | gss_release_msg(struct gss_upcall_msg *gss_msg) |
| 295 | { | 296 | { |
| 297 | struct net *net = rpc_net_ns(gss_msg->auth->client); | ||
| 296 | if (!atomic_dec_and_test(&gss_msg->count)) | 298 | if (!atomic_dec_and_test(&gss_msg->count)) |
| 297 | return; | 299 | return; |
| 298 | put_pipe_version(); | 300 | put_pipe_version(net); |
| 299 | BUG_ON(!list_empty(&gss_msg->list)); | 301 | BUG_ON(!list_empty(&gss_msg->list)); |
| 300 | if (gss_msg->ctx != NULL) | 302 | if (gss_msg->ctx != NULL) |
| 301 | gss_put_ctx(gss_msg->ctx); | 303 | gss_put_ctx(gss_msg->ctx); |
| @@ -441,7 +443,10 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg, | |||
| 441 | struct rpc_clnt *clnt, | 443 | struct rpc_clnt *clnt, |
| 442 | const char *service_name) | 444 | const char *service_name) |
| 443 | { | 445 | { |
| 444 | if (pipe_version == 0) | 446 | struct net *net = rpc_net_ns(clnt); |
| 447 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
| 448 | |||
| 449 | if (sn->pipe_version == 0) | ||
| 445 | gss_encode_v0_msg(gss_msg); | 450 | gss_encode_v0_msg(gss_msg); |
| 446 | else /* pipe_version == 1 */ | 451 | else /* pipe_version == 1 */ |
| 447 | gss_encode_v1_msg(gss_msg, clnt, service_name); | 452 | gss_encode_v1_msg(gss_msg, clnt, service_name); |
| @@ -457,7 +462,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, | |||
| 457 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); | 462 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); |
| 458 | if (gss_msg == NULL) | 463 | if (gss_msg == NULL) |
| 459 | return ERR_PTR(-ENOMEM); | 464 | return ERR_PTR(-ENOMEM); |
| 460 | vers = get_pipe_version(); | 465 | vers = get_pipe_version(rpc_net_ns(clnt)); |
| 461 | if (vers < 0) { | 466 | if (vers < 0) { |
| 462 | kfree(gss_msg); | 467 | kfree(gss_msg); |
| 463 | return ERR_PTR(vers); | 468 | return ERR_PTR(vers); |
| @@ -581,8 +586,8 @@ retry: | |||
| 581 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); | 586 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); |
| 582 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 587 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
| 583 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, | 588 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, |
| 584 | pipe_version >= 0, timeout); | 589 | sn->pipe_version >= 0, timeout); |
| 585 | if (pipe_version < 0) { | 590 | if (sn->pipe_version < 0) { |
| 586 | if (err == 0) | 591 | if (err == 0) |
| 587 | sn->gssd_running = 0; | 592 | sn->gssd_running = 0; |
| 588 | warn_gssd(); | 593 | warn_gssd(); |
| @@ -719,20 +724,22 @@ out: | |||
| 719 | 724 | ||
| 720 | static int gss_pipe_open(struct inode *inode, int new_version) | 725 | static int gss_pipe_open(struct inode *inode, int new_version) |
| 721 | { | 726 | { |
| 727 | struct net *net = inode->i_sb->s_fs_info; | ||
| 728 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
| 722 | int ret = 0; | 729 | int ret = 0; |
| 723 | 730 | ||
| 724 | spin_lock(&pipe_version_lock); | 731 | spin_lock(&pipe_version_lock); |
| 725 | if (pipe_version < 0) { | 732 | if (sn->pipe_version < 0) { |
| 726 | /* First open of any gss pipe determines the version: */ | 733 | /* First open of any gss pipe determines the version: */ |
| 727 | pipe_version = new_version; | 734 | sn->pipe_version = new_version; |
| 728 | rpc_wake_up(&pipe_version_rpc_waitqueue); | 735 | rpc_wake_up(&pipe_version_rpc_waitqueue); |
| 729 | wake_up(&pipe_version_waitqueue); | 736 | wake_up(&pipe_version_waitqueue); |
| 730 | } else if (pipe_version != new_version) { | 737 | } else if (sn->pipe_version != new_version) { |
| 731 | /* Trying to open a pipe of a different version */ | 738 | /* Trying to open a pipe of a different version */ |
| 732 | ret = -EBUSY; | 739 | ret = -EBUSY; |
| 733 | goto out; | 740 | goto out; |
| 734 | } | 741 | } |
| 735 | atomic_inc(&pipe_users); | 742 | atomic_inc(&sn->pipe_users); |
| 736 | out: | 743 | out: |
| 737 | spin_unlock(&pipe_version_lock); | 744 | spin_unlock(&pipe_version_lock); |
| 738 | return ret; | 745 | return ret; |
| @@ -752,6 +759,7 @@ static int gss_pipe_open_v1(struct inode *inode) | |||
| 752 | static void | 759 | static void |
| 753 | gss_pipe_release(struct inode *inode) | 760 | gss_pipe_release(struct inode *inode) |
| 754 | { | 761 | { |
| 762 | struct net *net = inode->i_sb->s_fs_info; | ||
| 755 | struct rpc_pipe *pipe = RPC_I(inode)->pipe; | 763 | struct rpc_pipe *pipe = RPC_I(inode)->pipe; |
| 756 | struct gss_upcall_msg *gss_msg; | 764 | struct gss_upcall_msg *gss_msg; |
| 757 | 765 | ||
| @@ -770,7 +778,7 @@ restart: | |||
| 770 | } | 778 | } |
| 771 | spin_unlock(&pipe->lock); | 779 | spin_unlock(&pipe->lock); |
| 772 | 780 | ||
| 773 | put_pipe_version(); | 781 | put_pipe_version(net); |
| 774 | } | 782 | } |
| 775 | 783 | ||
| 776 | static void | 784 | static void |
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h index 0827f641e8d7..74d948f5d5a1 100644 --- a/net/sunrpc/netns.h +++ b/net/sunrpc/netns.h | |||
| @@ -28,6 +28,8 @@ struct sunrpc_net { | |||
| 28 | wait_queue_head_t gssp_wq; | 28 | wait_queue_head_t gssp_wq; |
| 29 | struct rpc_clnt *gssp_clnt; | 29 | struct rpc_clnt *gssp_clnt; |
| 30 | int use_gss_proxy; | 30 | int use_gss_proxy; |
| 31 | int pipe_version; | ||
| 32 | atomic_t pipe_users; | ||
| 31 | struct proc_dir_entry *use_gssp_proc; | 33 | struct proc_dir_entry *use_gssp_proc; |
| 32 | 34 | ||
| 33 | unsigned int gssd_running; | 35 | unsigned int gssd_running; |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index a370762e459d..e7ce4b3eb0bd 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -1073,6 +1073,7 @@ void rpc_pipefs_init_net(struct net *net) | |||
| 1073 | 1073 | ||
| 1074 | mutex_init(&sn->pipefs_sb_lock); | 1074 | mutex_init(&sn->pipefs_sb_lock); |
| 1075 | sn->gssd_running = 1; | 1075 | sn->gssd_running = 1; |
| 1076 | sn->pipe_version = -1; | ||
| 1076 | } | 1077 | } |
| 1077 | 1078 | ||
| 1078 | /* | 1079 | /* |
