mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-25 16:11:45 +00:00
kernfs: associate a new kernfs_node with its parent on creation
Once created, a kernfs_node is always destroyed by kernfs_put().
Since ba7443bc65
("sysfs, kernfs: implement
kernfs_create/destroy_root()"), kernfs_put() depends on kernfs_root()
to locate the ino_ida. kernfs_root() in turn depends on
kernfs_node->parent being set for !dir nodes. This means that
kernfs_put() of a !dir node requires its ->parent to be initialized.
This leads to oops when a newly created !dir node is destroyed without
going through kernfs_add_one() or after failing kernfs_add_one()
before ->parent is set. kernfs_root() invoked from kernfs_put() will
try to dereference NULL parent.
Fix it by moving parent association to kernfs_new_node() from
kernfs_add_one(). kernfs_new_node() now takes @parent instead of
@root and determines the root from the parent and also sets the new
node's parent properly. @parent parameter is removed from
kernfs_add_one(). As there's no parent when creating the root node,
__kernfs_new_node() which takes @root as before and doesn't set the
parent is used in that case.
This ensures that a kernfs_node in any stage in its life has its
parent associated and thus can be put.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
917f56caaa
commit
db4aad209b
4 changed files with 34 additions and 24 deletions
|
@ -829,8 +829,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
|
|||
if (name_is_static)
|
||||
flags |= KERNFS_STATIC_NAME;
|
||||
|
||||
kn = kernfs_new_node(kernfs_root(parent), name,
|
||||
(mode & S_IALLUGO) | S_IFREG, flags);
|
||||
kn = kernfs_new_node(parent, name, (mode & S_IALLUGO) | S_IFREG, flags);
|
||||
if (!kn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -857,7 +856,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
|
|||
kn->flags |= KERNFS_HAS_MMAP;
|
||||
|
||||
kernfs_addrm_start(&acxt);
|
||||
rc = kernfs_add_one(&acxt, kn, parent);
|
||||
rc = kernfs_add_one(&acxt, kn);
|
||||
kernfs_addrm_finish(&acxt);
|
||||
|
||||
if (rc) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue