All it requires is making sure that d_walk() will skip *all* CURSOR dentries, even if somebody passes it one as an argument. Cursors are negative and unhashed all along, never get added to LRU or to shrink lists and no RCU references via ->d_sib are possible for those - dentry_unlist() makes sure that no killed dentry has ->d_sib.next left pointing to a cursor. Seeing that a cursor is allocated every time we open a directory on autofs, debugfs, devpts, etc., avoiding an RCU delay when such opened files get closed is attractive... Signed-off-by: Al Viro --- fs/dcache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/dcache.c b/fs/dcache.c index 2b5cf6e52ed6..f64a02998184 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1429,6 +1429,8 @@ static void d_walk(struct dentry *parent, void *data, read_seqbegin_or_lock(&rename_lock, &seq); this_parent = parent; spin_lock(&this_parent->d_lock); + if (unlikely(this_parent->d_flags & DCACHE_DENTRY_CURSOR)) + goto out_unlock; ret = enter(data, this_parent); switch (ret) { @@ -1982,7 +1984,7 @@ struct dentry *d_alloc_cursor(struct dentry * parent) { struct dentry *dentry = d_alloc_anon(parent->d_sb); if (dentry) { - dentry->d_flags |= DCACHE_DENTRY_CURSOR; + dentry->d_flags |= DCACHE_DENTRY_CURSOR | DCACHE_NORCU; dentry->d_parent = dget(parent); } return dentry; -- 2.47.3