|
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