All of lore.kernel.org
 help / color / mirror / Atom feed
* [RESEND PATCH v2] kernfs: fix dentry unexpected skip
@ 2018-05-28 12:54 Hatayama, Daisuke
  2018-05-28 13:08 ` Hatayama, Daisuke
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Hatayama, Daisuke @ 2018-05-28 12:54 UTC (permalink / raw)
  To: 'gregkh@linuxfoundation.org', 'tj@kernel.org'
  Cc: Okajima, Toshiyuki, linux-kernel, 'ebiederm@aristanetworks.com'

kernfs_dir_next_pos() overlooks the situation that the dentry
corresponding to a given pos object has already been inactive. Hence,
when kernfs_dir_pos() returns the dentry with a hash value larger than
the original one, kernfs_dir_next_pos() returns the dentry next to the
one returned by kernfs_dir_pos(). As a result, the dentry returned by
kernfs_dir_pos() is skipped.

To fix this issue, try to find a next node only when the returned
object is less than or equal to the original one.

Note that this implementation focuses on getting guarantee that the
existing nodes are never skipped, not interested in the other nodes
that are added or removed during the process.

We found this issue during a stress test that repeatedly reads
/sys/module directory to get a list of the currently loaded kernel
modules while repeatedly loading and unloading kernel modules
simultaneously.

v2: Fix the case where nodes with the same hash but with the name
    larger than the original node could still be skipped. Use
    kernfs_sd_compare() to compare kernfs_node objects. Imporove patch
    description.

Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Suggested-by: Toshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
Cc: Eric W. Biederman <ebiederm@aristanetworks.com>
---
 fs/kernfs/dir.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 89d1dc1..3aeeb7a 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1621,8 +1621,10 @@ static int kernfs_dir_fop_release(struct inode *inode, struct file *filp)
 static struct kernfs_node *kernfs_dir_next_pos(const void *ns,
 	struct kernfs_node *parent, ino_t ino, struct kernfs_node *pos)
 {
+	struct kernfs_node *orig = pos;
+
 	pos = kernfs_dir_pos(ns, parent, ino, pos);
-	if (pos) {
+	if (pos && kernfs_sd_compare(pos, orig) <= 0) {
 		do {
 			struct rb_node *node = rb_next(&pos->rb);
 			if (!node)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2018-06-07 18:36 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-28 12:54 [RESEND PATCH v2] kernfs: fix dentry unexpected skip Hatayama, Daisuke
2018-05-28 13:08 ` Hatayama, Daisuke
2018-05-29 16:26 ` 'tj@kernel.org'
2018-06-01  9:25   ` Hatayama, Daisuke
2018-06-01 17:07     ` 'tj@kernel.org'
2018-06-04  9:46       ` Hatayama, Daisuke
2018-06-02 17:25 ` Eric W. Biederman
2018-06-03 18:51   ` [CFT][PATCH] kernfs: Correct kernfs directory seeks Eric W. Biederman
2018-06-04  9:34     ` Hatayama, Daisuke
2018-06-04 14:44       ` Eric W. Biederman
2018-06-05  2:02         ` Eric W. Biederman
2018-06-05  5:52           ` Hatayama, Daisuke
2018-06-05  5:45         ` Hatayama, Daisuke
2018-06-05 15:31           ` Eric W. Biederman
2018-06-05 15:42             ` 'tj@kernel.org'
2018-06-05 17:47               ` Eric W. Biederman
2018-06-07 18:36                 ` Al Viro

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.