Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 362349
b: refs/heads/master
c: 8ce584c
h: refs/heads/master
i:
  362347: 417cae4
v: v3
  • Loading branch information
Al Viro committed Apr 9, 2013
1 parent 06e98fa commit c303e3c
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 52f21999c7b921a0390708b66ed286282c2e4bee
refs/heads/master: 8ce584c7416d8a85a6f3edc17d1cddefe331e87e
119 changes: 89 additions & 30 deletions trunk/fs/proc/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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--;
Expand All @@ -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);
2 changes: 2 additions & 0 deletions trunk/include/linux/proc_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;}
Expand Down

0 comments on commit c303e3c

Please sign in to comment.