diff options
Diffstat (limited to 'net/sunrpc/auth_gss/auth_gss.c')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 216 |
1 files changed, 154 insertions, 62 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index affa631ac1ab..d3ad81f8da5b 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -81,7 +81,7 @@ struct gss_auth { | |||
81 | * mechanism (for example, "krb5") and exists for | 81 | * mechanism (for example, "krb5") and exists for |
82 | * backwards-compatibility with older gssd's. | 82 | * backwards-compatibility with older gssd's. |
83 | */ | 83 | */ |
84 | struct dentry *dentry[2]; | 84 | struct rpc_pipe *pipe[2]; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* pipe_version >= 0 if and only if someone has a pipe open. */ | 87 | /* pipe_version >= 0 if and only if someone has a pipe open. */ |
@@ -112,7 +112,7 @@ gss_put_ctx(struct gss_cl_ctx *ctx) | |||
112 | /* gss_cred_set_ctx: | 112 | /* gss_cred_set_ctx: |
113 | * called by gss_upcall_callback and gss_create_upcall in order | 113 | * called by gss_upcall_callback and gss_create_upcall in order |
114 | * to set the gss context. The actual exchange of an old context | 114 | * to set the gss context. The actual exchange of an old context |
115 | * and a new one is protected by the inode->i_lock. | 115 | * and a new one is protected by the pipe->lock. |
116 | */ | 116 | */ |
117 | static void | 117 | static void |
118 | gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) | 118 | gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) |
@@ -251,7 +251,7 @@ struct gss_upcall_msg { | |||
251 | struct rpc_pipe_msg msg; | 251 | struct rpc_pipe_msg msg; |
252 | struct list_head list; | 252 | struct list_head list; |
253 | struct gss_auth *auth; | 253 | struct gss_auth *auth; |
254 | struct rpc_inode *inode; | 254 | struct rpc_pipe *pipe; |
255 | struct rpc_wait_queue rpc_waitqueue; | 255 | struct rpc_wait_queue rpc_waitqueue; |
256 | wait_queue_head_t waitqueue; | 256 | wait_queue_head_t waitqueue; |
257 | struct gss_cl_ctx *ctx; | 257 | struct gss_cl_ctx *ctx; |
@@ -294,10 +294,10 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
294 | } | 294 | } |
295 | 295 | ||
296 | static struct gss_upcall_msg * | 296 | static struct gss_upcall_msg * |
297 | __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | 297 | __gss_find_upcall(struct rpc_pipe *pipe, uid_t uid) |
298 | { | 298 | { |
299 | struct gss_upcall_msg *pos; | 299 | struct gss_upcall_msg *pos; |
300 | list_for_each_entry(pos, &rpci->in_downcall, list) { | 300 | list_for_each_entry(pos, &pipe->in_downcall, list) { |
301 | if (pos->uid != uid) | 301 | if (pos->uid != uid) |
302 | continue; | 302 | continue; |
303 | atomic_inc(&pos->count); | 303 | atomic_inc(&pos->count); |
@@ -315,18 +315,17 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | |||
315 | static inline struct gss_upcall_msg * | 315 | static inline struct gss_upcall_msg * |
316 | gss_add_msg(struct gss_upcall_msg *gss_msg) | 316 | gss_add_msg(struct gss_upcall_msg *gss_msg) |
317 | { | 317 | { |
318 | struct rpc_inode *rpci = gss_msg->inode; | 318 | struct rpc_pipe *pipe = gss_msg->pipe; |
319 | struct inode *inode = &rpci->vfs_inode; | ||
320 | struct gss_upcall_msg *old; | 319 | struct gss_upcall_msg *old; |
321 | 320 | ||
322 | spin_lock(&inode->i_lock); | 321 | spin_lock(&pipe->lock); |
323 | old = __gss_find_upcall(rpci, gss_msg->uid); | 322 | old = __gss_find_upcall(pipe, gss_msg->uid); |
324 | if (old == NULL) { | 323 | if (old == NULL) { |
325 | atomic_inc(&gss_msg->count); | 324 | atomic_inc(&gss_msg->count); |
326 | list_add(&gss_msg->list, &rpci->in_downcall); | 325 | list_add(&gss_msg->list, &pipe->in_downcall); |
327 | } else | 326 | } else |
328 | gss_msg = old; | 327 | gss_msg = old; |
329 | spin_unlock(&inode->i_lock); | 328 | spin_unlock(&pipe->lock); |
330 | return gss_msg; | 329 | return gss_msg; |
331 | } | 330 | } |
332 | 331 | ||
@@ -342,14 +341,14 @@ __gss_unhash_msg(struct gss_upcall_msg *gss_msg) | |||
342 | static void | 341 | static void |
343 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) | 342 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) |
344 | { | 343 | { |
345 | struct inode *inode = &gss_msg->inode->vfs_inode; | 344 | struct rpc_pipe *pipe = gss_msg->pipe; |
346 | 345 | ||
347 | if (list_empty(&gss_msg->list)) | 346 | if (list_empty(&gss_msg->list)) |
348 | return; | 347 | return; |
349 | spin_lock(&inode->i_lock); | 348 | spin_lock(&pipe->lock); |
350 | if (!list_empty(&gss_msg->list)) | 349 | if (!list_empty(&gss_msg->list)) |
351 | __gss_unhash_msg(gss_msg); | 350 | __gss_unhash_msg(gss_msg); |
352 | spin_unlock(&inode->i_lock); | 351 | spin_unlock(&pipe->lock); |
353 | } | 352 | } |
354 | 353 | ||
355 | static void | 354 | static void |
@@ -376,11 +375,11 @@ gss_upcall_callback(struct rpc_task *task) | |||
376 | struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, | 375 | struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, |
377 | struct gss_cred, gc_base); | 376 | struct gss_cred, gc_base); |
378 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; | 377 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; |
379 | struct inode *inode = &gss_msg->inode->vfs_inode; | 378 | struct rpc_pipe *pipe = gss_msg->pipe; |
380 | 379 | ||
381 | spin_lock(&inode->i_lock); | 380 | spin_lock(&pipe->lock); |
382 | gss_handle_downcall_result(gss_cred, gss_msg); | 381 | gss_handle_downcall_result(gss_cred, gss_msg); |
383 | spin_unlock(&inode->i_lock); | 382 | spin_unlock(&pipe->lock); |
384 | task->tk_status = gss_msg->msg.errno; | 383 | task->tk_status = gss_msg->msg.errno; |
385 | gss_release_msg(gss_msg); | 384 | gss_release_msg(gss_msg); |
386 | } | 385 | } |
@@ -450,7 +449,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, | |||
450 | kfree(gss_msg); | 449 | kfree(gss_msg); |
451 | return ERR_PTR(vers); | 450 | return ERR_PTR(vers); |
452 | } | 451 | } |
453 | gss_msg->inode = RPC_I(gss_auth->dentry[vers]->d_inode); | 452 | gss_msg->pipe = gss_auth->pipe[vers]; |
454 | INIT_LIST_HEAD(&gss_msg->list); | 453 | INIT_LIST_HEAD(&gss_msg->list); |
455 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | 454 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); |
456 | init_waitqueue_head(&gss_msg->waitqueue); | 455 | init_waitqueue_head(&gss_msg->waitqueue); |
@@ -474,8 +473,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
474 | return gss_new; | 473 | return gss_new; |
475 | gss_msg = gss_add_msg(gss_new); | 474 | gss_msg = gss_add_msg(gss_new); |
476 | if (gss_msg == gss_new) { | 475 | if (gss_msg == gss_new) { |
477 | struct inode *inode = &gss_new->inode->vfs_inode; | 476 | int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); |
478 | int res = rpc_queue_upcall(inode, &gss_new->msg); | ||
479 | if (res) { | 477 | if (res) { |
480 | gss_unhash_msg(gss_new); | 478 | gss_unhash_msg(gss_new); |
481 | gss_msg = ERR_PTR(res); | 479 | gss_msg = ERR_PTR(res); |
@@ -506,7 +504,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
506 | struct gss_cred *gss_cred = container_of(cred, | 504 | struct gss_cred *gss_cred = container_of(cred, |
507 | struct gss_cred, gc_base); | 505 | struct gss_cred, gc_base); |
508 | struct gss_upcall_msg *gss_msg; | 506 | struct gss_upcall_msg *gss_msg; |
509 | struct inode *inode; | 507 | struct rpc_pipe *pipe; |
510 | int err = 0; | 508 | int err = 0; |
511 | 509 | ||
512 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, | 510 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, |
@@ -524,8 +522,8 @@ gss_refresh_upcall(struct rpc_task *task) | |||
524 | err = PTR_ERR(gss_msg); | 522 | err = PTR_ERR(gss_msg); |
525 | goto out; | 523 | goto out; |
526 | } | 524 | } |
527 | inode = &gss_msg->inode->vfs_inode; | 525 | pipe = gss_msg->pipe; |
528 | spin_lock(&inode->i_lock); | 526 | spin_lock(&pipe->lock); |
529 | if (gss_cred->gc_upcall != NULL) | 527 | if (gss_cred->gc_upcall != NULL) |
530 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); | 528 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); |
531 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { | 529 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { |
@@ -538,7 +536,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
538 | gss_handle_downcall_result(gss_cred, gss_msg); | 536 | gss_handle_downcall_result(gss_cred, gss_msg); |
539 | err = gss_msg->msg.errno; | 537 | err = gss_msg->msg.errno; |
540 | } | 538 | } |
541 | spin_unlock(&inode->i_lock); | 539 | spin_unlock(&pipe->lock); |
542 | gss_release_msg(gss_msg); | 540 | gss_release_msg(gss_msg); |
543 | out: | 541 | out: |
544 | dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", | 542 | dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", |
@@ -549,7 +547,7 @@ out: | |||
549 | static inline int | 547 | static inline int |
550 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | 548 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) |
551 | { | 549 | { |
552 | struct inode *inode; | 550 | struct rpc_pipe *pipe; |
553 | struct rpc_cred *cred = &gss_cred->gc_base; | 551 | struct rpc_cred *cred = &gss_cred->gc_base; |
554 | struct gss_upcall_msg *gss_msg; | 552 | struct gss_upcall_msg *gss_msg; |
555 | DEFINE_WAIT(wait); | 553 | DEFINE_WAIT(wait); |
@@ -573,14 +571,14 @@ retry: | |||
573 | err = PTR_ERR(gss_msg); | 571 | err = PTR_ERR(gss_msg); |
574 | goto out; | 572 | goto out; |
575 | } | 573 | } |
576 | inode = &gss_msg->inode->vfs_inode; | 574 | pipe = gss_msg->pipe; |
577 | for (;;) { | 575 | for (;;) { |
578 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); | 576 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); |
579 | spin_lock(&inode->i_lock); | 577 | spin_lock(&pipe->lock); |
580 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { | 578 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { |
581 | break; | 579 | break; |
582 | } | 580 | } |
583 | spin_unlock(&inode->i_lock); | 581 | spin_unlock(&pipe->lock); |
584 | if (fatal_signal_pending(current)) { | 582 | if (fatal_signal_pending(current)) { |
585 | err = -ERESTARTSYS; | 583 | err = -ERESTARTSYS; |
586 | goto out_intr; | 584 | goto out_intr; |
@@ -591,7 +589,7 @@ retry: | |||
591 | gss_cred_set_ctx(cred, gss_msg->ctx); | 589 | gss_cred_set_ctx(cred, gss_msg->ctx); |
592 | else | 590 | else |
593 | err = gss_msg->msg.errno; | 591 | err = gss_msg->msg.errno; |
594 | spin_unlock(&inode->i_lock); | 592 | spin_unlock(&pipe->lock); |
595 | out_intr: | 593 | out_intr: |
596 | finish_wait(&gss_msg->waitqueue, &wait); | 594 | finish_wait(&gss_msg->waitqueue, &wait); |
597 | gss_release_msg(gss_msg); | 595 | gss_release_msg(gss_msg); |
@@ -609,7 +607,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
609 | const void *p, *end; | 607 | const void *p, *end; |
610 | void *buf; | 608 | void *buf; |
611 | struct gss_upcall_msg *gss_msg; | 609 | struct gss_upcall_msg *gss_msg; |
612 | struct inode *inode = filp->f_path.dentry->d_inode; | 610 | struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; |
613 | struct gss_cl_ctx *ctx; | 611 | struct gss_cl_ctx *ctx; |
614 | uid_t uid; | 612 | uid_t uid; |
615 | ssize_t err = -EFBIG; | 613 | ssize_t err = -EFBIG; |
@@ -639,14 +637,14 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
639 | 637 | ||
640 | err = -ENOENT; | 638 | err = -ENOENT; |
641 | /* Find a matching upcall */ | 639 | /* Find a matching upcall */ |
642 | spin_lock(&inode->i_lock); | 640 | spin_lock(&pipe->lock); |
643 | gss_msg = __gss_find_upcall(RPC_I(inode), uid); | 641 | gss_msg = __gss_find_upcall(pipe, uid); |
644 | if (gss_msg == NULL) { | 642 | if (gss_msg == NULL) { |
645 | spin_unlock(&inode->i_lock); | 643 | spin_unlock(&pipe->lock); |
646 | goto err_put_ctx; | 644 | goto err_put_ctx; |
647 | } | 645 | } |
648 | list_del_init(&gss_msg->list); | 646 | list_del_init(&gss_msg->list); |
649 | spin_unlock(&inode->i_lock); | 647 | spin_unlock(&pipe->lock); |
650 | 648 | ||
651 | p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); | 649 | p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); |
652 | if (IS_ERR(p)) { | 650 | if (IS_ERR(p)) { |
@@ -674,9 +672,9 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
674 | err = mlen; | 672 | err = mlen; |
675 | 673 | ||
676 | err_release_msg: | 674 | err_release_msg: |
677 | spin_lock(&inode->i_lock); | 675 | spin_lock(&pipe->lock); |
678 | __gss_unhash_msg(gss_msg); | 676 | __gss_unhash_msg(gss_msg); |
679 | spin_unlock(&inode->i_lock); | 677 | spin_unlock(&pipe->lock); |
680 | gss_release_msg(gss_msg); | 678 | gss_release_msg(gss_msg); |
681 | err_put_ctx: | 679 | err_put_ctx: |
682 | gss_put_ctx(ctx); | 680 | gss_put_ctx(ctx); |
@@ -722,23 +720,23 @@ static int gss_pipe_open_v1(struct inode *inode) | |||
722 | static void | 720 | static void |
723 | gss_pipe_release(struct inode *inode) | 721 | gss_pipe_release(struct inode *inode) |
724 | { | 722 | { |
725 | struct rpc_inode *rpci = RPC_I(inode); | 723 | struct rpc_pipe *pipe = RPC_I(inode)->pipe; |
726 | struct gss_upcall_msg *gss_msg; | 724 | struct gss_upcall_msg *gss_msg; |
727 | 725 | ||
728 | restart: | 726 | restart: |
729 | spin_lock(&inode->i_lock); | 727 | spin_lock(&pipe->lock); |
730 | list_for_each_entry(gss_msg, &rpci->in_downcall, list) { | 728 | list_for_each_entry(gss_msg, &pipe->in_downcall, list) { |
731 | 729 | ||
732 | if (!list_empty(&gss_msg->msg.list)) | 730 | if (!list_empty(&gss_msg->msg.list)) |
733 | continue; | 731 | continue; |
734 | gss_msg->msg.errno = -EPIPE; | 732 | gss_msg->msg.errno = -EPIPE; |
735 | atomic_inc(&gss_msg->count); | 733 | atomic_inc(&gss_msg->count); |
736 | __gss_unhash_msg(gss_msg); | 734 | __gss_unhash_msg(gss_msg); |
737 | spin_unlock(&inode->i_lock); | 735 | spin_unlock(&pipe->lock); |
738 | gss_release_msg(gss_msg); | 736 | gss_release_msg(gss_msg); |
739 | goto restart; | 737 | goto restart; |
740 | } | 738 | } |
741 | spin_unlock(&inode->i_lock); | 739 | spin_unlock(&pipe->lock); |
742 | 740 | ||
743 | put_pipe_version(); | 741 | put_pipe_version(); |
744 | } | 742 | } |
@@ -759,6 +757,75 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) | |||
759 | } | 757 | } |
760 | } | 758 | } |
761 | 759 | ||
760 | static void gss_pipes_dentries_destroy(struct rpc_auth *auth) | ||
761 | { | ||
762 | struct gss_auth *gss_auth; | ||
763 | |||
764 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | ||
765 | if (gss_auth->pipe[0]->dentry) | ||
766 | rpc_unlink(gss_auth->pipe[0]->dentry); | ||
767 | if (gss_auth->pipe[1]->dentry) | ||
768 | rpc_unlink(gss_auth->pipe[1]->dentry); | ||
769 | } | ||
770 | |||
771 | static int gss_pipes_dentries_create(struct rpc_auth *auth) | ||
772 | { | ||
773 | int err; | ||
774 | struct gss_auth *gss_auth; | ||
775 | struct rpc_clnt *clnt; | ||
776 | |||
777 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | ||
778 | clnt = gss_auth->client; | ||
779 | |||
780 | gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, | ||
781 | "gssd", | ||
782 | clnt, gss_auth->pipe[1]); | ||
783 | if (IS_ERR(gss_auth->pipe[1]->dentry)) | ||
784 | return PTR_ERR(gss_auth->pipe[1]->dentry); | ||
785 | gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, | ||
786 | gss_auth->mech->gm_name, | ||
787 | clnt, gss_auth->pipe[0]); | ||
788 | if (IS_ERR(gss_auth->pipe[0]->dentry)) { | ||
789 | err = PTR_ERR(gss_auth->pipe[0]->dentry); | ||
790 | goto err_unlink_pipe_1; | ||
791 | } | ||
792 | return 0; | ||
793 | |||
794 | err_unlink_pipe_1: | ||
795 | rpc_unlink(gss_auth->pipe[1]->dentry); | ||
796 | return err; | ||
797 | } | ||
798 | |||
799 | static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt, | ||
800 | struct rpc_auth *auth) | ||
801 | { | ||
802 | struct net *net = rpc_net_ns(clnt); | ||
803 | struct super_block *sb; | ||
804 | |||
805 | sb = rpc_get_sb_net(net); | ||
806 | if (sb) { | ||
807 | if (clnt->cl_dentry) | ||
808 | gss_pipes_dentries_destroy(auth); | ||
809 | rpc_put_sb_net(net); | ||
810 | } | ||
811 | } | ||
812 | |||
813 | static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt, | ||
814 | struct rpc_auth *auth) | ||
815 | { | ||
816 | struct net *net = rpc_net_ns(clnt); | ||
817 | struct super_block *sb; | ||
818 | int err = 0; | ||
819 | |||
820 | sb = rpc_get_sb_net(net); | ||
821 | if (sb) { | ||
822 | if (clnt->cl_dentry) | ||
823 | err = gss_pipes_dentries_create(auth); | ||
824 | rpc_put_sb_net(net); | ||
825 | } | ||
826 | return err; | ||
827 | } | ||
828 | |||
762 | /* | 829 | /* |
763 | * NOTE: we have the opportunity to use different | 830 | * NOTE: we have the opportunity to use different |
764 | * parameters based on the input flavor (which must be a pseudoflavor) | 831 | * parameters based on the input flavor (which must be a pseudoflavor) |
@@ -801,32 +868,33 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | |||
801 | * that we supported only the old pipe. So we instead create | 868 | * that we supported only the old pipe. So we instead create |
802 | * the new pipe first. | 869 | * the new pipe first. |
803 | */ | 870 | */ |
804 | gss_auth->dentry[1] = rpc_mkpipe(clnt->cl_path.dentry, | 871 | gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1, |
805 | "gssd", | 872 | RPC_PIPE_WAIT_FOR_OPEN); |
806 | clnt, &gss_upcall_ops_v1, | 873 | if (IS_ERR(gss_auth->pipe[1])) { |
807 | RPC_PIPE_WAIT_FOR_OPEN); | 874 | err = PTR_ERR(gss_auth->pipe[1]); |
808 | if (IS_ERR(gss_auth->dentry[1])) { | ||
809 | err = PTR_ERR(gss_auth->dentry[1]); | ||
810 | goto err_put_mech; | 875 | goto err_put_mech; |
811 | } | 876 | } |
812 | 877 | ||
813 | gss_auth->dentry[0] = rpc_mkpipe(clnt->cl_path.dentry, | 878 | gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0, |
814 | gss_auth->mech->gm_name, | 879 | RPC_PIPE_WAIT_FOR_OPEN); |
815 | clnt, &gss_upcall_ops_v0, | 880 | if (IS_ERR(gss_auth->pipe[0])) { |
816 | RPC_PIPE_WAIT_FOR_OPEN); | 881 | err = PTR_ERR(gss_auth->pipe[0]); |
817 | if (IS_ERR(gss_auth->dentry[0])) { | 882 | goto err_destroy_pipe_1; |
818 | err = PTR_ERR(gss_auth->dentry[0]); | ||
819 | goto err_unlink_pipe_1; | ||
820 | } | 883 | } |
884 | err = gss_pipes_dentries_create_net(clnt, auth); | ||
885 | if (err) | ||
886 | goto err_destroy_pipe_0; | ||
821 | err = rpcauth_init_credcache(auth); | 887 | err = rpcauth_init_credcache(auth); |
822 | if (err) | 888 | if (err) |
823 | goto err_unlink_pipe_0; | 889 | goto err_unlink_pipes; |
824 | 890 | ||
825 | return auth; | 891 | return auth; |
826 | err_unlink_pipe_0: | 892 | err_unlink_pipes: |
827 | rpc_unlink(gss_auth->dentry[0]); | 893 | gss_pipes_dentries_destroy_net(clnt, auth); |
828 | err_unlink_pipe_1: | 894 | err_destroy_pipe_0: |
829 | rpc_unlink(gss_auth->dentry[1]); | 895 | rpc_destroy_pipe_data(gss_auth->pipe[0]); |
896 | err_destroy_pipe_1: | ||
897 | rpc_destroy_pipe_data(gss_auth->pipe[1]); | ||
830 | err_put_mech: | 898 | err_put_mech: |
831 | gss_mech_put(gss_auth->mech); | 899 | gss_mech_put(gss_auth->mech); |
832 | err_free: | 900 | err_free: |
@@ -839,8 +907,9 @@ out_dec: | |||
839 | static void | 907 | static void |
840 | gss_free(struct gss_auth *gss_auth) | 908 | gss_free(struct gss_auth *gss_auth) |
841 | { | 909 | { |
842 | rpc_unlink(gss_auth->dentry[1]); | 910 | gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth); |
843 | rpc_unlink(gss_auth->dentry[0]); | 911 | rpc_destroy_pipe_data(gss_auth->pipe[0]); |
912 | rpc_destroy_pipe_data(gss_auth->pipe[1]); | ||
844 | gss_mech_put(gss_auth->mech); | 913 | gss_mech_put(gss_auth->mech); |
845 | 914 | ||
846 | kfree(gss_auth); | 915 | kfree(gss_auth); |
@@ -1547,7 +1616,9 @@ static const struct rpc_authops authgss_ops = { | |||
1547 | .create = gss_create, | 1616 | .create = gss_create, |
1548 | .destroy = gss_destroy, | 1617 | .destroy = gss_destroy, |
1549 | .lookup_cred = gss_lookup_cred, | 1618 | .lookup_cred = gss_lookup_cred, |
1550 | .crcreate = gss_create_cred | 1619 | .crcreate = gss_create_cred, |
1620 | .pipes_create = gss_pipes_dentries_create, | ||
1621 | .pipes_destroy = gss_pipes_dentries_destroy, | ||
1551 | }; | 1622 | }; |
1552 | 1623 | ||
1553 | static const struct rpc_credops gss_credops = { | 1624 | static const struct rpc_credops gss_credops = { |
@@ -1591,6 +1662,21 @@ static const struct rpc_pipe_ops gss_upcall_ops_v1 = { | |||
1591 | .release_pipe = gss_pipe_release, | 1662 | .release_pipe = gss_pipe_release, |
1592 | }; | 1663 | }; |
1593 | 1664 | ||
1665 | static __net_init int rpcsec_gss_init_net(struct net *net) | ||
1666 | { | ||
1667 | return gss_svc_init_net(net); | ||
1668 | } | ||
1669 | |||
1670 | static __net_exit void rpcsec_gss_exit_net(struct net *net) | ||
1671 | { | ||
1672 | gss_svc_shutdown_net(net); | ||
1673 | } | ||
1674 | |||
1675 | static struct pernet_operations rpcsec_gss_net_ops = { | ||
1676 | .init = rpcsec_gss_init_net, | ||
1677 | .exit = rpcsec_gss_exit_net, | ||
1678 | }; | ||
1679 | |||
1594 | /* | 1680 | /* |
1595 | * Initialize RPCSEC_GSS module | 1681 | * Initialize RPCSEC_GSS module |
1596 | */ | 1682 | */ |
@@ -1604,8 +1690,13 @@ static int __init init_rpcsec_gss(void) | |||
1604 | err = gss_svc_init(); | 1690 | err = gss_svc_init(); |
1605 | if (err) | 1691 | if (err) |
1606 | goto out_unregister; | 1692 | goto out_unregister; |
1693 | err = register_pernet_subsys(&rpcsec_gss_net_ops); | ||
1694 | if (err) | ||
1695 | goto out_svc_exit; | ||
1607 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); | 1696 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); |
1608 | return 0; | 1697 | return 0; |
1698 | out_svc_exit: | ||
1699 | gss_svc_shutdown(); | ||
1609 | out_unregister: | 1700 | out_unregister: |
1610 | rpcauth_unregister(&authgss_ops); | 1701 | rpcauth_unregister(&authgss_ops); |
1611 | out: | 1702 | out: |
@@ -1614,6 +1705,7 @@ out: | |||
1614 | 1705 | ||
1615 | static void __exit exit_rpcsec_gss(void) | 1706 | static void __exit exit_rpcsec_gss(void) |
1616 | { | 1707 | { |
1708 | unregister_pernet_subsys(&rpcsec_gss_net_ops); | ||
1617 | gss_svc_shutdown(); | 1709 | gss_svc_shutdown(); |
1618 | rpcauth_unregister(&authgss_ops); | 1710 | rpcauth_unregister(&authgss_ops); |
1619 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | 1711 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |