[<prev] [next>] [day] [month] [year] [list]
Message-ID: <169128520941.68052.15749253469930138901.stgit@donald.themaw.net>
Date: Sun, 06 Aug 2023 09:26:49 +0800
From: Ian Kent <raven@...maw.net>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Tejun Heo <tj@...nel.org>
Cc: Kernel Mailing List <linux-kernel@...r.kernel.org>,
Imran Khan <imran.f.khan@...cle.com>,
Miklos Szeredi <mszeredi@...hat.com>,
Arnd Bergmann <arnd@...db.de>,
Anders Roxell <anders.roxell@...aro.org>,
Minchan Kim <minchan@...nel.org>,
Eric Sandeen <sandeen@...deen.net>
Subject: [PATCH] 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: 9caf696142 (kernfs: Introduce separate rwsem to protect inode
attributes)
Signed-off-by: Ian Kent <raven@...maw.net>
Reviewed-By: Imran Khan <imran.f.khan@...cle.com>
Acked-by: Miklos Szeredi <mszeredi@...hat.com>
Cc: Anders Roxell <anders.roxell@...aro.org>
Cc: Arnd Bergmann <arnd@...db.de>
Cc: Minchan Kim <minchan@...nel.org>
Cc: Eric Sandeen <sandeen@...deen.net>
---
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);
Powered by blists - more mailing lists