|
17 | 17 |
|
18 | 18 | #include "kernfs-internal.h"
|
19 | 19 |
|
20 |
| -DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */ |
21 | 20 | /*
|
22 | 21 | * Don't use rename_lock to piggy back on pr_cont_buf. We don't want to
|
23 | 22 | * call pr_cont() while holding rename_lock. Because sometimes pr_cont()
|
@@ -228,7 +227,7 @@ int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
|
228 | 227 | if (to) {
|
229 | 228 | root = kernfs_root(to);
|
230 | 229 | if (!(root->flags & KERNFS_ROOT_INVARIANT_PARENT)) {
|
231 |
| - guard(read_lock_irqsave)(&kernfs_rename_lock); |
| 230 | + guard(read_lock_irqsave)(&root->kernfs_rename_lock); |
232 | 231 | return kernfs_path_from_node_locked(to, from, buf, buflen);
|
233 | 232 | }
|
234 | 233 | }
|
@@ -295,12 +294,14 @@ void pr_cont_kernfs_path(struct kernfs_node *kn)
|
295 | 294 | struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn)
|
296 | 295 | {
|
297 | 296 | struct kernfs_node *parent;
|
| 297 | + struct kernfs_root *root; |
298 | 298 | unsigned long flags;
|
299 | 299 |
|
300 |
| - read_lock_irqsave(&kernfs_rename_lock, flags); |
| 300 | + root = kernfs_root(kn); |
| 301 | + read_lock_irqsave(&root->kernfs_rename_lock, flags); |
301 | 302 | parent = kernfs_parent(kn);
|
302 | 303 | kernfs_get(parent);
|
303 |
| - read_unlock_irqrestore(&kernfs_rename_lock, flags); |
| 304 | + read_unlock_irqrestore(&root->kernfs_rename_lock, flags); |
304 | 305 |
|
305 | 306 | return parent;
|
306 | 307 | }
|
@@ -993,6 +994,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
|
993 | 994 | init_rwsem(&root->kernfs_iattr_rwsem);
|
994 | 995 | init_rwsem(&root->kernfs_supers_rwsem);
|
995 | 996 | INIT_LIST_HEAD(&root->supers);
|
| 997 | + rwlock_init(&root->kernfs_rename_lock); |
996 | 998 |
|
997 | 999 | /*
|
998 | 1000 | * On 64bit ino setups, id is ino. On 32bit, low 32bits are ino.
|
@@ -1789,15 +1791,15 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
1789 | 1791 | /* rename_lock protects ->parent accessors */
|
1790 | 1792 | if (old_parent != new_parent) {
|
1791 | 1793 | kernfs_get(new_parent);
|
1792 |
| - write_lock_irq(&kernfs_rename_lock); |
| 1794 | + write_lock_irq(&root->kernfs_rename_lock); |
1793 | 1795 |
|
1794 | 1796 | rcu_assign_pointer(kn->__parent, new_parent);
|
1795 | 1797 |
|
1796 | 1798 | kn->ns = new_ns;
|
1797 | 1799 | if (new_name)
|
1798 | 1800 | rcu_assign_pointer(kn->name, new_name);
|
1799 | 1801 |
|
1800 |
| - write_unlock_irq(&kernfs_rename_lock); |
| 1802 | + write_unlock_irq(&root->kernfs_rename_lock); |
1801 | 1803 | kernfs_put(old_parent);
|
1802 | 1804 | } else {
|
1803 | 1805 | /* name assignment is RCU protected, parent is the same */
|
|
0 commit comments