Commit e8f2b548de7ae65e17ee911e54712a3f26f69c60

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro:
 "A nasty bug in fs/namespace.c caught by Andrey + a couple of less
  serious unpleasantness - ecryptfs misc device playing hopeless games
  with try_module_get() and palinfo procfs support being...  not quite
  correctly done, to be polite."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  mnt: release locks on error path in do_loopback
  palinfo fixes
  procfs: add proc_remove_subtree()
  ecryptfs: close rmmod race

Showing 5 changed files Side-by-side Diff

arch/ia64/kernel/palinfo.c
... ... @@ -849,17 +849,6 @@
849 849  
850 850 #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries)
851 851  
852   -/*
853   - * this array is used to keep track of the proc entries we create. This is
854   - * required in the module mode when we need to remove all entries. The procfs code
855   - * does not do recursion of deletion
856   - *
857   - * Notes:
858   - * - +1 accounts for the cpuN directory entry in /proc/pal
859   - */
860   -#define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1))
861   -
862   -static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES];
863 852 static struct proc_dir_entry *palinfo_dir;
864 853  
865 854 /*
866 855  
867 856  
868 857  
869 858  
870 859  
871 860  
872 861  
... ... @@ -971,60 +960,32 @@
971 960 static void __cpuinit
972 961 create_palinfo_proc_entries(unsigned int cpu)
973 962 {
974   -# define CPUSTR "cpu%d"
975   -
976 963 pal_func_cpu_u_t f;
977   - struct proc_dir_entry **pdir;
978 964 struct proc_dir_entry *cpu_dir;
979 965 int j;
980   - char cpustr[sizeof(CPUSTR)];
  966 + char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */
  967 + sprintf(cpustr, "cpu%d", cpu);
981 968  
982   -
983   - /*
984   - * we keep track of created entries in a depth-first order for
985   - * cleanup purposes. Each entry is stored into palinfo_proc_entries
986   - */
987   - sprintf(cpustr,CPUSTR, cpu);
988   -
989 969 cpu_dir = proc_mkdir(cpustr, palinfo_dir);
  970 + if (!cpu_dir)
  971 + return;
990 972  
991 973 f.req_cpu = cpu;
992 974  
993   - /*
994   - * Compute the location to store per cpu entries
995   - * We dont store the top level entry in this list, but
996   - * remove it finally after removing all cpu entries.
997   - */
998   - pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)];
999   - *pdir++ = cpu_dir;
1000 975 for (j=0; j < NR_PALINFO_ENTRIES; j++) {
1001 976 f.func_id = j;
1002   - *pdir = create_proc_read_entry(
1003   - palinfo_entries[j].name, 0, cpu_dir,
1004   - palinfo_read_entry, (void *)f.value);
1005   - pdir++;
  977 + create_proc_read_entry(
  978 + palinfo_entries[j].name, 0, cpu_dir,
  979 + palinfo_read_entry, (void *)f.value);
1006 980 }
1007 981 }
1008 982  
1009 983 static void
1010 984 remove_palinfo_proc_entries(unsigned int hcpu)
1011 985 {
1012   - int j;
1013   - struct proc_dir_entry *cpu_dir, **pdir;
1014   -
1015   - pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)];
1016   - cpu_dir = *pdir;
1017   - *pdir++=NULL;
1018   - for (j=0; j < (NR_PALINFO_ENTRIES); j++) {
1019   - if ((*pdir)) {
1020   - remove_proc_entry ((*pdir)->name, cpu_dir);
1021   - *pdir ++= NULL;
1022   - }
1023   - }
1024   -
1025   - if (cpu_dir) {
1026   - remove_proc_entry(cpu_dir->name, palinfo_dir);
1027   - }
  986 + char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */
  987 + sprintf(cpustr, "cpu%d", hcpu);
  988 + remove_proc_subtree(cpustr, palinfo_dir);
1028 989 }
1029 990  
1030 991 static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb,
... ... @@ -1058,6 +1019,8 @@
1058 1019  
1059 1020 printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION);
1060 1021 palinfo_dir = proc_mkdir("pal", NULL);
  1022 + if (!palinfo_dir)
  1023 + return -ENOMEM;
1061 1024  
1062 1025 /* Create palinfo dirs in /proc for all online cpus */
1063 1026 for_each_online_cpu(i) {
1064 1027  
... ... @@ -1073,22 +1036,8 @@
1073 1036 static void __exit
1074 1037 palinfo_exit(void)
1075 1038 {
1076   - int i = 0;
1077   -
1078   - /* remove all nodes: depth first pass. Could optimize this */
1079   - for_each_online_cpu(i) {
1080   - remove_palinfo_proc_entries(i);
1081   - }
1082   -
1083   - /*
1084   - * Remove the top level entry finally
1085   - */
1086   - remove_proc_entry(palinfo_dir->name, NULL);
1087   -
1088   - /*
1089   - * Unregister from cpu notifier callbacks
1090   - */
1091 1039 unregister_hotcpu_notifier(&palinfo_cpu_notifier);
  1040 + remove_proc_subtree("pal", NULL);
1092 1041 }
1093 1042  
1094 1043 module_init(palinfo_init);
fs/ecryptfs/miscdev.c
... ... @@ -80,13 +80,6 @@
80 80 int rc;
81 81  
82 82 mutex_lock(&ecryptfs_daemon_hash_mux);
83   - rc = try_module_get(THIS_MODULE);
84   - if (rc == 0) {
85   - rc = -EIO;
86   - printk(KERN_ERR "%s: Error attempting to increment module use "
87   - "count; rc = [%d]\n", __func__, rc);
88   - goto out_unlock_daemon_list;
89   - }
90 83 rc = ecryptfs_find_daemon_by_euid(&daemon);
91 84 if (!rc) {
92 85 rc = -EINVAL;
... ... @@ -96,7 +89,7 @@
96 89 if (rc) {
97 90 printk(KERN_ERR "%s: Error attempting to spawn daemon; "
98 91 "rc = [%d]\n", __func__, rc);
99   - goto out_module_put_unlock_daemon_list;
  92 + goto out_unlock_daemon_list;
100 93 }
101 94 mutex_lock(&daemon->mux);
102 95 if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) {
... ... @@ -108,9 +101,6 @@
108 101 atomic_inc(&ecryptfs_num_miscdev_opens);
109 102 out_unlock_daemon:
110 103 mutex_unlock(&daemon->mux);
111   -out_module_put_unlock_daemon_list:
112   - if (rc)
113   - module_put(THIS_MODULE);
114 104 out_unlock_daemon_list:
115 105 mutex_unlock(&ecryptfs_daemon_hash_mux);
116 106 return rc;
... ... @@ -147,7 +137,6 @@
147 137 "bug.\n", __func__, rc);
148 138 BUG();
149 139 }
150   - module_put(THIS_MODULE);
151 140 return rc;
152 141 }
153 142  
... ... @@ -471,6 +460,7 @@
471 460  
472 461  
473 462 static const struct file_operations ecryptfs_miscdev_fops = {
  463 + .owner = THIS_MODULE,
474 464 .open = ecryptfs_miscdev_open,
475 465 .poll = ecryptfs_miscdev_poll,
476 466 .read = ecryptfs_miscdev_read,
... ... @@ -1690,7 +1690,7 @@
1690 1690  
1691 1691 if (IS_ERR(mnt)) {
1692 1692 err = PTR_ERR(mnt);
1693   - goto out;
  1693 + goto out2;
1694 1694 }
1695 1695  
1696 1696 err = graft_tree(mnt, path);
... ... @@ -755,37 +755,8 @@
755 755 free_proc_entry(pde);
756 756 }
757 757  
758   -/*
759   - * Remove a /proc entry and free it if it's not currently in use.
760   - */
761   -void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
  758 +static void entry_rundown(struct proc_dir_entry *de)
762 759 {
763   - struct proc_dir_entry **p;
764   - struct proc_dir_entry *de = NULL;
765   - const char *fn = name;
766   - unsigned int len;
767   -
768   - spin_lock(&proc_subdir_lock);
769   - if (__xlate_proc_name(name, &parent, &fn) != 0) {
770   - spin_unlock(&proc_subdir_lock);
771   - return;
772   - }
773   - len = strlen(fn);
774   -
775   - for (p = &parent->subdir; *p; p=&(*p)->next ) {
776   - if (proc_match(len, fn, *p)) {
777   - de = *p;
778   - *p = de->next;
779   - de->next = NULL;
780   - break;
781   - }
782   - }
783   - spin_unlock(&proc_subdir_lock);
784   - if (!de) {
785   - WARN(1, "name '%s'\n", name);
786   - return;
787   - }
788   -
789 760 spin_lock(&de->pde_unload_lock);
790 761 /*
791 762 * Stop accepting new callers into module. If you're
792 763  
... ... @@ -817,7 +788,41 @@
817 788 spin_lock(&de->pde_unload_lock);
818 789 }
819 790 spin_unlock(&de->pde_unload_lock);
  791 +}
820 792  
  793 +/*
  794 + * Remove a /proc entry and free it if it's not currently in use.
  795 + */
  796 +void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
  797 +{
  798 + struct proc_dir_entry **p;
  799 + struct proc_dir_entry *de = NULL;
  800 + const char *fn = name;
  801 + unsigned int len;
  802 +
  803 + spin_lock(&proc_subdir_lock);
  804 + if (__xlate_proc_name(name, &parent, &fn) != 0) {
  805 + spin_unlock(&proc_subdir_lock);
  806 + return;
  807 + }
  808 + len = strlen(fn);
  809 +
  810 + for (p = &parent->subdir; *p; p=&(*p)->next ) {
  811 + if (proc_match(len, fn, *p)) {
  812 + de = *p;
  813 + *p = de->next;
  814 + de->next = NULL;
  815 + break;
  816 + }
  817 + }
  818 + spin_unlock(&proc_subdir_lock);
  819 + if (!de) {
  820 + WARN(1, "name '%s'\n", name);
  821 + return;
  822 + }
  823 +
  824 + entry_rundown(de);
  825 +
821 826 if (S_ISDIR(de->mode))
822 827 parent->nlink--;
823 828 de->nlink = 0;
... ... @@ -827,4 +832,58 @@
827 832 pde_put(de);
828 833 }
829 834 EXPORT_SYMBOL(remove_proc_entry);
  835 +
  836 +int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
  837 +{
  838 + struct proc_dir_entry **p;
  839 + struct proc_dir_entry *root = NULL, *de, *next;
  840 + const char *fn = name;
  841 + unsigned int len;
  842 +
  843 + spin_lock(&proc_subdir_lock);
  844 + if (__xlate_proc_name(name, &parent, &fn) != 0) {
  845 + spin_unlock(&proc_subdir_lock);
  846 + return -ENOENT;
  847 + }
  848 + len = strlen(fn);
  849 +
  850 + for (p = &parent->subdir; *p; p=&(*p)->next ) {
  851 + if (proc_match(len, fn, *p)) {
  852 + root = *p;
  853 + *p = root->next;
  854 + root->next = NULL;
  855 + break;
  856 + }
  857 + }
  858 + if (!root) {
  859 + spin_unlock(&proc_subdir_lock);
  860 + return -ENOENT;
  861 + }
  862 + de = root;
  863 + while (1) {
  864 + next = de->subdir;
  865 + if (next) {
  866 + de->subdir = next->next;
  867 + next->next = NULL;
  868 + de = next;
  869 + continue;
  870 + }
  871 + spin_unlock(&proc_subdir_lock);
  872 +
  873 + entry_rundown(de);
  874 + next = de->parent;
  875 + if (S_ISDIR(de->mode))
  876 + next->nlink--;
  877 + de->nlink = 0;
  878 + if (de == root)
  879 + break;
  880 + pde_put(de);
  881 +
  882 + spin_lock(&proc_subdir_lock);
  883 + de = next;
  884 + }
  885 + pde_put(root);
  886 + return 0;
  887 +}
  888 +EXPORT_SYMBOL(remove_proc_subtree);
include/linux/proc_fs.h
... ... @@ -117,6 +117,7 @@
117 117 const struct file_operations *proc_fops,
118 118 void *data);
119 119 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
  120 +extern int remove_proc_subtree(const char *name, struct proc_dir_entry *parent);
120 121  
121 122 struct pid_namespace;
122 123  
... ... @@ -202,6 +203,7 @@
202 203 return NULL;
203 204 }
204 205 #define remove_proc_entry(name, parent) do {} while (0)
  206 +#define remove_proc_subtree(name, parent) do {} while (0)
205 207  
206 208 static inline struct proc_dir_entry *proc_symlink(const char *name,
207 209 struct proc_dir_entry *parent,const char *dest) {return NULL;}