6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Kent raven@themaw.net
commit 0559f63057f927d298d68294d6ff77ce09b99255 upstream.
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@dona... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/kernfs/dir.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 5a1a4af9d3d2..bf243015834e 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -383,9 +383,11 @@ static int kernfs_link_sibling(struct kernfs_node *kn) rb_insert_color(&kn->rb, &kn->parent->dir.children);
/* successfully added, account subdir number */ + down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs++; kernfs_inc_rev(kn->parent); + up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
return 0; } @@ -408,9 +410,11 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn) if (RB_EMPTY_NODE(&kn->rb)) return false;
+ down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; kernfs_inc_rev(kn->parent); + up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
rb_erase(&kn->rb, &kn->parent->dir.children); RB_CLEAR_NODE(&kn->rb);