diff options
| -rw-r--r-- | arch/ia64/kernel/palinfo.c | 77 | ||||
| -rw-r--r-- | fs/ecryptfs/miscdev.c | 14 | ||||
| -rw-r--r-- | fs/namespace.c | 2 | ||||
| -rw-r--r-- | fs/proc/generic.c | 119 | ||||
| -rw-r--r-- | include/linux/proc_fs.h | 2 | 
5 files changed, 107 insertions, 107 deletions
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 77597e5ea60..79521d5499f 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -849,17 +849,6 @@ static palinfo_entry_t palinfo_entries[]={  #define NR_PALINFO_ENTRIES	(int) ARRAY_SIZE(palinfo_entries) -/* - * this array is used to keep track of the proc entries we create. This is - * required in the module mode when we need to remove all entries. The procfs code - * does not do recursion of deletion - * - * Notes: - *	- +1 accounts for the cpuN directory entry in /proc/pal - */ -#define NR_PALINFO_PROC_ENTRIES	(NR_CPUS*(NR_PALINFO_ENTRIES+1)) - -static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES];  static struct proc_dir_entry *palinfo_dir;  /* @@ -971,60 +960,32 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi  static void __cpuinit  create_palinfo_proc_entries(unsigned int cpu)  { -#	define CPUSTR	"cpu%d" -  	pal_func_cpu_u_t f; -	struct proc_dir_entry **pdir;  	struct proc_dir_entry *cpu_dir;  	int j; -	char cpustr[sizeof(CPUSTR)]; - - -	/* -	 * we keep track of created entries in a depth-first order for -	 * cleanup purposes. Each entry is stored into palinfo_proc_entries -	 */ -	sprintf(cpustr,CPUSTR, cpu); +	char cpustr[3+4+1];	/* cpu numbers are up to 4095 on itanic */ +	sprintf(cpustr, "cpu%d", cpu);  	cpu_dir = proc_mkdir(cpustr, palinfo_dir); +	if (!cpu_dir) +		return;  	f.req_cpu = cpu; -	/* -	 * Compute the location to store per cpu entries -	 * We dont store the top level entry in this list, but -	 * remove it finally after removing all cpu entries. -	 */ -	pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)]; -	*pdir++ = cpu_dir;  	for (j=0; j < NR_PALINFO_ENTRIES; j++) {  		f.func_id = j; -		*pdir = create_proc_read_entry( -				palinfo_entries[j].name, 0, cpu_dir, -				palinfo_read_entry, (void *)f.value); -		pdir++; +		create_proc_read_entry( +			palinfo_entries[j].name, 0, cpu_dir, +			palinfo_read_entry, (void *)f.value);  	}  }  static void  remove_palinfo_proc_entries(unsigned int hcpu)  { -	int j; -	struct proc_dir_entry *cpu_dir, **pdir; - -	pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)]; -	cpu_dir = *pdir; -	*pdir++=NULL; -	for (j=0; j < (NR_PALINFO_ENTRIES); j++) { -		if ((*pdir)) { -			remove_proc_entry ((*pdir)->name, cpu_dir); -			*pdir ++= NULL; -		} -	} - -	if (cpu_dir) { -		remove_proc_entry(cpu_dir->name, palinfo_dir); -	} +	char cpustr[3+4+1];	/* cpu numbers are up to 4095 on itanic */ +	sprintf(cpustr, "cpu%d", hcpu); +	remove_proc_subtree(cpustr, palinfo_dir);  }  static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, @@ -1058,6 +1019,8 @@ palinfo_init(void)  	printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION);  	palinfo_dir = proc_mkdir("pal", NULL); +	if (!palinfo_dir) +		return -ENOMEM;  	/* Create palinfo dirs in /proc for all online cpus */  	for_each_online_cpu(i) { @@ -1073,22 +1036,8 @@ palinfo_init(void)  static void __exit  palinfo_exit(void)  { -	int i = 0; - -	/* remove all nodes: depth first pass. Could optimize this  */ -	for_each_online_cpu(i) { -		remove_palinfo_proc_entries(i); -	} - -	/* -	 * Remove the top level entry finally -	 */ -	remove_proc_entry(palinfo_dir->name, NULL); - -	/* -	 * Unregister from cpu notifier callbacks -	 */  	unregister_hotcpu_notifier(&palinfo_cpu_notifier); +	remove_proc_subtree("pal", NULL);  }  module_init(palinfo_init); diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 412e6eda25f..e4141f25749 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c @@ -80,13 +80,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)  	int rc;  	mutex_lock(&ecryptfs_daemon_hash_mux); -	rc = try_module_get(THIS_MODULE); -	if (rc == 0) { -		rc = -EIO; -		printk(KERN_ERR "%s: Error attempting to increment module use " -		       "count; rc = [%d]\n", __func__, rc); -		goto out_unlock_daemon_list; -	}  	rc = ecryptfs_find_daemon_by_euid(&daemon);  	if (!rc) {  		rc = -EINVAL; @@ -96,7 +89,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)  	if (rc) {  		printk(KERN_ERR "%s: Error attempting to spawn daemon; "  		       "rc = [%d]\n", __func__, rc); -		goto out_module_put_unlock_daemon_list; +		goto out_unlock_daemon_list;  	}  	mutex_lock(&daemon->mux);  	if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { @@ -108,9 +101,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)  	atomic_inc(&ecryptfs_num_miscdev_opens);  out_unlock_daemon:  	mutex_unlock(&daemon->mux); -out_module_put_unlock_daemon_list: -	if (rc) -		module_put(THIS_MODULE);  out_unlock_daemon_list:  	mutex_unlock(&ecryptfs_daemon_hash_mux);  	return rc; @@ -147,7 +137,6 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file)  		       "bug.\n", __func__, rc);  		BUG();  	} -	module_put(THIS_MODULE);  	return rc;  } @@ -471,6 +460,7 @@ out_free:  static const struct file_operations ecryptfs_miscdev_fops = { +	.owner   = THIS_MODULE,  	.open    = ecryptfs_miscdev_open,  	.poll    = ecryptfs_miscdev_poll,  	.read    = ecryptfs_miscdev_read, diff --git a/fs/namespace.c b/fs/namespace.c index d581e45c0a9..341d3f56408 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1690,7 +1690,7 @@ static int do_loopback(struct path *path, const char *old_name,  	if (IS_ERR(mnt)) {  		err = PTR_ERR(mnt); -		goto out; +		goto out2;  	}  	err = graft_tree(mnt, path); diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 4b3b3ffb52f..21e1a8f1659 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -755,37 +755,8 @@ void pde_put(struct proc_dir_entry *pde)  		free_proc_entry(pde);  } -/* - * Remove a /proc entry and free it if it's not currently in use. - */ -void remove_proc_entry(const char *name, struct proc_dir_entry *parent) +static void entry_rundown(struct proc_dir_entry *de)  { -	struct proc_dir_entry **p; -	struct proc_dir_entry *de = NULL; -	const char *fn = name; -	unsigned int len; - -	spin_lock(&proc_subdir_lock); -	if (__xlate_proc_name(name, &parent, &fn) != 0) { -		spin_unlock(&proc_subdir_lock); -		return; -	} -	len = strlen(fn); - -	for (p = &parent->subdir; *p; p=&(*p)->next ) { -		if (proc_match(len, fn, *p)) { -			de = *p; -			*p = de->next; -			de->next = NULL; -			break; -		} -	} -	spin_unlock(&proc_subdir_lock); -	if (!de) { -		WARN(1, "name '%s'\n", name); -		return; -	} -  	spin_lock(&de->pde_unload_lock);  	/*  	 * Stop accepting new callers into module. If you're @@ -817,6 +788,40 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)  		spin_lock(&de->pde_unload_lock);  	}  	spin_unlock(&de->pde_unload_lock); +} + +/* + * Remove a /proc entry and free it if it's not currently in use. + */ +void remove_proc_entry(const char *name, struct proc_dir_entry *parent) +{ +	struct proc_dir_entry **p; +	struct proc_dir_entry *de = NULL; +	const char *fn = name; +	unsigned int len; + +	spin_lock(&proc_subdir_lock); +	if (__xlate_proc_name(name, &parent, &fn) != 0) { +		spin_unlock(&proc_subdir_lock); +		return; +	} +	len = strlen(fn); + +	for (p = &parent->subdir; *p; p=&(*p)->next ) { +		if (proc_match(len, fn, *p)) { +			de = *p; +			*p = de->next; +			de->next = NULL; +			break; +		} +	} +	spin_unlock(&proc_subdir_lock); +	if (!de) { +		WARN(1, "name '%s'\n", name); +		return; +	} + +	entry_rundown(de);  	if (S_ISDIR(de->mode))  		parent->nlink--; @@ -827,3 +832,57 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)  	pde_put(de);  }  EXPORT_SYMBOL(remove_proc_entry); + +int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) +{ +	struct proc_dir_entry **p; +	struct proc_dir_entry *root = NULL, *de, *next; +	const char *fn = name; +	unsigned int len; + +	spin_lock(&proc_subdir_lock); +	if (__xlate_proc_name(name, &parent, &fn) != 0) { +		spin_unlock(&proc_subdir_lock); +		return -ENOENT; +	} +	len = strlen(fn); + +	for (p = &parent->subdir; *p; p=&(*p)->next ) { +		if (proc_match(len, fn, *p)) { +			root = *p; +			*p = root->next; +			root->next = NULL; +			break; +		} +	} +	if (!root) { +		spin_unlock(&proc_subdir_lock); +		return -ENOENT; +	} +	de = root; +	while (1) { +		next = de->subdir; +		if (next) { +			de->subdir = next->next; +			next->next = NULL; +			de = next; +			continue; +		} +		spin_unlock(&proc_subdir_lock); + +		entry_rundown(de); +		next = de->parent; +		if (S_ISDIR(de->mode)) +			next->nlink--; +		de->nlink = 0; +		if (de == root) +			break; +		pde_put(de); + +		spin_lock(&proc_subdir_lock); +		de = next; +	} +	pde_put(root); +	return 0; +} +EXPORT_SYMBOL(remove_proc_subtree); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 8307f2f94d8..94dfb2aa553 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -117,6 +117,7 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,  				const struct file_operations *proc_fops,  				void *data);  extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); +extern int remove_proc_subtree(const char *name, struct proc_dir_entry *parent);  struct pid_namespace; @@ -202,6 +203,7 @@ static inline struct proc_dir_entry *proc_create_data(const char *name,  	return NULL;  }  #define remove_proc_entry(name, parent) do {} while (0) +#define remove_proc_subtree(name, parent) do {} while (0)  static inline struct proc_dir_entry *proc_symlink(const char *name,  		struct proc_dir_entry *parent,const char *dest) {return NULL;}  |