aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/idmap.c10
-rw-r--r--include/linux/sunrpc/clnt.h2
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h9
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c9
-rw-r--r--net/sunrpc/clnt.c53
-rw-r--r--net/sunrpc/rpc_pipe.c268
6 files changed, 209 insertions, 142 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 1d0a5bf0d26..ffb8df91dc3 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -66,6 +66,7 @@ struct idmap_hashtable {
66}; 66};
67 67
68struct idmap { 68struct idmap {
69 char idmap_path[48];
69 struct dentry *idmap_dentry; 70 struct dentry *idmap_dentry;
70 wait_queue_head_t idmap_wq; 71 wait_queue_head_t idmap_wq;
71 struct idmap_msg idmap_im; 72 struct idmap_msg idmap_im;
@@ -101,8 +102,11 @@ nfs_idmap_new(struct nfs4_client *clp)
101 102
102 memset(idmap, 0, sizeof(*idmap)); 103 memset(idmap, 0, sizeof(*idmap));
103 104
104 idmap->idmap_dentry = rpc_mkpipe(clp->cl_rpcclient->cl_dentry, 105 snprintf(idmap->idmap_path, sizeof(idmap->idmap_path),
105 "idmap", idmap, &idmap_upcall_ops, 0); 106 "%s/idmap", clp->cl_rpcclient->cl_pathname);
107
108 idmap->idmap_dentry = rpc_mkpipe(idmap->idmap_path,
109 idmap, &idmap_upcall_ops, 0);
106 if (IS_ERR(idmap->idmap_dentry)) { 110 if (IS_ERR(idmap->idmap_dentry)) {
107 kfree(idmap); 111 kfree(idmap);
108 return; 112 return;
@@ -124,7 +128,7 @@ nfs_idmap_delete(struct nfs4_client *clp)
124 128
125 if (!idmap) 129 if (!idmap)
126 return; 130 return;
127 rpc_unlink(idmap->idmap_dentry); 131 rpc_unlink(idmap->idmap_path);
128 clp->cl_idmap = NULL; 132 clp->cl_idmap = NULL;
129 kfree(idmap); 133 kfree(idmap);
130} 134}
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index b5b51c19669..ab151bbb66d 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -59,7 +59,7 @@ struct rpc_clnt {
59 59
60 int cl_nodelen; /* nodename length */ 60 int cl_nodelen; /* nodename length */
61 char cl_nodename[UNX_MAXNODENAME]; 61 char cl_nodename[UNX_MAXNODENAME];
62 struct dentry * __cl_parent_dentry; 62 char cl_pathname[30];/* Path in rpc_pipe_fs */
63 struct dentry * cl_dentry; /* inode */ 63 struct dentry * cl_dentry; /* inode */
64 struct rpc_clnt * cl_parent; /* Points to parent of clones */ 64 struct rpc_clnt * cl_parent; /* Points to parent of clones */
65 struct rpc_rtt cl_rtt_default; 65 struct rpc_rtt cl_rtt_default;
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 63878d05c9a..63929349571 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -41,11 +41,10 @@ RPC_I(struct inode *inode)
41 41
42extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); 42extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
43 43
44extern struct dentry *rpc_mkdir(struct dentry *, char *, struct rpc_clnt *); 44extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *);
45extern void rpc_rmdir(struct dentry *); 45extern int rpc_rmdir(char *);
46extern struct dentry *rpc_mkpipe(struct dentry *, char *, void *, 46extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags);
47 struct rpc_pipe_ops *, int flags); 47extern int rpc_unlink(char *);
48extern void rpc_unlink(struct dentry *);
49 48
50#endif 49#endif
51#endif 50#endif
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index bd2555139fa..d2b08f16c25 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -87,6 +87,7 @@ struct gss_auth {
87 struct list_head upcalls; 87 struct list_head upcalls;
88 struct rpc_clnt *client; 88 struct rpc_clnt *client;
89 struct dentry *dentry; 89 struct dentry *dentry;
90 char path[48];
90 spinlock_t lock; 91 spinlock_t lock;
91}; 92};
92 93
@@ -689,8 +690,10 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
689 if (err) 690 if (err)
690 goto err_put_mech; 691 goto err_put_mech;
691 692
692 gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name, 693 snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s",
693 clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); 694 clnt->cl_pathname,
695 gss_auth->mech->gm_name);
696 gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
694 if (IS_ERR(gss_auth->dentry)) { 697 if (IS_ERR(gss_auth->dentry)) {
695 err = PTR_ERR(gss_auth->dentry); 698 err = PTR_ERR(gss_auth->dentry);
696 goto err_put_mech; 699 goto err_put_mech;
@@ -715,7 +718,7 @@ gss_destroy(struct rpc_auth *auth)
715 auth, auth->au_flavor); 718 auth, auth->au_flavor);
716 719
717 gss_auth = container_of(auth, struct gss_auth, rpc_auth); 720 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
718 rpc_unlink(gss_auth->dentry); 721 rpc_unlink(gss_auth->path);
719 gss_mech_put(gss_auth->mech); 722 gss_mech_put(gss_auth->mech);
720 723
721 rpcauth_free_credcache(auth); 724 rpcauth_free_credcache(auth);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 63bf591310e..5a8f01d726e 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -67,42 +67,26 @@ static u32 * call_verify(struct rpc_task *task);
67static int 67static int
68rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) 68rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
69{ 69{
70 static unsigned int clntid; 70 static uint32_t clntid;
71 char name[128];
72 int error; 71 int error;
73 72
74 if (dir_name == NULL) 73 if (dir_name == NULL)
75 return 0; 74 return 0;
76 75 for (;;) {
77 retry_parent: 76 snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
78 clnt->__cl_parent_dentry = rpc_mkdir(NULL, dir_name, NULL); 77 "%s/clnt%x", dir_name,
79 if (IS_ERR(clnt->__cl_parent_dentry)) { 78 (unsigned int)clntid++);
80 error = PTR_ERR(clnt->__cl_parent_dentry); 79 clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0';
81 if (error == -EEXIST) 80 clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
82 goto retry_parent; /* XXX(hch): WTF? */ 81 if (!IS_ERR(clnt->cl_dentry))
83 82 return 0;
84 printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
85 dir_name, error);
86 return error;
87 }
88
89
90 retry_child:
91 snprintf(name, sizeof(name), "clnt%x", clntid++);
92 name[sizeof(name) - 1] = '\0';
93
94 clnt->cl_dentry = rpc_mkdir(clnt->__cl_parent_dentry, name, clnt);
95 if (IS_ERR(clnt->cl_dentry)) {
96 error = PTR_ERR(clnt->cl_dentry); 83 error = PTR_ERR(clnt->cl_dentry);
97 if (error == -EEXIST) 84 if (error != -EEXIST) {
98 goto retry_child; 85 printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
99 printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", 86 clnt->cl_pathname, error);
100 name, error); 87 return error;
101 rpc_rmdir(clnt->__cl_parent_dentry); 88 }
102 return error;
103 } 89 }
104
105 return 0;
106} 90}
107 91
108/* 92/*
@@ -190,8 +174,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
190 return clnt; 174 return clnt;
191 175
192out_no_auth: 176out_no_auth:
193 rpc_rmdir(clnt->cl_dentry); 177 rpc_rmdir(clnt->cl_pathname);
194 rpc_rmdir(clnt->__cl_parent_dentry);
195out_no_path: 178out_no_path:
196 if (clnt->cl_server != clnt->cl_inline_name) 179 if (clnt->cl_server != clnt->cl_inline_name)
197 kfree(clnt->cl_server); 180 kfree(clnt->cl_server);
@@ -319,10 +302,8 @@ rpc_destroy_client(struct rpc_clnt *clnt)
319 rpc_destroy_client(clnt->cl_parent); 302 rpc_destroy_client(clnt->cl_parent);
320 goto out_free; 303 goto out_free;
321 } 304 }
322 if (clnt->cl_dentry) 305 if (clnt->cl_pathname[0])
323 rpc_rmdir(clnt->cl_dentry); 306 rpc_rmdir(clnt->cl_pathname);
324 if (clnt->__cl_parent_dentry)
325 rpc_rmdir(clnt->__cl_parent_dentry);
326 if (clnt->cl_xprt) { 307 if (clnt->cl_xprt) {
327 xprt_destroy(clnt->cl_xprt); 308 xprt_destroy(clnt->cl_xprt);
328 clnt->cl_xprt = NULL; 309 clnt->cl_xprt = NULL;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index b382809726d..ded6c63f11e 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -414,6 +414,38 @@ rpc_put_mount(void)
414 simple_release_fs(&rpc_mount, &rpc_mount_count); 414 simple_release_fs(&rpc_mount, &rpc_mount_count);
415} 415}
416 416
417static int
418rpc_lookup_parent(char *path, struct nameidata *nd)
419{
420 if (path[0] == '\0')
421 return -ENOENT;
422 if (rpc_get_mount()) {
423 printk(KERN_WARNING "%s: %s failed to mount "
424 "pseudofilesystem \n", __FILE__, __FUNCTION__);
425 return -ENODEV;
426 }
427 nd->mnt = mntget(rpc_mount);
428 nd->dentry = dget(rpc_mount->mnt_root);
429 nd->last_type = LAST_ROOT;
430 nd->flags = LOOKUP_PARENT;
431 nd->depth = 0;
432
433 if (path_walk(path, nd)) {
434 printk(KERN_WARNING "%s: %s failed to find path %s\n",
435 __FILE__, __FUNCTION__, path);
436 rpc_put_mount();
437 return -ENOENT;
438 }
439 return 0;
440}
441
442static void
443rpc_release_path(struct nameidata *nd)
444{
445 path_release(nd);
446 rpc_put_mount();
447}
448
417static struct inode * 449static struct inode *
418rpc_get_inode(struct super_block *sb, int mode) 450rpc_get_inode(struct super_block *sb, int mode)
419{ 451{
@@ -518,149 +550,197 @@ out_bad:
518 return -ENOMEM; 550 return -ENOMEM;
519} 551}
520 552
521struct dentry * 553static int
522rpc_mkdir(struct dentry *parent, char *name, struct rpc_clnt *rpc_client) 554__rpc_mkdir(struct inode *dir, struct dentry *dentry)
523{ 555{
524 struct inode *dir;
525 struct dentry *dentry;
526 struct inode *inode; 556 struct inode *inode;
557
558 inode = rpc_get_inode(dir->i_sb, S_IFDIR | S_IRUSR | S_IXUSR);
559 if (!inode)
560 goto out_err;
561 inode->i_ino = iunique(dir->i_sb, 100);
562 d_instantiate(dentry, inode);
563 dir->i_nlink++;
564 inode_dir_notify(dir, DN_CREATE);
565 rpc_get_mount();
566 return 0;
567out_err:
568 printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
569 __FILE__, __FUNCTION__, dentry->d_name.name);
570 return -ENOMEM;
571}
572
573static int
574__rpc_rmdir(struct inode *dir, struct dentry *dentry)
575{
527 int error; 576 int error;
528 577
529 if (!parent) 578 shrink_dcache_parent(dentry);
530 parent = rpc_mount->mnt_root; 579 if (dentry->d_inode) {
580 rpc_close_pipes(dentry->d_inode);
581 rpc_inode_setowner(dentry->d_inode, NULL);
582 }
583 if ((error = simple_rmdir(dir, dentry)) != 0)
584 return error;
585 if (!error) {
586 inode_dir_notify(dir, DN_DELETE);
587 d_drop(dentry);
588 rpc_put_mount();
589 }
590 return 0;
591}
531 592
532 dir = parent->d_inode; 593static struct dentry *
533 594rpc_lookup_negative(char *path, struct nameidata *nd)
534 error = rpc_get_mount(); 595{
535 if (error) 596 struct dentry *dentry;
536 return ERR_PTR(error); 597 struct inode *dir;
598 int error;
537 599
600 if ((error = rpc_lookup_parent(path, nd)) != 0)
601 return ERR_PTR(error);
602 dir = nd->dentry->d_inode;
538 down(&dir->i_sem); 603 down(&dir->i_sem);
539 dentry = lookup_one_len(name, parent, strlen(name)); 604 dentry = lookup_hash(&nd->last, nd->dentry);
540 if (IS_ERR(dentry)) 605 if (IS_ERR(dentry))
541 goto out_unlock; 606 goto out_err;
542 if (dentry->d_inode) { 607 if (dentry->d_inode) {
608 dput(dentry);
543 dentry = ERR_PTR(-EEXIST); 609 dentry = ERR_PTR(-EEXIST);
544 goto out_dput; 610 goto out_err;
545 } 611 }
546 612 return dentry;
547 inode = rpc_get_inode(dir->i_sb, S_IFDIR | S_IRUSR | S_IXUSR); 613out_err:
548 if (!inode)
549 goto out_dput;
550 inode->i_ino = iunique(dir->i_sb, 100);
551 dir->i_nlink++;
552 RPC_I(dentry->d_inode)->private = rpc_client;
553
554 d_instantiate(dentry, inode);
555 dget(dentry);
556 up(&dir->i_sem); 614 up(&dir->i_sem);
615 rpc_release_path(nd);
616 return dentry;
617}
557 618
558 inode_dir_notify(dir, DN_CREATE);
559 619
620struct dentry *
621rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
622{
623 struct nameidata nd;
624 struct dentry *dentry;
625 struct inode *dir;
626 int error;
627
628 dentry = rpc_lookup_negative(path, &nd);
629 if (IS_ERR(dentry))
630 return dentry;
631 dir = nd.dentry->d_inode;
632 if ((error = __rpc_mkdir(dir, dentry)) != 0)
633 goto err_dput;
634 RPC_I(dentry->d_inode)->private = rpc_client;
560 error = rpc_populate(dentry, authfiles, 635 error = rpc_populate(dentry, authfiles,
561 RPCAUTH_info, RPCAUTH_EOF); 636 RPCAUTH_info, RPCAUTH_EOF);
562 if (error) 637 if (error)
563 goto out_depopulate; 638 goto err_depopulate;
564 639out:
565 return dentry;
566
567 out_depopulate:
568 rpc_rmdir(dentry);
569 out_dput:
570 dput(dentry);
571 out_unlock:
572 up(&dir->i_sem); 640 up(&dir->i_sem);
573 rpc_put_mount(); 641 rpc_release_path(&nd);
574 return dentry; 642 return dentry;
643err_depopulate:
644 rpc_depopulate(dentry);
645 __rpc_rmdir(dir, dentry);
646err_dput:
647 dput(dentry);
648 printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n",
649 __FILE__, __FUNCTION__, path, error);
650 dentry = ERR_PTR(error);
651 goto out;
575} 652}
576 653
577void 654int
578rpc_rmdir(struct dentry *dentry) 655rpc_rmdir(char *path)
579{ 656{
580 struct dentry *parent = dentry->d_parent; 657 struct nameidata nd;
581 658 struct dentry *dentry;
582 rpc_depopulate(dentry); 659 struct inode *dir;
660 int error;
583 661
584 down(&parent->d_inode->i_sem); 662 if ((error = rpc_lookup_parent(path, &nd)) != 0)
585 if (dentry->d_inode) { 663 return error;
586 rpc_close_pipes(dentry->d_inode); 664 dir = nd.dentry->d_inode;
587 rpc_inode_setowner(dentry->d_inode, NULL); 665 down(&dir->i_sem);
588 simple_rmdir(parent->d_inode, dentry); 666 dentry = lookup_hash(&nd.last, nd.dentry);
667 if (IS_ERR(dentry)) {
668 error = PTR_ERR(dentry);
669 goto out_release;
589 } 670 }
590 up(&parent->d_inode->i_sem); 671 rpc_depopulate(dentry);
591 672 error = __rpc_rmdir(dir, dentry);
592 inode_dir_notify(parent->d_inode, DN_DELETE); 673 dput(dentry);
593 rpc_put_mount(); 674out_release:
675 up(&dir->i_sem);
676 rpc_release_path(&nd);
677 return error;
594} 678}
595 679
596struct dentry * 680struct dentry *
597rpc_mkpipe(struct dentry *parent, char *name, void *private, 681rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags)
598 struct rpc_pipe_ops *ops, int flags)
599{ 682{
600 struct inode *dir = parent->d_inode; 683 struct nameidata nd;
601 struct dentry *dentry; 684 struct dentry *dentry;
602 struct inode *inode; 685 struct inode *dir, *inode;
603 struct rpc_inode *rpci; 686 struct rpc_inode *rpci;
604 int error;
605
606 error = rpc_get_mount();
607 if (error)
608 return ERR_PTR(error);
609 687
610 down(&parent->d_inode->i_sem); 688 dentry = rpc_lookup_negative(path, &nd);
611 dentry = lookup_one_len(name, parent, strlen(name));
612 if (IS_ERR(dentry)) 689 if (IS_ERR(dentry))
613 goto out_unlock; 690 return dentry;
614 if (dentry->d_inode) { 691 dir = nd.dentry->d_inode;
615 dentry = ERR_PTR(-EEXIST); 692 inode = rpc_get_inode(dir->i_sb, S_IFSOCK | S_IRUSR | S_IWUSR);
616 goto out_dput; 693 if (!inode)
617 } 694 goto err_dput;
618
619 inode = rpc_get_inode(parent->d_inode->i_sb,
620 S_IFSOCK | S_IRUSR | S_IWUSR);
621 if (!inode) {
622 dentry = ERR_PTR(-ENOMEM);
623 goto out_dput;
624 }
625
626 inode->i_ino = iunique(dir->i_sb, 100); 695 inode->i_ino = iunique(dir->i_sb, 100);
627 inode->i_fop = &rpc_pipe_fops; 696 inode->i_fop = &rpc_pipe_fops;
628 697 d_instantiate(dentry, inode);
629 rpci = RPC_I(inode); 698 rpci = RPC_I(inode);
630 rpci->private = private; 699 rpci->private = private;
631 rpci->flags = flags; 700 rpci->flags = flags;
632 rpci->ops = ops; 701 rpci->ops = ops;
633
634 d_instantiate(dentry, inode);
635 dget(dentry);
636 up(&parent->d_inode->i_sem);
637
638 inode_dir_notify(dir, DN_CREATE); 702 inode_dir_notify(dir, DN_CREATE);
703out:
704 up(&dir->i_sem);
705 rpc_release_path(&nd);
639 return dentry; 706 return dentry;
640 707err_dput:
641 out_dput:
642 dput(dentry); 708 dput(dentry);
643 out_unlock: 709 dentry = ERR_PTR(-ENOMEM);
644 up(&parent->d_inode->i_sem); 710 printk(KERN_WARNING "%s: %s() failed to create pipe %s (errno = %d)\n",
645 rpc_put_mount(); 711 __FILE__, __FUNCTION__, path, -ENOMEM);
646 return dentry; 712 goto out;
647} 713}
648 714
649void 715int
650rpc_unlink(struct dentry *dentry) 716rpc_unlink(char *path)
651{ 717{
652 struct dentry *parent = dentry->d_parent; 718 struct nameidata nd;
719 struct dentry *dentry;
720 struct inode *dir;
721 int error;
653 722
654 down(&parent->d_inode->i_sem); 723 if ((error = rpc_lookup_parent(path, &nd)) != 0)
724 return error;
725 dir = nd.dentry->d_inode;
726 down(&dir->i_sem);
727 dentry = lookup_hash(&nd.last, nd.dentry);
728 if (IS_ERR(dentry)) {
729 error = PTR_ERR(dentry);
730 goto out_release;
731 }
732 d_drop(dentry);
655 if (dentry->d_inode) { 733 if (dentry->d_inode) {
656 rpc_close_pipes(dentry->d_inode); 734 rpc_close_pipes(dentry->d_inode);
657 rpc_inode_setowner(dentry->d_inode, NULL); 735 rpc_inode_setowner(dentry->d_inode, NULL);
658 simple_unlink(parent->d_inode, dentry); 736 error = simple_unlink(dir, dentry);
659 } 737 }
660 up(&parent->d_inode->i_sem); 738 dput(dentry);
661 739 inode_dir_notify(dir, DN_DELETE);
662 inode_dir_notify(parent->d_inode, DN_DELETE); 740out_release:
663 rpc_put_mount(); 741 up(&dir->i_sem);
742 rpc_release_path(&nd);
743 return error;
664} 744}
665 745
666/* 746/*