aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-08-09 15:14:20 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-08-09 15:14:20 -0400
commitac6fecee3121a6825a01c8fda2f5cbf1ad6a3ebd (patch)
treeee45a178326d18e8ffacd094d6b28f3a09dd9f80 /net/sunrpc
parentcfeaa4a3caaf590c1fdb7a83fcd5326e7cdc70c3 (diff)
SUNRPC: Clean up rpc_populate/depopulate
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/rpc_pipe.c187
1 files changed, 101 insertions, 86 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 36338515f342..e5f37ded1565 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -401,7 +401,6 @@ static const struct file_operations rpc_info_operations = {
401 * We have a single directory with 1 node in it. 401 * We have a single directory with 1 node in it.
402 */ 402 */
403enum { 403enum {
404 RPCAUTH_Root = 1,
405 RPCAUTH_lockd, 404 RPCAUTH_lockd,
406 RPCAUTH_mount, 405 RPCAUTH_mount,
407 RPCAUTH_nfs, 406 RPCAUTH_nfs,
@@ -415,12 +414,12 @@ enum {
415 * Description of fs contents. 414 * Description of fs contents.
416 */ 415 */
417struct rpc_filelist { 416struct rpc_filelist {
418 char *name; 417 const char *name;
419 const struct file_operations *i_fop; 418 const struct file_operations *i_fop;
420 umode_t mode; 419 umode_t mode;
421}; 420};
422 421
423static struct rpc_filelist files[] = { 422static const struct rpc_filelist files[] = {
424 [RPCAUTH_lockd] = { 423 [RPCAUTH_lockd] = {
425 .name = "lockd", 424 .name = "lockd",
426 .mode = S_IFDIR | S_IRUGO | S_IXUGO, 425 .mode = S_IFDIR | S_IRUGO | S_IXUGO,
@@ -448,11 +447,11 @@ static struct rpc_filelist files[] = {
448}; 447};
449 448
450enum { 449enum {
451 RPCAUTH_info = 2, 450 RPCAUTH_info,
452 RPCAUTH_EOF 451 RPCAUTH_EOF
453}; 452};
454 453
455static struct rpc_filelist authfiles[] = { 454static const struct rpc_filelist authfiles[] = {
456 [RPCAUTH_info] = { 455 [RPCAUTH_info] = {
457 .name = "info", 456 .name = "info",
458 .i_fop = &rpc_info_operations, 457 .i_fop = &rpc_info_operations,
@@ -564,6 +563,20 @@ out_err:
564 return -ENOMEM; 563 return -ENOMEM;
565} 564}
566 565
566static int __rpc_create(struct inode *dir, struct dentry *dentry,
567 umode_t mode,
568 const struct file_operations *i_fop,
569 void *private)
570{
571 int err;
572
573 err = __rpc_create_common(dir, dentry, S_IFREG | mode, i_fop, private);
574 if (err)
575 return err;
576 fsnotify_create(dir, dentry);
577 return 0;
578}
579
567static int __rpc_mkdir(struct inode *dir, struct dentry *dentry, 580static int __rpc_mkdir(struct inode *dir, struct dentry *dentry,
568 umode_t mode, 581 umode_t mode,
569 const struct file_operations *i_fop, 582 const struct file_operations *i_fop,
@@ -601,6 +614,17 @@ static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry,
601 return 0; 614 return 0;
602} 615}
603 616
617static int __rpc_rmdir(struct inode *dir, struct dentry *dentry)
618{
619 int ret;
620
621 dget(dentry);
622 ret = simple_rmdir(dir, dentry);
623 d_delete(dentry);
624 dput(dentry);
625 return ret;
626}
627
604static int __rpc_unlink(struct inode *dir, struct dentry *dentry) 628static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
605{ 629{
606 int ret; 630 int ret;
@@ -678,100 +702,96 @@ static struct dentry *rpc_lookup_negative(const char *path,
678/* 702/*
679 * FIXME: This probably has races. 703 * FIXME: This probably has races.
680 */ 704 */
681static void rpc_depopulate(struct dentry *parent, 705static void __rpc_depopulate(struct dentry *parent,
682 unsigned long start, unsigned long eof) 706 const struct rpc_filelist *files,
707 int start, int eof)
683{ 708{
684 struct inode *dir = parent->d_inode; 709 struct inode *dir = parent->d_inode;
685 struct list_head *pos, *next; 710 struct dentry *dentry;
686 struct dentry *dentry, *dvec[10]; 711 struct qstr name;
687 int n = 0; 712 int i;
688 713
689 mutex_lock_nested(&dir->i_mutex, I_MUTEX_CHILD); 714 for (i = start; i < eof; i++) {
690repeat: 715 name.name = files[i].name;
691 spin_lock(&dcache_lock); 716 name.len = strlen(files[i].name);
692 list_for_each_safe(pos, next, &parent->d_subdirs) { 717 name.hash = full_name_hash(name.name, name.len);
693 dentry = list_entry(pos, struct dentry, d_u.d_child); 718 dentry = d_lookup(parent, &name);
694 if (!dentry->d_inode || 719
695 dentry->d_inode->i_ino < start || 720 if (dentry == NULL)
696 dentry->d_inode->i_ino >= eof)
697 continue; 721 continue;
698 spin_lock(&dentry->d_lock); 722 if (dentry->d_inode == NULL)
699 if (!d_unhashed(dentry)) { 723 goto next;
700 dget_locked(dentry); 724 switch (dentry->d_inode->i_mode & S_IFMT) {
701 __d_drop(dentry); 725 default:
702 spin_unlock(&dentry->d_lock); 726 BUG();
703 dvec[n++] = dentry; 727 case S_IFREG:
704 if (n == ARRAY_SIZE(dvec)) 728 __rpc_unlink(dir, dentry);
705 break; 729 break;
706 } else 730 case S_IFDIR:
707 spin_unlock(&dentry->d_lock); 731 __rpc_rmdir(dir, dentry);
708 } 732 }
709 spin_unlock(&dcache_lock); 733next:
710 if (n) { 734 dput(dentry);
711 do {
712 dentry = dvec[--n];
713 if (S_ISREG(dentry->d_inode->i_mode))
714 simple_unlink(dir, dentry);
715 else if (S_ISDIR(dentry->d_inode->i_mode))
716 simple_rmdir(dir, dentry);
717 d_delete(dentry);
718 dput(dentry);
719 } while (n);
720 goto repeat;
721 } 735 }
736}
737
738static void rpc_depopulate(struct dentry *parent,
739 const struct rpc_filelist *files,
740 int start, int eof)
741{
742 struct inode *dir = parent->d_inode;
743
744 mutex_lock_nested(&dir->i_mutex, I_MUTEX_CHILD);
745 __rpc_depopulate(parent, files, start, eof);
722 mutex_unlock(&dir->i_mutex); 746 mutex_unlock(&dir->i_mutex);
723} 747}
724 748
725static int 749static int rpc_populate(struct dentry *parent,
726rpc_populate(struct dentry *parent, 750 const struct rpc_filelist *files,
727 struct rpc_filelist *files, 751 int start, int eof,
728 int start, int eof) 752 void *private)
729{ 753{
730 struct inode *inode, *dir = parent->d_inode; 754 struct inode *dir = parent->d_inode;
731 void *private = RPC_I(dir)->private;
732 struct dentry *dentry; 755 struct dentry *dentry;
733 umode_t mode; 756 int i, err;
734 int i;
735 757
736 mutex_lock(&dir->i_mutex); 758 mutex_lock(&dir->i_mutex);
737 for (i = start; i < eof; i++) { 759 for (i = start; i < eof; i++) {
738 dentry = d_alloc_name(parent, files[i].name); 760 struct qstr q;
739 if (!dentry) 761
740 goto out_bad; 762 q.name = files[i].name;
741 dentry->d_op = &rpc_dentry_operations; 763 q.len = strlen(files[i].name);
742 mode = files[i].mode; 764 q.hash = full_name_hash(q.name, q.len);
743 inode = rpc_get_inode(dir->i_sb, mode); 765 dentry = __rpc_lookup_create_exclusive(parent, &q);
744 if (!inode) { 766 err = PTR_ERR(dentry);
745 dput(dentry); 767 if (IS_ERR(dentry))
746 goto out_bad; 768 goto out_bad;
769 switch (files[i].mode & S_IFMT) {
770 default:
771 BUG();
772 case S_IFREG:
773 err = __rpc_create(dir, dentry,
774 files[i].mode,
775 files[i].i_fop,
776 private);
777 break;
778 case S_IFDIR:
779 err = __rpc_mkdir(dir, dentry,
780 files[i].mode,
781 NULL,
782 private);
747 } 783 }
748 inode->i_ino = i; 784 if (err != 0)
749 if (files[i].i_fop) 785 goto out_bad;
750 inode->i_fop = files[i].i_fop;
751 if (private)
752 rpc_inode_setowner(inode, private);
753 if (S_ISDIR(mode))
754 inc_nlink(dir);
755 d_add(dentry, inode);
756 fsnotify_create(dir, dentry);
757 } 786 }
758 mutex_unlock(&dir->i_mutex); 787 mutex_unlock(&dir->i_mutex);
759 return 0; 788 return 0;
760out_bad: 789out_bad:
790 __rpc_depopulate(parent, files, start, eof);
761 mutex_unlock(&dir->i_mutex); 791 mutex_unlock(&dir->i_mutex);
762 printk(KERN_WARNING "%s: %s failed to populate directory %s\n", 792 printk(KERN_WARNING "%s: %s failed to populate directory %s\n",
763 __FILE__, __func__, parent->d_name.name); 793 __FILE__, __func__, parent->d_name.name);
764 return -ENOMEM; 794 return err;
765}
766
767static int
768__rpc_rmdir(struct inode *dir, struct dentry *dentry)
769{
770 int error;
771 error = simple_rmdir(dir, dentry);
772 if (!error)
773 d_delete(dentry);
774 return error;
775} 795}
776 796
777/** 797/**
@@ -800,16 +820,14 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
800 if (error != 0) 820 if (error != 0)
801 goto out_err; 821 goto out_err;
802 error = rpc_populate(dentry, authfiles, 822 error = rpc_populate(dentry, authfiles,
803 RPCAUTH_info, RPCAUTH_EOF); 823 RPCAUTH_info, RPCAUTH_EOF, rpc_client);
804 if (error) 824 if (error)
805 goto err_depopulate; 825 goto err_rmdir;
806 dget(dentry);
807out: 826out:
808 mutex_unlock(&dir->i_mutex); 827 mutex_unlock(&dir->i_mutex);
809 rpc_release_path(&nd); 828 rpc_release_path(&nd);
810 return dentry; 829 return dentry;
811err_depopulate: 830err_rmdir:
812 rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF);
813 __rpc_rmdir(dir, dentry); 831 __rpc_rmdir(dir, dentry);
814out_err: 832out_err:
815 printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n", 833 printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n",
@@ -832,9 +850,8 @@ rpc_rmdir(struct dentry *dentry)
832 parent = dget_parent(dentry); 850 parent = dget_parent(dentry);
833 dir = parent->d_inode; 851 dir = parent->d_inode;
834 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); 852 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
835 rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF); 853 rpc_depopulate(dentry, authfiles, RPCAUTH_info, RPCAUTH_EOF);
836 error = __rpc_rmdir(dir, dentry); 854 error = __rpc_rmdir(dir, dentry);
837 dput(dentry);
838 mutex_unlock(&dir->i_mutex); 855 mutex_unlock(&dir->i_mutex);
839 dput(parent); 856 dput(parent);
840 return error; 857 return error;
@@ -900,7 +917,6 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
900 private, ops, flags); 917 private, ops, flags);
901 if (err) 918 if (err)
902 goto out_err; 919 goto out_err;
903 dget(dentry);
904out: 920out:
905 mutex_unlock(&dir->i_mutex); 921 mutex_unlock(&dir->i_mutex);
906 return dentry; 922 return dentry;
@@ -932,7 +948,6 @@ rpc_unlink(struct dentry *dentry)
932 dir = parent->d_inode; 948 dir = parent->d_inode;
933 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); 949 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
934 error = __rpc_rmpipe(dir, dentry); 950 error = __rpc_rmpipe(dir, dentry);
935 dput(dentry);
936 mutex_unlock(&dir->i_mutex); 951 mutex_unlock(&dir->i_mutex);
937 dput(parent); 952 dput(parent);
938 return error; 953 return error;
@@ -970,7 +985,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
970 iput(inode); 985 iput(inode);
971 return -ENOMEM; 986 return -ENOMEM;
972 } 987 }
973 if (rpc_populate(root, files, RPCAUTH_Root + 1, RPCAUTH_RootEOF)) 988 if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
974 goto out; 989 goto out;
975 sb->s_root = root; 990 sb->s_root = root;
976 return 0; 991 return 0;