proc: do translation + unlink atomically at remove_proc_entry()
Subsystems (2)
PATCH 1/2 proc: do translation + unlink atomically at remove_proc_entry()
remove_proc_entry() does
lock
lookup parent
unlock
lock
unlink proc entry from lists
unlock
which can be made bit more correct by doing parent translation + unlink without dropping lock.
Signed-off-by Alexey Dobriyan <[email protected]>
---
fs/proc/generic.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
fs/proc/generic.c +19 -12
@@ -291,19 +291,17 @@ static const struct inode_operations proc_file_inode_operations = {* returns the struct proc_dir_entry for "/proc/tty/driver", and * returns "serial" in residual. */ -static int xlate_proc_name (const char *name, -struct proc_dir_entry **ret,const char **residual) +static int __xlate_proc_name (const char *name,struct proc_dir_entry **ret, +const char **residual) {const char *cp = name, *next;struct proc_dir_entry *de;int len; -int rtn =0 ; de = *ret;if (!de) de = &proc_root; -spin_lock (&proc_subdir_lock);while (1 ) { next =strchr (cp,'/' );if (!next)
@@ -314,17 +312,24 @@ static int xlate_proc_name(const char *name,if (proc_match (len, cp, de))break ; } -if (!de) { - rtn = -ENOENT ; - goto out; - } +if (!de) +return -ENOENT ; cp += len +1 ; } *residual = cp; *ret = de; -out: +return 0 ; +} + +static int xlate_proc_name (const char *name,struct proc_dir_entry **ret, +const char **residual) +{ +int rv; + +spin_lock (&proc_subdir_lock); + rv =__xlate_proc_name (name, ret, residual);spin_unlock (&proc_subdir_lock); -return rtn; +return rv; }static DEFINE_IDA (proc_inum_ida);
@@ -793,11 +798,13 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)const char *fn = name;int len; -if (xlate_proc_name (name, &parent, &fn) !=0 ) +spin_lock (&proc_subdir_lock); +if (__xlate_proc_name (name, &parent, &fn) !=0 ) { +spin_unlock (&proc_subdir_lock);return ; + } len =strlen (fn); -spin_lock (&proc_subdir_lock);for (p = &parent->subdir; *p; p=&(*p)->next ) {if (proc_match (len, fn, *p)) { de = *p;