diff options
-rw-r--r-- | fs/proc/generic.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index e5dee5c3188e..ff3ffc76a937 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #include "internal.h" | 27 | #include "internal.h" |
28 | 28 | ||
29 | static DEFINE_SPINLOCK(proc_subdir_lock); | 29 | static DEFINE_RWLOCK(proc_subdir_lock); |
30 | 30 | ||
31 | static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de) | 31 | static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de) |
32 | { | 32 | { |
@@ -172,9 +172,9 @@ static int xlate_proc_name(const char *name, struct proc_dir_entry **ret, | |||
172 | { | 172 | { |
173 | int rv; | 173 | int rv; |
174 | 174 | ||
175 | spin_lock(&proc_subdir_lock); | 175 | read_lock(&proc_subdir_lock); |
176 | rv = __xlate_proc_name(name, ret, residual); | 176 | rv = __xlate_proc_name(name, ret, residual); |
177 | spin_unlock(&proc_subdir_lock); | 177 | read_unlock(&proc_subdir_lock); |
178 | return rv; | 178 | return rv; |
179 | } | 179 | } |
180 | 180 | ||
@@ -231,11 +231,11 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
231 | { | 231 | { |
232 | struct inode *inode; | 232 | struct inode *inode; |
233 | 233 | ||
234 | spin_lock(&proc_subdir_lock); | 234 | read_lock(&proc_subdir_lock); |
235 | de = pde_subdir_find(de, dentry->d_name.name, dentry->d_name.len); | 235 | de = pde_subdir_find(de, dentry->d_name.name, dentry->d_name.len); |
236 | if (de) { | 236 | if (de) { |
237 | pde_get(de); | 237 | pde_get(de); |
238 | spin_unlock(&proc_subdir_lock); | 238 | read_unlock(&proc_subdir_lock); |
239 | inode = proc_get_inode(dir->i_sb, de); | 239 | inode = proc_get_inode(dir->i_sb, de); |
240 | if (!inode) | 240 | if (!inode) |
241 | return ERR_PTR(-ENOMEM); | 241 | return ERR_PTR(-ENOMEM); |
@@ -243,7 +243,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
243 | d_add(dentry, inode); | 243 | d_add(dentry, inode); |
244 | return NULL; | 244 | return NULL; |
245 | } | 245 | } |
246 | spin_unlock(&proc_subdir_lock); | 246 | read_unlock(&proc_subdir_lock); |
247 | return ERR_PTR(-ENOENT); | 247 | return ERR_PTR(-ENOENT); |
248 | } | 248 | } |
249 | 249 | ||
@@ -270,12 +270,12 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *file, | |||
270 | if (!dir_emit_dots(file, ctx)) | 270 | if (!dir_emit_dots(file, ctx)) |
271 | return 0; | 271 | return 0; |
272 | 272 | ||
273 | spin_lock(&proc_subdir_lock); | 273 | read_lock(&proc_subdir_lock); |
274 | de = pde_subdir_first(de); | 274 | de = pde_subdir_first(de); |
275 | i = ctx->pos - 2; | 275 | i = ctx->pos - 2; |
276 | for (;;) { | 276 | for (;;) { |
277 | if (!de) { | 277 | if (!de) { |
278 | spin_unlock(&proc_subdir_lock); | 278 | read_unlock(&proc_subdir_lock); |
279 | return 0; | 279 | return 0; |
280 | } | 280 | } |
281 | if (!i) | 281 | if (!i) |
@@ -287,19 +287,19 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *file, | |||
287 | do { | 287 | do { |
288 | struct proc_dir_entry *next; | 288 | struct proc_dir_entry *next; |
289 | pde_get(de); | 289 | pde_get(de); |
290 | spin_unlock(&proc_subdir_lock); | 290 | read_unlock(&proc_subdir_lock); |
291 | if (!dir_emit(ctx, de->name, de->namelen, | 291 | if (!dir_emit(ctx, de->name, de->namelen, |
292 | de->low_ino, de->mode >> 12)) { | 292 | de->low_ino, de->mode >> 12)) { |
293 | pde_put(de); | 293 | pde_put(de); |
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | spin_lock(&proc_subdir_lock); | 296 | read_lock(&proc_subdir_lock); |
297 | ctx->pos++; | 297 | ctx->pos++; |
298 | next = pde_subdir_next(de); | 298 | next = pde_subdir_next(de); |
299 | pde_put(de); | 299 | pde_put(de); |
300 | de = next; | 300 | de = next; |
301 | } while (de); | 301 | } while (de); |
302 | spin_unlock(&proc_subdir_lock); | 302 | read_unlock(&proc_subdir_lock); |
303 | return 1; | 303 | return 1; |
304 | } | 304 | } |
305 | 305 | ||
@@ -338,16 +338,16 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp | |||
338 | if (ret) | 338 | if (ret) |
339 | return ret; | 339 | return ret; |
340 | 340 | ||
341 | spin_lock(&proc_subdir_lock); | 341 | write_lock(&proc_subdir_lock); |
342 | dp->parent = dir; | 342 | dp->parent = dir; |
343 | if (pde_subdir_insert(dir, dp) == false) { | 343 | if (pde_subdir_insert(dir, dp) == false) { |
344 | WARN(1, "proc_dir_entry '%s/%s' already registered\n", | 344 | WARN(1, "proc_dir_entry '%s/%s' already registered\n", |
345 | dir->name, dp->name); | 345 | dir->name, dp->name); |
346 | spin_unlock(&proc_subdir_lock); | 346 | write_unlock(&proc_subdir_lock); |
347 | proc_free_inum(dp->low_ino); | 347 | proc_free_inum(dp->low_ino); |
348 | return -EEXIST; | 348 | return -EEXIST; |
349 | } | 349 | } |
350 | spin_unlock(&proc_subdir_lock); | 350 | write_unlock(&proc_subdir_lock); |
351 | 351 | ||
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
@@ -549,9 +549,9 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
549 | const char *fn = name; | 549 | const char *fn = name; |
550 | unsigned int len; | 550 | unsigned int len; |
551 | 551 | ||
552 | spin_lock(&proc_subdir_lock); | 552 | write_lock(&proc_subdir_lock); |
553 | if (__xlate_proc_name(name, &parent, &fn) != 0) { | 553 | if (__xlate_proc_name(name, &parent, &fn) != 0) { |
554 | spin_unlock(&proc_subdir_lock); | 554 | write_unlock(&proc_subdir_lock); |
555 | return; | 555 | return; |
556 | } | 556 | } |
557 | len = strlen(fn); | 557 | len = strlen(fn); |
@@ -559,7 +559,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
559 | de = pde_subdir_find(parent, fn, len); | 559 | de = pde_subdir_find(parent, fn, len); |
560 | if (de) | 560 | if (de) |
561 | rb_erase(&de->subdir_node, &parent->subdir); | 561 | rb_erase(&de->subdir_node, &parent->subdir); |
562 | spin_unlock(&proc_subdir_lock); | 562 | write_unlock(&proc_subdir_lock); |
563 | if (!de) { | 563 | if (!de) { |
564 | WARN(1, "name '%s'\n", name); | 564 | WARN(1, "name '%s'\n", name); |
565 | return; | 565 | return; |
@@ -583,16 +583,16 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) | |||
583 | const char *fn = name; | 583 | const char *fn = name; |
584 | unsigned int len; | 584 | unsigned int len; |
585 | 585 | ||
586 | spin_lock(&proc_subdir_lock); | 586 | write_lock(&proc_subdir_lock); |
587 | if (__xlate_proc_name(name, &parent, &fn) != 0) { | 587 | if (__xlate_proc_name(name, &parent, &fn) != 0) { |
588 | spin_unlock(&proc_subdir_lock); | 588 | write_unlock(&proc_subdir_lock); |
589 | return -ENOENT; | 589 | return -ENOENT; |
590 | } | 590 | } |
591 | len = strlen(fn); | 591 | len = strlen(fn); |
592 | 592 | ||
593 | root = pde_subdir_find(parent, fn, len); | 593 | root = pde_subdir_find(parent, fn, len); |
594 | if (!root) { | 594 | if (!root) { |
595 | spin_unlock(&proc_subdir_lock); | 595 | write_unlock(&proc_subdir_lock); |
596 | return -ENOENT; | 596 | return -ENOENT; |
597 | } | 597 | } |
598 | rb_erase(&root->subdir_node, &parent->subdir); | 598 | rb_erase(&root->subdir_node, &parent->subdir); |
@@ -605,7 +605,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) | |||
605 | de = next; | 605 | de = next; |
606 | continue; | 606 | continue; |
607 | } | 607 | } |
608 | spin_unlock(&proc_subdir_lock); | 608 | write_unlock(&proc_subdir_lock); |
609 | 609 | ||
610 | proc_entry_rundown(de); | 610 | proc_entry_rundown(de); |
611 | next = de->parent; | 611 | next = de->parent; |
@@ -616,7 +616,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) | |||
616 | break; | 616 | break; |
617 | pde_put(de); | 617 | pde_put(de); |
618 | 618 | ||
619 | spin_lock(&proc_subdir_lock); | 619 | write_lock(&proc_subdir_lock); |
620 | de = next; | 620 | de = next; |
621 | } | 621 | } |
622 | pde_put(root); | 622 | pde_put(root); |