kernfs: fix missing kernfs_iattr_rwsem locking
JIRA: https://issues.redhat.com/browse/RHEL-52956 Upstream status: Linus commit 0559f63057f927d298d68294d6ff77ce09b99255 Author: Ian Kent <raven@themaw.net> Date: Sun Aug 6 09:26:49 2023 +0800 kernfs: fix missing kernfs_iattr_rwsem locking When the kernfs_iattr_rwsem was introduced a case was missed. The update of the kernfs directory node child count was also protected by the kernfs_rwsem and needs to be included in the change so that the child count (and so the inode n_link attribute) does not change while holding the rwsem for read. Fixes: 9caf69614225 ("kernfs: Introduce separate rwsem to protect inode attributes.") Cc: stable <stable@kernel.org> Signed-off-by: Ian Kent <raven@themaw.net> Reviewed-By: Imran Khan <imran.f.khan@oracle.com> Acked-by: Miklos Szeredi <mszeredi@redhat.com> Cc: Anders Roxell <anders.roxell@linaro.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Minchan Kim <minchan@kernel.org> Cc: Eric Sandeen <sandeen@sandeen.net> Link: https://lore.kernel.org/r/169128520941.68052.15749253469930138901.stgit@donald.themaw.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Ian Kent <ikent@redhat.com>
This commit is contained in:
parent
cafaee9ad8
commit
e203ef12dc
|
@ -374,9 +374,11 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
|
||||||
rb_insert_color(&kn->rb, &kn->parent->dir.children);
|
rb_insert_color(&kn->rb, &kn->parent->dir.children);
|
||||||
|
|
||||||
/* successfully added, account subdir number */
|
/* successfully added, account subdir number */
|
||||||
|
down_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
|
||||||
if (kernfs_type(kn) == KERNFS_DIR)
|
if (kernfs_type(kn) == KERNFS_DIR)
|
||||||
kn->parent->dir.subdirs++;
|
kn->parent->dir.subdirs++;
|
||||||
kernfs_inc_rev(kn->parent);
|
kernfs_inc_rev(kn->parent);
|
||||||
|
up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -397,9 +399,11 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn)
|
||||||
if (RB_EMPTY_NODE(&kn->rb))
|
if (RB_EMPTY_NODE(&kn->rb))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
down_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
|
||||||
if (kernfs_type(kn) == KERNFS_DIR)
|
if (kernfs_type(kn) == KERNFS_DIR)
|
||||||
kn->parent->dir.subdirs--;
|
kn->parent->dir.subdirs--;
|
||||||
kernfs_inc_rev(kn->parent);
|
kernfs_inc_rev(kn->parent);
|
||||||
|
up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
|
||||||
|
|
||||||
rb_erase(&kn->rb, &kn->parent->dir.children);
|
rb_erase(&kn->rb, &kn->parent->dir.children);
|
||||||
RB_CLEAR_NODE(&kn->rb);
|
RB_CLEAR_NODE(&kn->rb);
|
||||||
|
|
Loading…
Reference in New Issue