From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 403512D77E6; Sat, 15 Aug 2026 04:28:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768103; cv=none; b=MSTNi31Ltw5ZtuUcywHEz6nG8AbwntRDKQdyfuh2tC8msGQLTRBXK/+OriYIZQz0dYuiL5vdang/NdJirSl0gT2omfoE/CjIhYgI0Spjy5pe+FW0FOgxWl5QJ1ggzPyUNZN4j5gmrewKBz1SltLJ9lebNGypdvRCXfEoHVgqS+M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768103; c=relaxed/simple; bh=CqMFuZ3pzG+/7E/ejH9BKoyQXHKBIfn5fWqIQ6sInLc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i59tGy2+DTMqK2+jCEvEbYjzl6RQOz2eVy7gXhDMU6BUxT86cqfdyjZd10kfVU+xsSda9NwqsgNno8RrAg5s1/s+YrFrNQ7I01u+atnRmpvxsZjkzr/iSMr1d5BsHJJbFNNGuYdH7mOIg3PsrS3Kg7A2D24fxZyMuP0ky0Ug5Sg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=WBmtwnu9; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=M7sTg89Q; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="WBmtwnu9"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="M7sTg89Q" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailflow.phl.internal (Postfix) with ESMTP id 6ADD013803F8; Sat, 15 Aug 2026 00:28:20 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-06.internal (MEProxy); Sat, 15 Aug 2026 00:28:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768100; x=1786775300; bh=+JhGCUNFMj7JKQCtgUbCKJqkxMSu7hV462ntB5fltj8=; b= WBmtwnu9grbU9MYGLvFiQ34CNP/ce343WNKHd0uUKE7K4U/RQaX4eOS5j+u8V0DJ 0NTjYvwKn91C6/usK6IpifIDingbwTDAoUVkaYuQs4m2R6Q5q802L2m75rZ02h7u VXvOJe1mJuYBIuEws0orroi7Ky5MqPGpeuGuM+AEhVk8WSHtbozueAKAZhOenKJg gBWpmE7zgpPibOVE5wqKqMOP0aKp/MJqBnFvihBO+nbOnMoSKv2gRWHzLEOLJSzx spZJ5ymX9+q7c2onqdm8+C8D0gFQmrJI/CpsoZfKb73zyqP+36Jc9albg+OBZUAG nE/baWffKmnIeM8UJqbI6Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768100; x=1786775300; bh=+ JhGCUNFMj7JKQCtgUbCKJqkxMSu7hV462ntB5fltj8=; b=M7sTg89QucaM4zPH5 GHCpotQIrWqZxKxSwJ9x5TxwzTtOCq6Blqp3aEWgyDiXMjQI1GXj6mSN4DgkdCm3 2wi+m4LjlQHeKZIfRshB0DYCPMXEDqJkCWtv8GQIWKog6osIG6hmEkUC9U+aZb1e Wr9I2WJSGm7I3vX+TpZEDCkeKzDr4nQ7WpHJtPBrzcJW2guv+dUpOPt8kGvzWWT+ xfEMBtGFHLZf7yRW0ZR5UP8/6KRgUKop24muIGjf2Q+4kvT0C7E2ASmrtc7mAsy6 /5YEs6EPbwVqewYC3w2CqNXaKuhcyL0sw5GocVJHzyqpWcOKGpIt0nJKGXufsIU1 4zJXw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTF9KskX6ORZkk2qDbanJAqhpO1c3Xju1rB/XGbwQvOGWemlAS7RTfehH6z/blxuZu ndq9JpuBON/sKJpHNFmlA8NZthzZuohefFsXvvzkhDLNc/boPY1CbYwGZ3ejocQdZP5Ev/ BXLTdsGGIGk/QWYctoHjfRUZGHXRv5et6FUSLml8RkvDkfsb7WSgppX3LyXjWcFTLwfp/k XOfgf9r/SZsCIW4bEY4xzTmE8sCd1BMMrUIBiSLPUM5HPZAu9IGndquxD0N2k1kJS4EkJO uSSxartPr+p/2sBY7kb8VaiOyCHt8JoqHMJjX2cNsGCbf1T449z1owAvKjvcnWl37FvYNI 5V2Fq5xnU4qiJ86juIkAnHH/ib4mvr1oRQ5r5JT9yS74qMtPQWW9MrI/LVsQJRYLBzoCdd wPAZVvts902FpM1rjp5wDya9Oc72p9a+x4jknzOZP5KTMxATsXh+TgaW5dKEsKdGXvW5P1 cSOg5rJ2EpdK8GR5Cq2nAmz5H2q9Lqxyd9qh/za82UZ/kSoFh4C7QnTnbU7IgxSI79vRf0 n/CBg8V0DSdsssnNFxBDrCUUaPN4iZgdClqQtkJM8aGns92G+LLIhz4yjunDp5V3SLmuDX f9uR8Bs2aqePXaFNkGKpByEVboIh3iFkcfIhuUSyGgH+vr3FMir2iQLltzhQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:28:13 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 01/18] VFS: don't count references through ->d_parent Date: Sat, 15 Aug 2026 14:21:18 +1000 Message-ID: <20260815042707.2535717-2-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown The number of negative child dentries that a given dentry can have is effectively unbounded, so counting the references through ->d_parent can overflow ->d_lockref.count. We only use this count so that we can know when there are no remaining references including from children. However most children appear on the ->d_children list and the few remaining children (inactive DCACHE_DENTRY_CURSORs) only exist in a context were a separate reference is held on the parent. So if we count whether d_children is nonempty (i.e. dget() when it becomes non-empty, dput() when it comes empty) and require children not on ->d_children to have a reference on the parent some other way (which they already do), then ->d_lockref.count will not overflow and we can still know exactly when all references, including through ->d_parent, are gone. __d_move() allows that dentries might not be on any d_children list as is the case for IS_ROOT() dentries. Rather than track when this is the case we dget() either parent if they have an empty d_children before children are moved around, then dput() if they turn out to be empty afterwards. This will increment dentry if it IS_ROOT(), and then decrement it afterwards, and will decrement the refcount on old_parent if its ->d_children becomes empty. To help with this, dput_dlock() is added which warns rather than decrementing to zero (which should never happen). When a DCACHE_CURSOR dentry is added to d_children, it is only ever added "before" or "behind" an existing child, so it will never be the first and so never needs to adjust the refcount on the parent. If it remains on the list until dput() it could be the last child to be removed, in which case normal handling applies in dentry_unlist() (where it has been moved from dentry_kill(). When a cursor is deliberately removed from the d_children list the refcount must be decremented if that leaves the list empty. hlist_move_behind() and hlist_move_before() are added to simplify moving a cursor within the d_children list. This result in some duplicate code as they share a common prefix with d_detach_cursor() (hlist_del) which is currently factored out. We can expect the compiler to optimise this away and don't need to clutter the C code with it. Signed-off-by: NeilBrown --- fs/dcache.c | 40 +++++++++++++++++++++++++++++++++------- fs/internal.h | 10 ++++++++++ fs/libfs.c | 14 +++++++------- include/linux/dcache.h | 17 ++++++++++++++++- include/linux/list.h | 30 ++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 15 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 3e9af9de7074..ae726f3ff0cb 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -670,6 +670,8 @@ static inline void dentry_unlist(struct dentry *dentry) return; } __hlist_del(&dentry->d_sib); + if (hlist_empty(&dentry->d_parent->d_children)) + dentry->d_parent->d_lockref.count--; /* * Cursors can move around the list of children. While we'd been * a normal list member, it didn't matter - ->d_sib.next would've @@ -843,7 +845,7 @@ static struct dentry *dentry_kill(struct dentry *dentry) spin_unlock(&dentry->d_lock); if (likely(can_free)) dentry_free(dentry); - if (parent && --parent->d_lockref.count) { + if (parent && parent->d_lockref.count) { spin_unlock(&parent->d_lock); return NULL; } @@ -1986,7 +1988,9 @@ struct dentry *d_alloc(struct dentry * parent, const = struct qstr *name) * don't need child lock because it is not subject * to concurrency here */ - dentry->d_parent =3D dget_dlock(parent); + dentry->d_parent =3D parent; + if (hlist_empty(&parent->d_children)) + dget_dlock(parent); hlist_add_head(&dentry->d_sib, &parent->d_children); spin_unlock(&parent->d_lock); =20 @@ -2005,7 +2009,7 @@ struct dentry *d_alloc_cursor(struct dentry * parent) struct dentry *dentry =3D d_alloc_anon(parent->d_sb); if (dentry) { dentry->d_flags |=3D DCACHE_DENTRY_CURSOR | DCACHE_NORCU; - dentry->d_parent =3D dget(parent); + dentry->d_parent =3D parent; } return dentry; } @@ -2767,7 +2771,9 @@ struct dentry *d_alloc_parallel(struct dentry *parent, =20 new->d_flags |=3D DCACHE_PAR_LOOKUP; spin_lock(&parent->d_lock); - new->d_parent =3D dget_dlock(parent); + new->d_parent =3D parent; + if (hlist_empty(&parent->d_children)) + dget_dlock(parent); hlist_add_head(&new->d_sib, &parent->d_children); if (parent->d_flags & DCACHE_DISCONNECTED) new->d_flags |=3D DCACHE_DISCONNECTED; @@ -3095,12 +3101,21 @@ static void __d_move(struct dentry *dentry, struct = dentry *target, =20 /* ... and switch them in the tree */ dentry->d_parent =3D target->d_parent; + + /* + * Ensure ref count on parents reflect d_children being non-empty, + * which they almost certainly are. If either end up being empty, + * this is handled below after the moves. + */ + if (hlist_empty(&old_parent->d_children)) + dget_dlock(old_parent); + if (dentry->d_parent !=3D old_parent && + hlist_empty(&dentry->d_parent->d_children)) + dget_dlock(dentry->d_parent); + if (!exchange) { copy_name(dentry, target); target->d_hash.pprev =3D NULL; - dentry->d_parent->d_lockref.count++; - if (dentry !=3D old_parent) /* wasn't IS_ROOT */ - WARN_ON(!--old_parent->d_lockref.count); } else { target->d_parent =3D old_parent; swap_names(dentry, target); @@ -3113,6 +3128,17 @@ static void __d_move(struct dentry *dentry, struct d= entry *target, if (!hlist_unhashed(&dentry->d_sib)) __hlist_del(&dentry->d_sib); hlist_add_head(&dentry->d_sib, &dentry->d_parent->d_children); + + /* + * Adjust parent refcounts if either d_children ended up empty. + * This should only ever be old_parent. + */ + if (hlist_empty(&old_parent->d_children)) + dput_dlock(old_parent); + if (dentry->d_parent !=3D old_parent && + hlist_empty(&dentry->d_parent->d_children)) + dput_dlock(dentry->d_parent); + __d_rehash(dentry); fsnotify_update_flags(dentry); fscrypt_handle_d_move(dentry); diff --git a/fs/internal.h b/fs/internal.h index 355d93f92208..8646fd6d55ef 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -234,6 +234,16 @@ extern struct dentry *__d_lookup(const struct dentry *= , const struct qstr *); extern struct dentry *__d_lookup_rcu(const struct dentry *parent, const struct qstr *name, unsigned *seq); =20 +static inline void d_detach_cursor(struct dentry *cursor) +{ + if (hlist_unhashed(&cursor->d_sib)) + return; + hlist_del_init(&cursor->d_sib); + if (hlist_empty(&cursor->d_parent->d_children)) + /* That was the last child, must drop implied reference */ + dput_dlock(cursor->d_parent); +} + /* * pipe.c */ diff --git a/fs/libfs.c b/fs/libfs.c index 5a0d276379d1..7cd816b8e2a0 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -128,9 +128,7 @@ static struct dentry *scan_positives(struct dentry *cur= sor, count =3D 1; } if (need_resched()) { - if (!hlist_unhashed(&cursor->d_sib)) - __hlist_del(&cursor->d_sib); - hlist_add_behind(&cursor->d_sib, &d->d_sib); + hlist_move_behind(&cursor->d_sib, &d->d_sib); p =3D &cursor->d_sib.next; spin_unlock(&dentry->d_lock); cond_resched(); @@ -166,9 +164,10 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offs= et, int whence) to =3D scan_positives(cursor, &dentry->d_children.first, offset - 2, NULL); spin_lock(&dentry->d_lock); - hlist_del_init(&cursor->d_sib); if (to) - hlist_add_behind(&cursor->d_sib, &to->d_sib); + hlist_move_behind(&cursor->d_sib, &to->d_sib); + else + d_detach_cursor(cursor); spin_unlock(&dentry->d_lock); dput(to); =20 @@ -210,9 +209,10 @@ int dcache_readdir(struct file *file, struct dir_conte= xt *ctx) p =3D &next->d_sib.next; } spin_lock(&dentry->d_lock); - hlist_del_init(&cursor->d_sib); if (next) - hlist_add_before(&cursor->d_sib, &next->d_sib); + hlist_move_before(&cursor->d_sib, &next->d_sib); + else + d_detach_cursor(cursor); spin_unlock(&dentry->d_lock); dput(next); =20 diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 4b1ff99608e0..64d64bab16fe 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -324,7 +324,7 @@ extern char *dentry_path(const struct dentry *, char *,= int); /* Allocation counts.. */ =20 /** - * dget_dlock - get a reference to a dentry + * dget_dlock - get a reference to a dentry while locked * @dentry: dentry to get a reference to * * Given a live dentry, increment the reference count and return the dentr= y. @@ -339,6 +339,21 @@ static inline struct dentry *dget_dlock(struct dentry = *dentry) return dentry; } =20 +/** + * dput_dlock - put a reference to a dentry while locked + * @dentry: dentry to get a reference to + * + * Given a live dentry, decrement the reference count and return the dentr= y. + * Caller must hold @dentry->d_lock. The dentry must still have + * a reference after the decrement. This can be used when two + * references are held and one must be dropped. + */ +static inline struct dentry *dput_dlock(struct dentry *dentry) +{ + if (!WARN_ON(dentry->d_lockref.count =3D=3D 0)) + dentry->d_lockref.count--; + return dentry; +} =20 /** * dget - get a reference to a dentry diff --git a/include/linux/list.h b/include/linux/list.h index 09d979976b3b..8db89117e959 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -1107,6 +1107,36 @@ static inline void hlist_add_behind(struct hlist_nod= e *n, WRITE_ONCE(n->next->pprev, &n->next); } =20 +/** + * hlist_move_behind - move an hlist node to a new location in list + * @n: hlist node to be moved + * @prev: hlist node after which @n should be added. + * + * @n may be on the list or unhashed but must not be @prev. + * It is removed if necessary and re-added after @prev. + */ +static inline void hlist_move_behind(struct hlist_node *n, + struct hlist_node *prev) +{ + hlist_del_init(n); + hlist_add_behind(n, prev); +} + +/** + * hlist_move_before - move an hlist node to a new location in list + * @n: hlist node to be moved + * @next: hlist node before which @n should be added. + * + * @n may be on the list or unhashed but must not be @next. + * It is removed if necessary and re-added before @next. + */ +static inline void hlist_move_before(struct hlist_node *n, + struct hlist_node *next) +{ + hlist_del_init(n); + hlist_add_before(n, next); +} + /** * hlist_add_fake - create a fake hlist consisting of a single headless no= de * @n: Node to make a fake list out of base-commit: dac3e89a2c90c2feeb471e1f22a2512ad424b792 --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7EF423BD06; Sat, 15 Aug 2026 04:28:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768113; cv=none; b=nl8Hwwu/ORtsjYoc2SKLOEPmIPFJl3GXz93OJMgdWIunckKsmDlJQjrfP5MrrL3RyM9D2pRUNjbYd/uoy/UV2RfOFse70tdnob/aMb6Jlf2PxN/uVHjOeN6+5bWHr+iEoqWdNxCwGGs08+CZSbgrmdSp0f4R6Cx5v74dakyiAkA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768113; c=relaxed/simple; bh=H5SH3/ro6ITe1unbKv6X98QtZBMK8wgTThIC4wk+kBM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rkaJwXr5xwFl9qaSlcdoCuriKC5xg/dMVg9OlTZgakZiuk/ALaMh6Jo2SnuzgjIEqJwQVJ6vN8qf9LICtJwiSdyitZ0Ws3zLrEfxSSefogyO1aMrKxOA1uigeGXynIZnPDghukYu++cdf2z+2UTthqbEkhmG5p+ziVLZpP2Pqf4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=V/p/o4WP; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=lBBmDaW9; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="V/p/o4WP"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="lBBmDaW9" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailflow.phl.internal (Postfix) with ESMTP id D747213803F8; Sat, 15 Aug 2026 00:28:30 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Sat, 15 Aug 2026 00:28:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768110; x=1786775310; bh=vhLaq8TeacEW12FmtPepvksnJ81hegqNRNrapfehjX8=; b= V/p/o4WP0WcwfrEWun9wojoBjFslQ2KR8eymAbIyfKXYJhmjh2zpPd5HWeYzYXEI VVr33kr/8VNLYnXPLh/xYsilyGiRfVWHluoMjMUMJXLQ5wrOA+Z6LEAZulJj1qv/ VvM2OzsQDxWxfEQRdAUs4koAkrdm2U+kBOtft8OtuwMjV8080Cu3xYk8hNWf7tGG fztY3DHgBmW9e7WZkXNLSnQsaT3jzqz1iOojp5Apo0vcDM9EmggbnjICsd6SyZ6P V7Jinv47FA/fNAPFu1sYIyOd5U41+nNyaZICtQqqC3ATBfwZL6tyIi2Gdm1Wx9fz eT4ScfyF3PWtj3XyGsyapw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768110; x=1786775310; bh=v hLaq8TeacEW12FmtPepvksnJ81hegqNRNrapfehjX8=; b=lBBmDaW9o3UkM1erN lpxbHNJXIhY2pOMT9LR1O+n1qTpOImF9zp5gedc6gsZxqqaHiQqu1RazOM5d8OzT V7nU7MgfWBvejQIKJ89ie47gAtEgi3O/i7ikhTsvedTvWyErZt/khfAmIa2msaRR oYVEffLxk5Ejn4vBAdVW8xMHxNoVAG4wyyWifpx1lMLG4GYTPk1EkdTun4dgUsaI eeObrdoeAD1v5AIw8KP0PWvnSF2/GrYU8em5nRBCkYUmjf5xmwnKk1eX0nzXwjJq jFobsDFxiVdSPgoZiljCB7xEygQsvBv5WXcXTcEYUgcb0epxgnUxTqKQH36oZyac Tm90g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTGxKCIJg189DggFiXo5ZJL4dIjbhm46neB2Vqz0yysnTK2EEvZfyUO+W+5VylOmxA MXt5kdik9jz+bmdCUGG9zhM/yC7XCFdf6P2fYdm8xoYAkS4lmA5u96Kjpq2TeGn/dPFbKL mULzfOuDXcNtV/w8ss/fVr14WSq3NSOCPLhEhjAPC143exYjC0qGmAPeJSTejsuElTX1t+ XC5iq/pm2rahqBTv8qgJG6LygUrvIIzUau+lgT4YNtEUmALkB88s8XvdfVuXa0aHqANFgm TtvBEfNb5mRkIrhcsMJtSzP4V6xOiTZaNgnWWaBZgJzE/9cocWzpzl5kcQPsd0HyLX0eMr YAbw5tYyR7joh4+2EBy9c/8oggr3yXL2s0H5Z6uMmkWP00w9VqaPyh8NbGrhoT7zl0MOOy TfEkwe+LH/DNUh7n1MO4ZjHSUKId3FwShs7sdUQ1TJIs2eJ3juFCAtzAuyK0bl/9yp2xrx ORdVMowDPiG/Ef1wms65ffMPJ0dD+zgBWGUSuAqbBLs7y02okxkILz346Dsj3GzazCdPn2 QL53Wd3dT+Q8GZKflBMhoMWJi6XVPuqNhi7Fut/F2KZzjh7EaenT0nXlalxL5jm7Zs1fAs MSc/LuWOCPfh4nX4eMa2qY4CTh1BMoU9pbp9yrC0WJqZAJCNY9xXlxZPoPWw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:28:24 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 02/18] autofs: change positive_after() so it takes d_lock rather than the caller Date: Sat, 15 Aug 2026 14:21:19 +1000 Message-ID: <20260815042707.2535717-3-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Moving the d_lock from caller to callee simplifies the code. The only non-trivial code that is no longer locked is parent =3D p->d_parent; and as autofs doesn't support rename, ->d_parent is stable and this doesn't need to be protected. Signed-off-by: NeilBrown --- fs/autofs/expire.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c index 5c2d459e1e48..909622eeb8a0 100644 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@ -70,9 +70,9 @@ static int autofs_mount_busy(struct vfsmount *mnt, return status; } =20 -/* p->d_lock held */ static struct dentry *positive_after(struct dentry *p, struct dentry *chil= d) { + spin_lock(&p->d_lock); child =3D child ? d_next_sibling(child) : d_first_child(p); =20 hlist_for_each_entry_from(child, d_sib) { @@ -84,6 +84,7 @@ static struct dentry *positive_after(struct dentry *p, st= ruct dentry *child) } spin_unlock(&child->d_lock); } + spin_unlock(&p->d_lock); =20 return NULL; } @@ -98,9 +99,7 @@ static struct dentry *get_next_positive_subdir(struct den= try *prev, struct dentry *q; =20 spin_lock(&sbi->lookup_lock); - spin_lock(&root->d_lock); q =3D positive_after(root, prev); - spin_unlock(&root->d_lock); spin_unlock(&sbi->lookup_lock); dput(prev); return q; @@ -119,7 +118,6 @@ static struct dentry *get_next_positive_dentry(struct d= entry *prev, return dget(root); =20 spin_lock(&sbi->lookup_lock); - spin_lock(&p->d_lock); while (1) { struct dentry *parent; =20 @@ -127,12 +125,9 @@ static struct dentry *get_next_positive_dentry(struct = dentry *prev, if (ret || p =3D=3D root) break; parent =3D p->d_parent; - spin_unlock(&p->d_lock); - spin_lock(&parent->d_lock); d =3D p; p =3D parent; } - spin_unlock(&p->d_lock); spin_unlock(&sbi->lookup_lock); dput(prev); return ret; --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1EDA62DAFDE; Sat, 15 Aug 2026 04:28:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768124; cv=none; b=rYAxKbROdN3nmEXdepfKZ3v0sU7OZkxDM2uc+ou6sqvyiPEZ0hqJ4iCywWWVrcwIa1TIShPH+1LGA08sN6dN8k8ZmcvFgD0QhQVeHyVrE1Yi9xCk4sUdg9Ad4gDgteY2UExTdXdc/xdqNPfWv4ev7KQdb916sat5gjP2y+Og0lA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768124; c=relaxed/simple; bh=yIHtNJ55MhE2MaPIfXvzHiwBMs0J+NWpXiu+PMzC4oQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=drJQUt9JGZNt5xNzy4si8QRw2gxLX4CcL6De+m/eeiokTjS2pCmmC971dK/KJCmSnBi0XJLlBdZRjtmVgkz5xOxlo+8mGQDrfzjRC9yK7WtV3Sjw24dEKkCqZu4YLr9ojmEQEc3fSEnjsNg2PEAaO6zmYk44YbDi4EXmmcC7yyA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=bqjRfLkv; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ZMt01d64; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="bqjRfLkv"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ZMt01d64" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id 4F59913803F8; Sat, 15 Aug 2026 00:28:42 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:28:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768122; x=1786775322; bh=QBxhcF/9xx0fJVzCRbVatWLSoovuhY6RZpsb7+BVY1I=; b= bqjRfLkvS3cbGxzlykjKRbh1Ksx3VDguHVHcxlQ3b6hF21VmVribKgPD8jPxh1dx SPdk6P4xXZqhaZJPPwT/UKP9MgSAxUD5InxteviMhw3hARMmxaCihN8B897Hpq/c 7QR40flaUVf8s/pQHdcEcm6ZV5NTdQvLusWEp5bsFTiliEIADFO74dWtzaYgQBiO v0SEoxv0JJ4URdSXbkhQyBcIO7Zf+5NhvLYZ8nv39gN+aaYDSS8fAjtv9X1f8X4X K5z+vafIg44JmNw5ayuAHYmrU9DGJLqgmu/7qBc0zcztnEO2j+qm5dfBJU2Y3pYZ pyW/6AogP81G1CDVidfNdQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768122; x=1786775322; bh=Q BxhcF/9xx0fJVzCRbVatWLSoovuhY6RZpsb7+BVY1I=; b=ZMt01d64ylFJIe5sJ tvytFxduHgcYH5k4nG6D6q7eh7MG+D839nemg0C03zkCpmn3n7WT4/lNfZXYmUd/ u5ROLa31WfTKkBaKvolW3LtHe7do1Yrx7Ko3YiVmA1o9eyW8202G3zLjT+zpjuHb qi9c7uez+OD20t60ADSuOM+Z8xb7Ajj2y2XfGHi3Hddfqzsz+FSujBkG/cEggkXA XiklcFIvpa0PS7ZT1PkvXxQn7l37/EuYo6zBPXZYvPj8CCGycHpMh6+6ImxKT1Vv NOIONFxeDpxsnCob64yL1fhgZEOkstMkAj4ZIHzwfI21Rvo5C7JPQGfsTeeoEP0n Ul7zA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTF9KskX6ORZkk2qDbanJAqhpO1c3Xju1rB/XGbwQvOGWemlAS7RTfehH6z/blxuZu ndq9JpuBON/sKJpHNFmlA8NZthzZuohefFsXvvzkhDLNc/boPY1CbYwGZ3ejocQdZP5Ev/ BXLTdsGGIGk/QWYctoHjfRUZGHXRv5et6FUSLml8RkvDkfsb7WSgppX3LyXjWcFTLwfp/k XOfgf9r/SZsCIW4bEY4xzTmE8sCd1BMMrUIBiSLPUM5HPZAu9IGndquxD0N2k1kJS4EkJO uSSxartPr+p/2sBY7kb8VaiOyCHt8JoqHMJjX2cNsGCbf1T449z1owAvKjvcnWl37FvYZv xBkvdljat0cxOiVSTUjjCqHmk/A6Cs8PzDW3BOACcrmezftHMRKnBhGU6LNdRMB1S1EC9d d2SQHNJLexn4xqrIZSBv/ulS6vcZHMpj8ecULxFQYbpVaE0q+QaW2BimNl4kAYh+PTqdWN RAjy8/sdQJy3OlWJBRTCyXtMx/4jalL0aqRU4DKNs+PMmVujZWLb72fTBsjj0Y6FHn6Ox9 P5g0qhXLsWnv694+ccz845f9Ihek1XQe0skjxYMjXVzXs8DvXC7jR93McY7PzSw8UrZBJb eVQPMK6P5hZjSLiQtyv7m5+LWGTosCyc+9J0KVZYHQnUkk+W8zkSdx/e1pUw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:28:36 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 03/18] coda: don't take rcu_read_lock() in coda_flag_children() Date: Sat, 15 Aug 2026 14:21:20 +1000 Message-ID: <20260815042707.2535717-4-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown As described in Documentation/RCU/whatisRCU.rst sections on rcu_read_lock() and rcu_read_unlock(), spinlocks prevent the RCU grace period from ending so there is no need to call rcu_read_lock/unlock inside a spinlock protected section of code. Signed-off-by: NeilBrown --- fs/coda/cache.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 245131296300..970f0022ec52 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -93,14 +93,12 @@ static void coda_flag_children(struct dentry *parent, i= nt flag) struct dentry *de; =20 spin_lock(&parent->d_lock); - rcu_read_lock(); hlist_for_each_entry(de, &parent->d_children, d_sib) { struct inode *inode =3D d_inode_rcu(de); /* don't know what to do with negative dentries */ if (inode) coda_flag_inode(inode, flag); } - rcu_read_unlock(); spin_unlock(&parent->d_lock); } =20 --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7CC992D77E6; Sat, 15 Aug 2026 04:28:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768132; cv=none; b=XqD4K6m1ywT4EVQGF7RfrjjXUawtFA9kYSDEotJuRiqYqEw3gZ9apV2h6ZAr1FHLZm2jns0Vm4NiRPXOWSY/LHFTeJdJmfZ26OIAPfXg6solsm9jdxqmmFgwzfKx0EmVEXOEufFMX0INHHXslWkCknd/z6c4NvVnuTCimZCPkBo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768132; c=relaxed/simple; bh=A0UhbREzQ2b96qESdEBPrmUcdJUGNNPBEmk7drrg2k8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rPrkE0hQY7C5LIAlTT6qLdrd/JCPbADkxDmisi9SaWhh7vp4SSPUxLvILeflCwX9b5H4exyzytEybzlgqvPe3+CMp9c+A8xLVJA/VZFZtdKbjqF3G6NeKoqtZcAcSCxxP2M3ynACJcqdvCea/kn5Pcgkuj6yfTexdJFhOzZImQE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=lOahxFdw; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=cJ6X2n1R; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="lOahxFdw"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="cJ6X2n1R" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id 8F78B1380411; Sat, 15 Aug 2026 00:28:50 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:28:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768130; x=1786775330; bh=30+fT77CWVQvZZk/s/T4uRUE7JQPMDkgqcoKGgJMCL4=; b= lOahxFdw5kiEJD3ro7+HnvkIfFp6IFS0D3Y9hf9CKLjS5a4i2lYuspEiyH77bVte F+qfxD8Fi5uIgDI4t4ypjMgptiOd2GvivbiNeYoaszLd63HQGyJmWLTSI7+PsNno 8j09X89T5iP6ejjDLbjlkgMTcXEuXJpBL54VmRM509SNTUcmcD/LjIGevmGdfW6B TbChej1XfhcvHNjEy4t9U1akatocIW9BWsO1alH3w7zqYv2auG89j3mRebz/GI41 XHNTpjNOp0xvfG1eQBc72GOzH2oGsJZZqRBIyncpSkXKcdOpSiKTiUOXnCvNvzF5 aL7VopMLJli6a4B1OKJSPA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768130; x=1786775330; bh=3 0+fT77CWVQvZZk/s/T4uRUE7JQPMDkgqcoKGgJMCL4=; b=cJ6X2n1RAYP7oAWgn /ObSjbGj6FRaVViEenB9BjQV773032oNlR/V0cG+tMNrf1nP3Woyx0/q/LDmTIXX h98ICIs4mQsrPdLcRw/jm+ZaixejutDYYI04o9UvdUMwYsOrICgXWVmVDYNbJ2Oy K5/65BdNXZGlwo9/CQmR559BpS/hx0sK8ZKG8T/qwIuIvEnssK12ZZiVu05lxiso ACA30j2x+2c7mETCmM82b1SupAXBK8JdCrmSYAobb7q9ISuoPK5EGiAxUwhxgbcc qDriYPx4+VO+W0qvetafCzVgTYs39g7i4RbkICieZc1cqlRtsLORy9aLsMA9Xv1g 9p5tg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTGxKCIJg189DggFiXo5ZJL4dIjbhm46neB2Vqz0yysnTK2EEvZfyUO+W+5VylOmxA MXt5kdik9jz+bmdCUGG9zhM/yC7XCFdf6P2fYdm8xoYAkS4lmA5u96Kjpq2TeGn/dPFbKL mULzfOuDXcNtV/w8ss/fVr14WSq3NSOCPLhEhjAPC143exYjC0qGmAPeJSTejsuElTX1t+ XC5iq/pm2rahqBTv8qgJG6LygUrvIIzUau+lgT4YNtEUmALkB88s8XvdfVuXa0aHqANFgm TtvBEfNb5mRkIrhcsMJtSzP4V6xOiTZaNgnWWaBZgJzE/9cocWzpzl5kcQPsd0HyLX0eAk cBD4+I3j0niSMzcI0GyaYcha+Lf4GpfMAm9iR2rEXYmbXHvJeQ9IVi8f7BSRKLoOcrvsyo anTjeg9VMQ1pKhx1onwV0VxFHyGWIqcN7uFNZAHLvSMSTCBTBiEWkO2aRVW4inH0eqHzjL 3dg5VAuGtIk5NYJvMY49lfX7fuc1vFkYLsM8eUiS75J4Zqzwuev33owc/MvGoaEKAUBFuc LcnULLM/E40FQhZHCOxc1EkY3NYXRkGmeQL5nJ+TMXPO0+Ws4W71oLiO/yFloAEt980ZPg cX3Iv7KO42sPvTMG7Y6AqrhbsXtVDxwBZjE7iWp+5RJykrXQziB45IWBBtlQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:28:44 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 04/18] nfs: separate locked regions in nfs_clear_verifier_directory() Date: Sat, 15 Aug 2026 14:21:21 +1000 Message-ID: <20260815042707.2535717-5-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown nfs_clear_verifier_directory() locks the dir to call nfs_unset_verifier_delegated() and also to walk the d_children list. These are two separate needs and they don't need to both be in the same locked region. Subsequent patches will use a helper for walking the d_children list and that helper may drop the lock temporarily. To simplify this transition, split the locked range by dropping and retaking the lock between to make two separate locked regions. Signed-off-by: NeilBrown --- fs/nfs/dir.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c7caffb31935..bba5d996413c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1492,6 +1492,9 @@ static void nfs_clear_verifier_directory(struct inode= *dir) =20 spin_lock(&this_parent->d_lock); nfs_unset_verifier_delegated(&this_parent->d_time); + spin_unlock(&this_parent->d_lock); + + spin_lock(&this_parent->d_lock); dentry =3D d_first_child(this_parent); hlist_for_each_entry_from(dentry, d_sib) { if (unlikely(dentry->d_flags & DCACHE_DENTRY_CURSOR)) --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36D0E2222CC; Sat, 15 Aug 2026 04:29:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768142; cv=none; b=Io8gcUmnBHLAzgpElI8U5tcVHZaIlL3HJPaIEyjQnzEZ9HcSZtM0kYbqKFQnlXVTccVj2TzH9BlpiaPhv/Zf7MPLjITMdOvgUEC6nspE45r7K2d5RE9V1RMZsXBd2KPwo5+gIrphHVkwX+7kxp+QD5pgt0AJYRnUulpOEStMQX8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768142; c=relaxed/simple; bh=p1mMn9qOZZwguR9yZ3qRBputr4xWHGS+mAUHVqwEuY8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YmnImghSoC6PyhU/cbF79nmGNSaZvgkpFFf0PWp13kwBST+44sSmRWtp80pP2b4jcZGWtJM7MXfAhS+yO4VR9/GKdbIveehxkAJVDWwGVHNaMNs10bCuc7cqLSezU+v/Yn1/XNBpnukukOs3jKo0DU02vfJ+aSAL8XaAA8twtOM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=UREgnDyb; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=KlA2fVSz; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="UREgnDyb"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="KlA2fVSz" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id 09C701380411; Sat, 15 Aug 2026 00:29:00 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:29:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768140; x=1786775340; bh=AH8tVpPfOZN5UyDdOxfXJOmbn3oiZz5KgirDEs++h9M=; b= UREgnDybw91X4mYtsrUAXc4ebAHvCtDn23OpUXls2m9FbLZZgKFEZsdzoViCnTri bvIqHKHF2pDIbvHzVOzkCYRoRjZzN581suOLOL0uKfz5cRf89MElOVSTCe1DNOZx T5CASOB6nAk/QVVrMDYhlGqHzaTpc+ooi8NiKG9CdtJ7GnBQTNhBWIDVVoJYdoqm jYcoIJ8Aplu+s+gnh7b5sqn2QWOKmznVJJ5eIJOFYjNYDYjBxijUdTl6gN3YJAFu k3wjucWcFIcUQUGsuDuokupkLg16f6gH8Q+h/BhTP9GplCODWU+FQKnLxc/lK7J3 lH+JLYLcyqp5TICEUBsFEg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768140; x=1786775340; bh=A H8tVpPfOZN5UyDdOxfXJOmbn3oiZz5KgirDEs++h9M=; b=KlA2fVSznUU1V+Wc8 o4aJV0CCLOZxof1D3YpapXdcX9kovbGQIEg9lk3ov/oc7rTIb9r5mKqPYhF9xvWH Lgti6mQ17Nwm79Ckm1Tf5A1lipL3kaeukOUGM8MCt0R1EYpOJF77mX4deplo89NA 7xHNPdQgz64J2XUVpMLWHgyK9KOg7XBz/ve8giSs3kU2nGFjZ2JzeywfTBpBh1ey Sz2RUvaO2F01oDhuyTN/Ch4DDCuhKQw+VA/k5pmlnc4qeoNBZTcE6D8H6lqwXPqY QNNeYoie1jNf5DzENJZg7S46Ok6Kgd+TObOzwEMQ7Z08F6s1TVepDxF5JLStyzix KQrtA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE846WIQAeAfC2svQKIx1rsRetJ1LqZbsylzr9Pg5j2zb0C1579PSws3yCQ5R+Olu b4zipOSfuqPCCaiDU3QS41htHgbbUHbw+9IzWKPPDnBCHa6LTRLmDA4RjMkkHbUX8AcF+A MaOV82BKDsir/tMJG7jGbG0WSaN6GMmU4sezvndaPTX2rOOXNVUsNv6YabWiNiTF4FcJlI 4RfFT7jjBx2dFRn3NgR5XxWgsk6mzpLzO8biU/naSZJT+ZXMzU/K2WBbpybV+o2TIlRRCb KSueBiL5GSYxcW7IeiZ+C1vDelgggOSZL/+/q2EWxFhEhtw6QnwbZ3VRg5nZrTdYUceOGJ QLpHXKd9HHznugxMz98kj3me/NvtT9doUUxsnNXicuRJZ/aAZd3fqQ9H28qACe5K4RyzWU QWxbensHeA8lFkRtEdj2ZXW+0Gp3giu8YTDrGdqxdahIQHF7iqJsSwrnE+0omSdvjc2Tck 3wfFX3hXRIUu+oSs4mTOUWy/aDS7Qoqop9SLGyZUh2qTdDoBA4KjU8JFWJtTPYilcA8Ozj WZ76pmEavFTNNg54YU8f5IcyfYm2yV1hLzLed5vRbWaGjDA0yKv2Cgd5rO3iHFn4DnYxXo 4SN4nYxbPHaHeaYVDhLTHLf5WC0oyJsMXEG7KfD6WwA3OSNannI5BVCu2k7w X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:28:53 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 05/18] Add and use d_for_each_positive_child family of iterators Date: Sat, 15 Aug 2026 14:21:22 +1000 Message-ID: <20260815042707.2535717-6-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Provide iterators for the d_children/d_sib lists. These iterators only report dentries that are positive (though they could be negative by the time they are used). As DCACHE_DENTRY_CURSOR dentries are never positive they are never reported. d_for_each_positive_child() takes the parent lock and sets the iterator to each positive child in turn. d_for_each_positive_child_continue() can continue after an existing dentry, or (when initialised to NULL) behave like d_for_each_positive_child(). This requires that something prevent the start dentry from being moved before d_for_each_positive_child_continue() can take the parent lock - typically ->i_rwsem. The use of scoped_guard() in these macros makes it safe to "break" or "goto" out of the loop - the lock will be dropped in that case. These are then used everywhere outside of dcache.c and libfs.c where d_children/d_sib iteration is needed. Signed-off-by: NeilBrown --- fs/autofs/expire.c | 7 +---- fs/ceph/mds_client.c | 10 +++----- fs/coda/cache.c | 4 +-- fs/libfs.c | 4 +-- fs/nfs/dir.c | 7 +---- fs/notify/fsnotify.c | 7 +---- include/linux/dcache.h | 58 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 66 insertions(+), 31 deletions(-) diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c index 909622eeb8a0..ba1a3a2bfc9a 100644 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@ -72,10 +72,7 @@ static int autofs_mount_busy(struct vfsmount *mnt, =20 static struct dentry *positive_after(struct dentry *p, struct dentry *chil= d) { - spin_lock(&p->d_lock); - child =3D child ? d_next_sibling(child) : d_first_child(p); - - hlist_for_each_entry_from(child, d_sib) { + d_for_each_positive_child_continue(child, p) { spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); if (simple_positive(child)) { dget_dlock(child); @@ -84,8 +81,6 @@ static struct dentry *positive_after(struct dentry *p, st= ruct dentry *child) } spin_unlock(&child->d_lock); } - spin_unlock(&p->d_lock); - return NULL; } =20 diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 3c692ad02c85..5c4e72c3b110 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2182,14 +2182,10 @@ static bool drop_negative_children(struct dentry *d= entry) if (!d_is_dir(dentry)) goto out; =20 - spin_lock(&dentry->d_lock); - hlist_for_each_entry(child, &dentry->d_children, d_sib) { - if (d_really_is_positive(child)) { - all_negative =3D false; - break; - } + d_for_each_positive_child(child, dentry) { + all_negative =3D false; + break; } - spin_unlock(&dentry->d_lock); =20 if (all_negative) shrink_dcache_parent(dentry); diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 970f0022ec52..dca88d749b86 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -92,14 +92,12 @@ static void coda_flag_children(struct dentry *parent, i= nt flag) { struct dentry *de; =20 - spin_lock(&parent->d_lock); - hlist_for_each_entry(de, &parent->d_children, d_sib) { + d_for_each_positive_child(de, parent) { struct inode *inode =3D d_inode_rcu(de); /* don't know what to do with negative dentries */ if (inode) coda_flag_inode(inode, flag); } - spin_unlock(&parent->d_lock); } =20 void coda_flag_inode_children(struct inode *inode, int flag) diff --git a/fs/libfs.c b/fs/libfs.c index 7cd816b8e2a0..8e99067079e8 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -768,8 +768,7 @@ int simple_empty(struct dentry *dentry) struct dentry *child; int ret =3D 0; =20 - spin_lock(&dentry->d_lock); - hlist_for_each_entry(child, &dentry->d_children, d_sib) { + d_for_each_positive_child(child, dentry) { spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); if (simple_positive(child)) { spin_unlock(&child->d_lock); @@ -779,7 +778,6 @@ int simple_empty(struct dentry *dentry) } ret =3D 1; out: - spin_unlock(&dentry->d_lock); return ret; } EXPORT_SYMBOL(simple_empty); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index bba5d996413c..3aa874626299 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1494,11 +1494,7 @@ static void nfs_clear_verifier_directory(struct inod= e *dir) nfs_unset_verifier_delegated(&this_parent->d_time); spin_unlock(&this_parent->d_lock); =20 - spin_lock(&this_parent->d_lock); - dentry =3D d_first_child(this_parent); - hlist_for_each_entry_from(dentry, d_sib) { - if (unlikely(dentry->d_flags & DCACHE_DENTRY_CURSOR)) - continue; + d_for_each_positive_child(dentry, this_parent) { inode =3D d_inode_rcu(dentry); if (inode && NFS_PROTO(inode)->have_delegation(inode, FMODE_READ, 0)) @@ -1507,7 +1503,6 @@ static void nfs_clear_verifier_directory(struct inode= *dir) nfs_unset_verifier_delegated(&dentry->d_time); spin_unlock(&dentry->d_lock); } - spin_unlock(&this_parent->d_lock); } =20 /** diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 7e2f330fd283..90a2121fc54a 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -85,16 +85,11 @@ void fsnotify_set_children_dentry_flags(struct inode *i= node) /* run all of the children of the original inode and fix their * d_flags to indicate parental interest (their parent is the * original inode) */ - spin_lock(&alias->d_lock); - hlist_for_each_entry(child, &alias->d_children, d_sib) { - if (!child->d_inode) - continue; - + d_for_each_positive_child(child, alias) { spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); child->d_flags |=3D DCACHE_FSNOTIFY_PARENT_WATCHED; spin_unlock(&child->d_lock); } - spin_unlock(&alias->d_lock); } spin_unlock(&inode->i_lock); } diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 64d64bab16fe..cabf05e74b1f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -656,6 +656,64 @@ static inline struct dentry *d_next_sibling(const stru= ct dentry *dentry) return hlist_entry_safe(dentry->d_sib.next, struct dentry, d_sib); } =20 +static inline struct dentry *d_next_positive(struct dentry *child) +{ + do { + child =3D d_next_sibling(child); + } while (child && !d_really_is_positive(child)); + return child; +} + +static inline struct dentry *d_first_positive(const struct dentry *parent, + struct dentry *child) +{ + if (!child) + child =3D d_first_child(parent); + else + child =3D d_next_sibling(child); + if (child && !d_really_is_positive(child)) + child =3D d_next_positive(child); + return child; +} + +/** + * d_for_each_positive_child - iterate over positive children in the dcache + * @child: iterator dentry + * @parent: dentry of parent + * + * Iteratively set @child to each positive child of @parent. + * @parent->d_lock should NOT be held. + * @child may no longer be positive when the caller examines it + * so care is still needed which could involve locking the child + * or using d_inode_rcu() to access the inode. + * + * DCACHE_DENTRY_CURSOR dentries will never be returned, only true children + * which have at some point in the past been positive. + */ +#define d_for_each_positive_child(child, parent) \ + scoped_guard(spinlock, &parent->d_lock) \ + for (child =3D d_first_positive(parent, NULL); child; \ + child =3D d_next_positive(child)) + +/** + * d_for_each_positive_child_continue - iterate over remaining positive ch= ildren + * @child: iterator dentry and starting point. + * @parent: dentry of parent + * + * If @child is %NULL this behaves identically to d_for_each_positive_chil= d(). + * Otherwise @child must be an existing child of %parent and subsequent ch= ildren + * in the d_children list of @parent are returned. + * + * Safely using this requires that something prevents @child from being + * renamed to a different directory before we get the lock. Holding + * i_rwsem on the @parent is sufficient. + * + */ +#define d_for_each_positive_child_continue(child, parent) \ + scoped_guard(spinlock, &parent->d_lock) \ + for (child =3D d_first_positive(parent, child); child; \ + child =3D d_next_positive(child)) + void set_default_d_op(struct super_block *, const struct dentry_operations= *); struct dentry *d_make_persistent(struct dentry *, struct inode *); void d_make_discardable(struct dentry *dentry); --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 422262D77E6; Sat, 15 Aug 2026 04:29:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768151; cv=none; b=S7WmeLkcafTJO2xs5rxksz4X7jSO2ONRwvwmMIw7bJE8mlYToe3IUxctR0x+LpLzARYW+dJs6StTyZLwH7NwDm4Wo3hVwdtDgKsfDRr8NkrDPRoekrJcHAuriZkwqWZumbO5unR+T159Mu3UjBjgDsO11Wo3APNy2A2Y5O0mYJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768151; c=relaxed/simple; bh=T34JxOpiVNgmqXtrINvffld2SqngikizyR2EAJbzHuQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZACMiWe3LdEoWSzTctyGDVR+cGDPkWeQIM5cQgH7kl7WEoS4qfLnKEEARPT4/mteXFxjQcktmaRiyqqOW87eC5EminhZoNEvczzDK+DNFM+uEvH3fRzrykvCdPUFqvglyS2FhURdZS5osVYqIJ+mf4z3mH93yKtAfGEZ4/sGLG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=JDukkkAa; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=VdiUHgCH; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="JDukkkAa"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="VdiUHgCH" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailflow.phl.internal (Postfix) with ESMTP id 772741380411; Sat, 15 Aug 2026 00:29:09 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Sat, 15 Aug 2026 00:29:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768149; x=1786775349; bh=J95HikmQr7dRaxCO6Pi9Ng8sIJ7NNBS+kKqBtfcPV/0=; b= JDukkkAaBaawMxLsBPC8/UD7H2xV66dd8B/foWP7/1eqSmzaGfErdds2rnWLaGNk JXIeObLh8BjGKfTRhKD4cNROsnLA/rjV55UCNFmh4k8ncMrMdN2jAF+x88pSbAa1 40hi0EFPNeLGsSG1im9j6Tj5uLU5xNTmgKCO6uo3ea8VU4Bu1Nel6kf37/Hwdjdm 98nUhCQQxQ/zLkVNGjuSTLh9P9jlbqTGYVyRuJu5GLw4chmz7cJe9I4yRAGLe3zS qe0BlbmFpke4Vx61HZEdHxLXcZlKa87ENYTlPSbcdLrgwGzsgeC7L3sAOLOx9olm xgop+2ruIMrwZ6e0S/zh9w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768149; x=1786775349; bh=J 95HikmQr7dRaxCO6Pi9Ng8sIJ7NNBS+kKqBtfcPV/0=; b=VdiUHgCHVGK+L3g0f oUfWaAI3IOOWygwZY9RqfUXyzCHZ0p63VjrCo6vyqJliO20GeqxIANeP4QmFRtkZ BGsnvGTcEhxfiS9DSU6dK+nwlZTyL3dJb7yuVPWvrd7dG/9Yf7Z8/9CXxFPWlhAL /PhLLTi/aHbT3LyaOLPvaOGIx6WFA4zHsB1tzevm6QOj7zdbqIFnrUMNYHIOzgMv +37AblPz7efkz0QLe92viroBBLe0piJwIXDIE5s8D+VDTQ4aIgoCk4+N6CeHi+S2 +uOhOBXUaOISdPzTCmJhcoyGPOvMdZgWqBA3UvOBqnYAV2trI8kJEIpXRkYiFTmR pAqGg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE846WIQAeAfC2svQKIx1rsRetJ1LqZbsylzr9Pg5j2zb0C1579PSws3yCQ5R+Olu b4zipOSfuqPCCaiDU3QS41htHgbbUHbw+9IzWKPPDnBCHa6LTRLmDA4RjMkkHbUX8AcF+A MaOV82BKDsir/tMJG7jGbG0WSaN6GMmU4sezvndaPTX2rOOXNVUsNv6YabWiNiTF4FcJlI 4RfFT7jjBx2dFRn3NgR5XxWgsk6mzpLzO8biU/naSZJT+ZXMzU/K2WBbpybV+o2TIlRRCb KSueBiL5GSYxcW7IeiZ+C1vDelgggOSZL/+/q2EWxFhEhtw6QnwbZ3VRg5nZrTdYUceOeU OJ+hHoMWZqqvPmDNafLAjR2gST6+96lKpnmoRnyjmtNRJcEJr1bigQcQ+jBosNkmZXUHgu zBK8fOQ0u8d1q/S42A3IQ4IDJq8qDF0K1GGcAvdRakdROjV8rHXJ5GjUbGjRQHYDlhUw6a tne8LElYoXIfr5gwyQWwj+Ogm43U9POOj0+jxHveuegQBShoxUgV8r4n2IFCNqTEcQ+8v7 TrwfZWW33m0P3GcEjq9Gnl/0/okD7GHHYO/yLcnPmlVPl+8IEz8nZL4g7GqV4eZ7AuQk6n JTxOirHm/yU+vc1l9isduItZHg91GNVxuOy7WDPGRfmzN5E8U10viEAQulcA X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:03 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 06/18] fsnotify: don't hold a spin_lock across fsnotify_recalc_mask() calls. Date: Sat, 15 Aug 2026 14:21:23 +1000 Message-ID: <20260815042707.2535717-7-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown fsnotify_recalc_mask() is normally called without any spin_lock held. fsnotify_group_lock() (a mutex) is often held, or else srcu_read_lock(&fsnotify_mark_srcu) is held. Either of these are sufficient to keep the mark and the connector stable. However dnotify_recalc_inode_mask() does hold a spin_lock when calling fsnotify_recalc_mask(). This is problematic as fsnotify_recalc_mask() can walk the d_children list which can be long. Holding a spin_lock prevents us from using cond_resched() in that walk. So change dnotify_recalc_inode_mask() to NOT call fsnotify_recalc_mask() but instead return a flag indicating if it needs to be called. Callers check this flag and call fsnotify_recalc_mask() after dropping the spin_lock. As part of this, dnotify_handle_event() now only calls dnotify_recalc_inode_mask() once rather than possibly several times during the loop. After this change, the only spin_lock held across the d_children walk other than the parent's d_lock is the inode's i_lock. This will be addressed in a later patch. Signed-off-by: NeilBrown --- fs/notify/dnotify/dnotify.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 9fb73bafd41d..d8aff13097c2 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -54,12 +54,13 @@ struct dnotify_mark { /* * When a process starts or stops watching an inode the set of events which * dnotify cares about for that inode may change. This function runs the - * list of everything receiving dnotify events about this directory and ca= lculates - * the set of all those events. After it updates what dnotify is interest= ed in - * it calls the fsnotify function so it can update the set of all events r= elevant + * list of everything receiving dnotify events about this directory and + * calculates the set of all those events. After it updates what dnotify = is + * interested in it returns true if the fsnotify function should be called + * (after dropping the lock) so it can update the set of all events releva= nt * to this inode. */ -static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) +static bool dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) { __u32 new_mask =3D 0; struct dnotify_struct *dn; @@ -72,10 +73,9 @@ static void dnotify_recalc_inode_mask(struct fsnotify_ma= rk *fsn_mark) for (dn =3D dn_mark->dn; dn !=3D NULL; dn =3D dn->dn_next) new_mask |=3D (dn->dn_mask & ~FS_DN_MULTISHOT); if (fsn_mark->mask =3D=3D new_mask) - return; + return false; fsn_mark->mask =3D new_mask; - - fsnotify_recalc_mask(fsn_mark->connector); + return true; } =20 /* @@ -94,6 +94,7 @@ static int dnotify_handle_event(struct fsnotify_mark *ino= de_mark, u32 mask, struct dnotify_struct *dn; struct dnotify_struct **prev; struct fown_struct *fown; + bool need_recalc =3D false; __u32 test_mask =3D mask & ~FS_EVENT_ON_CHILD; =20 /* not a dir, dnotify doesn't care */ @@ -116,11 +117,15 @@ static int dnotify_handle_event(struct fsnotify_mark = *inode_mark, u32 mask, else { *prev =3D dn->dn_next; kmem_cache_free(dnotify_struct_cache, dn); - dnotify_recalc_inode_mask(inode_mark); + need_recalc =3D true; } } =20 + if (need_recalc) + need_recalc =3D dnotify_recalc_inode_mask(inode_mark); spin_unlock(&inode_mark->lock); + if (need_recalc) + fsnotify_recalc_mask(inode_mark->connector); =20 return 0; } @@ -156,6 +161,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) struct dnotify_struct **prev; struct inode *inode; bool free =3D false; + bool need_recalc =3D false; =20 inode =3D file_inode(filp); if (!S_ISDIR(inode->i_mode)) @@ -174,13 +180,16 @@ void dnotify_flush(struct file *filp, fl_owner_t id) if ((dn->dn_owner =3D=3D id) && (dn->dn_filp =3D=3D filp)) { *prev =3D dn->dn_next; kmem_cache_free(dnotify_struct_cache, dn); - dnotify_recalc_inode_mask(fsn_mark); + if (dnotify_recalc_inode_mask(fsn_mark)) + need_recalc =3D true; break; } prev =3D &dn->dn_next; } =20 spin_unlock(&fsn_mark->lock); + if (need_recalc) + fsnotify_recalc_mask(fsn_mark->connector); =20 /* nothing else could have found us thanks to the dnotify_groups mark_mutex */ @@ -265,6 +274,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned= int arg) fl_owner_t id =3D current->files; struct file *f =3D NULL; int destroy =3D 0, error =3D 0; + bool need_recalc =3D false; __u32 mask; =20 /* we use these to tell if we need to kfree */ @@ -377,9 +387,11 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigne= d int arg) else if (error =3D=3D -EEXIST) error =3D 0; =20 - dnotify_recalc_inode_mask(fsn_mark); + need_recalc =3D dnotify_recalc_inode_mask(fsn_mark); out: spin_unlock(&fsn_mark->lock); + if (need_recalc) + fsnotify_recalc_mask(fsn_mark->connector); =20 if (destroy) fsnotify_detach_mark(fsn_mark); --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 902C92DB7BF; Sat, 15 Aug 2026 04:29:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768160; cv=none; b=k6cYprQpOeKIdTsrEvK8HI9bz7WYJZx6mnJIQLceogZ7ODfCFFsrpTqb1eNOQjgoESJQ7h1tqV6ma/jpHsKS5Abm5P5id8hoL7xM7e9ouUDFTKnpbSU1Ri3BKZ6BIldo8/5LmEITN1KL0u2+fdfBI63TsE58i8M5yeBEGizVqi0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768160; c=relaxed/simple; bh=ZE2AWEM7O60kQNA58ZkvgPkhSH4ss7eUl3SaCWj191U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kmLP48Ca4YjyzURRGyVidjVqiQh0DBriPxMA65X/OPTjWw7db0ewItxqJVU3E9Nfyn7ge7owMllJrn4VwTcSRFBc923adu9U8hyZ0KT7BS+5J3+S3G8ytvDF1xH4h4AqLUe2Wkm1jmveWckFxznK2d+omSV+A9CNaYms02cgbmw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=iQYsNxHm; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=hyWnXGeB; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="iQYsNxHm"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="hyWnXGeB" Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailflow.phl.internal (Postfix) with ESMTP id DB9DB13803F8; Sat, 15 Aug 2026 00:29:18 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-04.internal (MEProxy); Sat, 15 Aug 2026 00:29:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768158; x=1786775358; bh=MTJXqUkyboP6nT1GdTre2i6fxL2R8FyE2y1tAnQFr54=; b= iQYsNxHmTqnqXN9YIEHGTBNqeP90eSrxSPZEDBAstp6pqBfxQNOGYYj0Ob+LrCX0 IeJFxZuRNkjRToAglDkBPadPiVj3blQYQA2Yjt3Vv67SmrFA+T07XrXO9GU+3ksQ 0yq2JfM92++mqmYBnG/k5D7HraoAr76TypGIFwJNSjSsRsk3GHwx075wQ0t3ZAQ6 hUPIuKOL1SBGQk4HM2WAL8qrI07pfzZvXgZyziktOMS2UaWOHb06zTs9cD5s69tk ZT1E4z0JHB5++7i5Q8XMakocUpDJcbs63uSHs0qUT+DuKX7BgoQ72VnBYgUPE8os PxeVj046br0Fkrc2vnhHDA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768158; x=1786775358; bh=M TJXqUkyboP6nT1GdTre2i6fxL2R8FyE2y1tAnQFr54=; b=hyWnXGeBGBjoTLk4B tcBhYbvO3hKJ3RL6PBhXODlknM2ULrDYX83e5FsHeNG8L2lvCr0hmzTTdxNQRXUu Mdjcum5s9qXNzugGN86r21ldea9SY8pHyxK6AM2//RlBO1B8oqmnXIU2zUO1XCqz qx6iOGXnITXWE41WjJjOoDN6hTtSKE3TP/nWRCEhH4ll7GpE8ALdD3ZFMj7sSA4s uk2nEsFUWPUUYpOhac+Yfp16KWoZN6tteoXfY6+2fbhZQxdJR/1SLpwHRw+DWfNw A0FPcz7M6K5BWCJOrxSG6OJmQRYfYyG0HQO966gEUizJxHngRyShygSoINB3etiF PTwOg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTF9KskX6ORZkk2qDbanJAqhpO1c3Xju1rB/XGbwQvOGWemlAS7RTfehH6z/blxuZu ndq9JpuBON/sKJpHNFmlA8NZthzZuohefFsXvvzkhDLNc/boPY1CbYwGZ3ejocQdZP5Ev/ BXLTdsGGIGk/QWYctoHjfRUZGHXRv5et6FUSLml8RkvDkfsb7WSgppX3LyXjWcFTLwfp/k XOfgf9r/SZsCIW4bEY4xzTmE8sCd1BMMrUIBiSLPUM5HPZAu9IGndquxD0N2k1kJS4EkJO uSSxartPr+p/2sBY7kb8VaiOyCHt8JoqHMJjX2cNsGCbf1T449z1owAvKjvcnWl37FvYCJ /8WMwfkQVLpPQ3C5lHBVZt7sM9Uzikm2MYqCDrsEuafBjLRBE7DuzED7NYTvSWa5sMEDTa CWGxclX/6PIYcR6Qh4v4AE/hAtA2N/j+G+pO9cs9TV6Jla1UrDHwg1knSwGjwVRrUsN678 MQNZvJxAXot0nE/7DgKB2wKTCeGMl6arvqMiYDPs3Gj0wgiC2CCl7DmITUMPy6yeVjbhf2 p974jswAGkRxBAJrLKcVaaxk7q27/hZZ52PuTqKQrg8861pX+HdOhyEHBjAwn+I0hNmpoC JHQP+fYk2DSVo9q16f7P0FoZSicAzwlBZ0DXk7V60ijseMYd+sS2uuEhkPDQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:12 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 07/18] fsnotify: reduce i_lock hold time in fsnotify_set_children_dentry_flags() Date: Sat, 15 Aug 2026 14:21:24 +1000 Message-ID: <20260815042707.2535717-8-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Rather than hold i_lock across a d_children walk, dget() a reference to the dentry and drop the i_lock before the walk. This is easily done with d_find_alias(). This requires that we dput() which can sleep. Now that no locks are held across calls to fsnotify_set_children_dentry_flags(), this is safe. Signed-off-by: NeilBrown --- fs/notify/fsnotify.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 90a2121fc54a..4a383d4d8a7b 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -71,27 +71,28 @@ void fsnotify_sb_free(struct super_block *sb) */ void fsnotify_set_children_dentry_flags(struct inode *inode) { - struct dentry *alias; + struct dentry *alias, *child; =20 if (!S_ISDIR(inode->i_mode)) return; =20 - spin_lock(&inode->i_lock); - /* run all of the dentries associated with this inode. Since this is a - * directory, there damn well better only be one item on this list */ - for_each_alias(alias, inode) { - struct dentry *child; - - /* run all of the children of the original inode and fix their - * d_flags to indicate parental interest (their parent is the - * original inode) */ - d_for_each_positive_child(child, alias) { - spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); - child->d_flags |=3D DCACHE_FSNOTIFY_PARENT_WATCHED; - spin_unlock(&child->d_lock); - } + /* Find the dentry for inode - there can only be one */ + alias =3D d_find_alias(inode); + + if (!alias) + return; + + /* + * run all of the children of the original inode and fix their + * d_flags to indicate parental interest (their parent is the + * original inode) + */ + d_for_each_positive_child(child, alias) { + spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); + child->d_flags |=3D DCACHE_FSNOTIFY_PARENT_WATCHED; + spin_unlock(&child->d_lock); } - spin_unlock(&inode->i_lock); + dput(alias); } =20 /* --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D57492222CC; Sat, 15 Aug 2026 04:29:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768171; cv=none; b=DHtsX8BZahHwVqC1mvHzHP7FI14vAt6npw/NVg1YAbqtYgm1sOs8B7qIYonexM79wt8QGYeKIrKTodhSIiaoEjMBul8Li+7GikCSCcqjIV7wChfQKyquSSx8jzsQwdXyYiiSZHnDp+M/Wv6BzvSLaxIFGweLD/GjxWLUsKwxKL8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768171; c=relaxed/simple; bh=AdhooIjboAu3YKY/yuVksKwU8xau5i7EOd+Vl1SZzvQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sAjGKMIXutpUoaCcikkXhizi4SABtvJIPQqCCX3rbVqGW8aRv4r6ss/p1lul/7vNXVRQfv5lcOcL495okcK7mYPHjBKvTowzDWZZK0SJVCIZcrtPlf5IX5Ch5L7wQPc1MOuAuzHRCcmrSqXCeo7KOJVlE6BTBti/qRbNrbawYKU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=ZR4KrllY; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=OHQh6o/D; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="ZR4KrllY"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="OHQh6o/D" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id EAA3213803F8; Sat, 15 Aug 2026 00:29:28 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:29:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768168; x=1786775368; bh=2qeLuelJx2/+SBs2S68hwoXODkH6n7+CkxfeqKI7W2s=; b= ZR4KrllYxWnBYgC4dsMIDPZkLXfN6UK1oOr1OqWkALKcfMzAeG8LVg/viclNxycS 4kqiDGc3DE4Z4yIxhSDaYQ0QDmxWzIF8mr2jP2Qnj5dfr6kTmpd0piI5+IwCDt4m Gr/y7zY8nygnvK3DoQEaf0Sv8RWji+l1Sqh51WJwD00Jv7ozQMgTpHHj+Bdyv0xL oqeJJ3ZN9MRTnNqbyypNIVnB6DrfkA2nIdwdmAxK5IXT2mg/zD9HUG2iXQbK7toZ eaeU9Axb2/T4xC9p8CkKfN3cjeDC1vj9M7Z7NZhnXIxy2Ut5fQaIw3f0B8PnHWgP sQ+OUVgbcjDSmkjTHUHSkg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768168; x=1786775368; bh=2 qeLuelJx2/+SBs2S68hwoXODkH6n7+CkxfeqKI7W2s=; b=OHQh6o/Dp9Bohl9Er mPbsOGSvRBLcxD+15NWWBFgozYJVvJbRqsP8YPuC+t3e8/sS8PH29EU00mD4SNy0 HEZ2Jm66WfGX2j/VXv6p2XM6XwvrpUlx6ptHVqd1VmxuffYtCIbjMiXnX2P+zaZ+ aaOpaxkLvd1ceDBqaSD3N1/SxPoP+++OxOeql1TKQrbqaTTX2BFFRJbvzbtEU+1w LOAWw25tdazkuIBzYJhnt3+wshR23vZUuIpP+b3hVj6usI5QgXrDKfMgETlD1WO5 UMtSTj8+UOyFCUXhuUDLd0BYiUeZsiAxVFO94U3iViUXF40rkvjPxcWRDguaVdqm rhzGw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE47D4+VfwQFQzr11DJvQLYIXqMi0hZV0dErVHB+rL0DNVNd8lKaFjc/DBGC/9Z+e 1XqqSxG1COnVE2p0h+gE+3sT3WHc2s4pfHSbkJDPkdz9l078ivxoBUX7LaQuIqMUvNfdCK OTO6fH4CbhonnMAQrCy6mAjkD3yfDfiioSRLElGFQqu4IKzk74/3+ETPYsMsadCTSlIE72 pFesoG42fVWkR1DR5x8Czt3y4MWTPZ7Vk8PZOOBmt7LfMXAwJXwlpNe3RczRrG53IXGKeB lZ2vtwNbgIUpnHC00hTYciEg8pKF9qQ82JcZyji4nf8ZRkE3Cre+0W/dXUWlpbwnOwzitG Ch201FCa68CyyiT9UPUmL5R7nuDBzo5e54dDHD3COMxf2yP3fi4ndKcc5O3oDVsmb8S9IM uD97AUUD4DvwjItpp22V3agGLAivOVOMAxrGXyWbiRnxRL7icIV7jaNx5Ex7prYayXIhz+ UiJnuYexXYZqo/dTaf3PSaDa1G0yv4qQ14LPP8t18GvE0/hMWZK9fN4vRqCZvSUFN/9pf8 8+7NFwQt6UpJSF7mbuayno783GhQQp4OnNMMJsvnH8nTAKSCwMURpLsm2fiPBycyVs4rLl XGUdWkZ+A6H2vRDD1uefDY7BuiGnaAq2rEXxnRt7xvYCvGZ5cogLMUAe4QxQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:22 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 08/18] libfs: simplify scan_positives() Date: Sat, 15 Aug 2026 14:21:25 +1000 Message-ID: <20260815042707.2535717-9-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown This patch removes explicit use of hlist_node from scan_positives() and callers, and consistently uses struct dentry instead. Previously scan_positives() had two args which were closely related: p and last. If last was not NULL, p was precisely &last->d_sib.next. If last WAS NULL, then p was &cursor->d_parent->d_children.first or &cursor->d_sib.next If, for the final case, we pass 'cursor' as 'last', then we only need 'last' not 'p'. For this to work we must dget(cursor) before passing it, as scan_positives() calls dput() on last. So now to scan from the start, pass NULL; to scan from a particular dentry, pass that dentry. Note that scan_positives() can be given a "last' which is unhashed. This happens if, for example, dcache_dir_lseek is called to seek beyond the end of the directory - thus leaving the cursor detached - and then dcache_readdir() is called. "next" will be the detached cursor which will be passed in to scan_positives() as "last". d_next_sibling() of this will be NULL. Signed-off-by: NeilBrown --- fs/libfs.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 8e99067079e8..c2b09e72cbd8 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -103,18 +103,23 @@ EXPORT_SYMBOL(dcache_dir_close); * We are looking for th positive after

; if * found, dentry is grabbed and returned to caller. * If no such element exists, NULL is returned. + * If last has been removed from the d_children list + * (i.e. last->d_sib is unhashed) then it is treated like + * the last element of the list and %NULL is returned. */ static struct dentry *scan_positives(struct dentry *cursor, - struct hlist_node **p, - loff_t count, - struct dentry *last) + struct dentry *last, + loff_t count) { struct dentry *dentry =3D cursor->d_parent, *found =3D NULL; + struct dentry *next; =20 spin_lock(&dentry->d_lock); - while (*p) { - struct dentry *d =3D hlist_entry(*p, struct dentry, d_sib); - p =3D &d->d_sib.next; + next =3D last ? d_next_sibling(last) : d_first_child(dentry); + while (next) { + struct dentry *d =3D next; + + next =3D d_next_sibling(next); // we must at least skip cursors, to avoid livelocks if (d->d_flags & DCACHE_DENTRY_CURSOR) continue; @@ -129,10 +134,10 @@ static struct dentry *scan_positives(struct dentry *c= ursor, } if (need_resched()) { hlist_move_behind(&cursor->d_sib, &d->d_sib); - p =3D &cursor->d_sib.next; spin_unlock(&dentry->d_lock); cond_resched(); spin_lock(&dentry->d_lock); + next =3D d_next_sibling(cursor); } } spin_unlock(&dentry->d_lock); @@ -161,8 +166,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offse= t, int whence) inode_lock_shared(dentry->d_inode); =20 if (offset > 2) - to =3D scan_positives(cursor, &dentry->d_children.first, - offset - 2, NULL); + to =3D scan_positives(cursor, NULL, offset - 2); spin_lock(&dentry->d_lock); if (to) hlist_move_behind(&cursor->d_sib, &to->d_sib); @@ -190,23 +194,19 @@ int dcache_readdir(struct file *file, struct dir_cont= ext *ctx) struct dentry *dentry =3D file->f_path.dentry; struct dentry *cursor =3D file->private_data; struct dentry *next =3D NULL; - struct hlist_node **p; =20 if (!dir_emit_dots(file, ctx)) return 0; =20 - if (ctx->pos =3D=3D 2) - p =3D &dentry->d_children.first; - else - p =3D &cursor->d_sib.next; + if (ctx->pos > 2) + next =3D dget(cursor); =20 - while ((next =3D scan_positives(cursor, p, 1, next)) !=3D NULL) { + while ((next =3D scan_positives(cursor, next, 1)) !=3D NULL) { if (!dir_emit(ctx, next->d_name.name, next->d_name.len, d_inode(next)->i_ino, fs_umode_to_dtype(d_inode(next)->i_mode))) break; ctx->pos++; - p =3D &next->d_sib.next; } spin_lock(&dentry->d_lock); if (next) --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7934D2E888C; Sat, 15 Aug 2026 04:29:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768179; cv=none; b=RP/pIsHdXcCz4fRPr1D4/E10L7wfNiyE3vmJExzCnGfncOY2R9uEGtyYyBazjO0em7hyOIH9g7yunBcXrbXvkU1O6Qprxu6CYcjhcdTIQ6M2sLE6sBB+iw4eRnJMCh2SUhdgd5qwlFymedUwSMarLrpyTWYH4s0oNOpi2t6OhpA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768179; c=relaxed/simple; bh=5uGTVSye3mf5dZIRBjYy2z/ZTSIaYWwrRnaJjtdebsk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MkchFR/HbrOQYV/YkpM0Ee4mqkt6Ng2/0hnEw4tx4k5hJvLUF31ABaOlK+uF46TDcDDO6mcn+r748Ufjte26VmrYHfh/7/UqT8UyjO4KR+ugsRlZMy+10NoWpK5u84C2w0DLZ9yOybsSk/azC4XlZsh/A7SIvTY5dKFlqEhOe5Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=An9Hi3FR; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=MpOLJi1K; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="An9Hi3FR"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="MpOLJi1K" Received: from phl-compute-11.internal (phl-compute-11.internal [10.202.2.51]) by mailflow.phl.internal (Postfix) with ESMTP id 91F731380411; Sat, 15 Aug 2026 00:29:37 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-11.internal (MEProxy); Sat, 15 Aug 2026 00:29:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768177; x=1786775377; bh=xugvkkdASQjNIkrgB5+lqBJ1a48J5bnIdSUDy+kkN7k=; b= An9Hi3FRGYa4y7NQfa94yik5YeDMPbgDFTdk4flDun4WXLa84v5x/YzKvILDLSZM jm+neQD3xXylmsHoiNRPJky3xmbZKvCSJoILUZMr2DTKDsPE1LvXQZ1ydT29btLg GzIvvnIJPjOLz8zKKtickGVHAhtv/UpDiHECPaAlG7WTcylwZJFExh23FIwkW0dZ rp9kwt69NLHfcbxxL/RPk383ozC9qPV1FV1+5lFRRzdVx9P9NuledAjb3kJ8XgSZ fXUTGXClRr+YWufeWopyTQXPgcvAzf5ywPFZwe6ECIK73mg/AlncfgVjtcu0fJEo GK8LuPGW5hLIuQWIqwwQVg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768177; x=1786775377; bh=x ugvkkdASQjNIkrgB5+lqBJ1a48J5bnIdSUDy+kkN7k=; b=MpOLJi1KWGhuLp1Jt Pxn3fGpoXpHFBJyXB3F7pxgmCm0RMAQCTZhz66s1uwyOt89C/P5PorZLCP0mHhIg GfgIzcNVcZUOua5EtCfHQCGevRlFrO8bpPL3HpMqbcTuyYM7yCTa0q23s8wrVuVo BXCiFz2qw5vr0BkqnpW0tUAwc+pa614ymYjtSBXUkcz7TeS/aqfknm3wIxH63w15 TNdz4BCxSIh6SC7OO+GtzPVgd6LFIU6YgDnHLP0Yn4Q+DOUVuZ4GM6OYT5UkQAKt ToKy/RX9mIniQ4En+tjtTkTk0vuju3CUOn0jR2T8eLIE+IuLDxm7t2KM5KE5CBMd /rs4g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEYOd3tLu5dATIbifwhlYvY0qyYOt7s1LgDprEXebOtP02E/NfWDhmB6dUHRD18Mw M/OVd5zhrG+UTD+zvSQphReiWNJaCd0AqwUD63tHfAJF2OAEGvFg1iC8SkfXHW4Cbq3Pnv XZPdOI+4XvyfDrMe9ntOWfnHEDm7Vl4MwVM6/98uzVFr9W5lPBzuk8llcQfOSsZLGGgf8M 1akEE1al0EFoJJ4d9fnySO8LzXZFHrFib9IETFD1LEL7DAdqppQ7UcHFMAN4HHBzYumdeq UmiiM2nwa1tgBmTDGFT6cgwcylPb6+Qw0oEVRuLdEgoMQRjiQsSj7nR2Cv5Z5tDGgputOo kZ6J9sqBzCor7Zdx1pNuXjfKxQm5HAp1Iwc3l3RQQ89v72cA5wAIMhytU0LGNbulNUIj5K zwufoLCPJY9GPR96ITIx3uYtGZ3wM4gQBKR9yY5KhXBkEzsucIYfm9a9m0ZvDSbF/qkcLf 8nz8u+7lS2nFeEa+8oKeb880/oU29jA4XiKcNMi6Kj3fEKOA9MEZiSH4mPlALmSZLpSL4D VE0GwLdfOTQZlr/hukwLqfiKM+6IUUg3If59HXotEfjK3dDmB9hqKw/CGarUSeex07Kvff qBpt7jZC+6ggK9JJYXXEbXhXv9URF+1KIT/1knbn7EPoxMe9F49OcxbaIA3A X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:31 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 09/18] libfs: change scan_positives() to use d_for_each_positive_child_continue() Date: Sat, 15 Aug 2026 14:21:26 +1000 Message-ID: <20260815042707.2535717-10-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Using d_for_each_positive_child_continue() simplifies this code slightly and make is easier to read. Signed-off-by: NeilBrown --- fs/libfs.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index c2b09e72cbd8..398fae675207 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -112,17 +112,9 @@ static struct dentry *scan_positives(struct dentry *cu= rsor, loff_t count) { struct dentry *dentry =3D cursor->d_parent, *found =3D NULL; - struct dentry *next; + struct dentry *d =3D last; =20 - spin_lock(&dentry->d_lock); - next =3D last ? d_next_sibling(last) : d_first_child(dentry); - while (next) { - struct dentry *d =3D next; - - next =3D d_next_sibling(next); - // we must at least skip cursors, to avoid livelocks - if (d->d_flags & DCACHE_DENTRY_CURSOR) - continue; + d_for_each_positive_child_continue(d, dentry) { if (simple_positive(d) && !--count) { spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); if (simple_positive(d)) @@ -134,13 +126,12 @@ static struct dentry *scan_positives(struct dentry *c= ursor, } if (need_resched()) { hlist_move_behind(&cursor->d_sib, &d->d_sib); + d =3D cursor; spin_unlock(&dentry->d_lock); cond_resched(); spin_lock(&dentry->d_lock); - next =3D d_next_sibling(cursor); } } - spin_unlock(&dentry->d_lock); dput(last); return found; } --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD9F22E8DEC; Sat, 15 Aug 2026 04:29:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768188; cv=none; b=Q83uHbparg13Ra0I5N3YLeNd7lNDZwuPWManSYZyK1WuVCPMBvnRUkB0PJXwJlnnQEqxEUYSWpnS2IHR/MiHS85AzinPBBwLUXil13YtkgIhC+rN+HRccvC/t5J4t5UyWh/CFGaYtyhWGhnUY0uk+zyH9EVJfzbHYQK8xxrAA74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768188; c=relaxed/simple; bh=EZGnXuikWmFjT40ONNIsrdGsW79YaEfq6MXY9Qq7SaM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CYwAHfgh0ZVTBZX50znySP0GjQ3mbb+Y2rMQXbGYJp4LwFXqYNyW/hCJRWNcLtBhGFh0FjwW7brAYmcT6Twqch6wJBH80UBVjMYVxx4YzdOWmPsN5JiLzxm7+rfPCzFLEV5IE8a1Esari9JxMhQXWTCNEJtWpmY+fcVrYU9dpQM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=LMeHqGrG; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=XCqhSiPE; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="LMeHqGrG"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="XCqhSiPE" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailflow.phl.internal (Postfix) with ESMTP id E9FF713803F8; Sat, 15 Aug 2026 00:29:45 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Sat, 15 Aug 2026 00:29:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768185; x=1786775385; bh=V15p7YB1wxkGPcoPidTUC9Y0oWBoIwi0W1mfdrFuHck=; b= LMeHqGrGTjpjg317G/5toOtGJUn411/cAslSJIP2/3meBmitcbUMeHVDrB9+24Y2 mR+c+CsEocyVI46IR+nsqY9if0XMVWf4ueNBZQY0do9LDrY0vsbZEi/VNUAwghDY B39HuDD0bJmZ3EMLgJ7GUJZ9XEdA5a5HrJBXdhlheh9fB1fzDqnVQVlycInvP3AR s9z2q2By40CwWRS2sh/lMYHfe3ua7IuaY1MXLX754jKYfObQ97Ikocfh5uOKIVDj aYaZ4EtthdiZSkhL+m+3dw3sIVSqRRv9v0rpuEQGbXvuXXf/s1JSGQTt6Gnln76k ffDjIajhZIkDtfRFNbbEWQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768185; x=1786775385; bh=V 15p7YB1wxkGPcoPidTUC9Y0oWBoIwi0W1mfdrFuHck=; b=XCqhSiPEE8zxpXhEi 25mPzVa3HlHSQJNBe0Rh27aDSU9B/zMyhG4ppSHMa3IUPLnVfFQkdJdsBPanfLkF M8E7rrS6F4eAWQsRI5PxEzTn5kYDRQVYAw7qrl6buzJbvenTYpuTUAupEMZgRCRV dIErpKJpGH65cIorCGdXzjvt5SVqP4zi6xXdn8585Tz+dkCyKbRr0vPQpraBqS+m 7AmlcV6e604VlnASF3gNzX7i8ejpSMmGOvp//P19ffTzonGWX4LhcgCihnRhFsd4 4KDC0oNbUQxMYXXf7l4m2L3xhy+6mGPqDEcV3UEbJI/8nw6KA6qu6hRKnOPbqO4J NUNbw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE47D4+VfwQFQzr11DJvQLYIXqMi0hZV0dErVHB+rL0DNVNd8lKaFjc/DBGC/9Z+e 1XqqSxG1COnVE2p0h+gE+3sT3WHc2s4pfHSbkJDPkdz9l078ivxoBUX7LaQuIqMUvNfdCK OTO6fH4CbhonnMAQrCy6mAjkD3yfDfiioSRLElGFQqu4IKzk74/3+ETPYsMsadCTSlIE72 pFesoG42fVWkR1DR5x8Czt3y4MWTPZ7Vk8PZOOBmt7LfMXAwJXwlpNe3RczRrG53IXGKeB lZ2vtwNbgIUpnHC00hTYciEg8pKF9qQ82JcZyji4nf8ZRkE3Cre+0W/dXUWlpbwnOwzilo oGgS/Vr84mqDIFHdcOGo8SGnshn8wyVFzanBYe1PRk47FC4N2o3JW6XIwaqDE8BgOOY8hS ZY4XQtz8qfO7mITcXHWiBRdPCBerznxyx7JT+vqjedup7QsMUu24nJ3n3+WbEvZNPt7skY lErRt8RgYRoV6vSZIRB8SZh6PaNwpLdoHw0uT2gkFzUrZYaFqppyP7VMNOiL5kxqYEnQDE UoDDsfsp8CwAfIW1f9XmaWwh9Ob9Djh08hg/L14OltoBjEDfkJmtTjw9q1hYoHBSw0z1ZV 3dpebE0dqj9iApNXewSxkbl8DJtBX7P4TOtRLnaEGdQkMw7vyDJPDKXehzOQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:40 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 10/18] libfs: allow scan_positives() to be called without a cursor. Date: Sat, 15 Aug 2026 14:21:27 +1000 Message-ID: <20260815042707.2535717-11-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Rather than taking parent from cursor, pass it in explicitly. And only cond_sched() if a cursor is available. This will allow scan_positives() to be used in place of find_positive_dentry(). Signed-off-by: NeilBrown --- fs/libfs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 398fae675207..21abe0074c77 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -107,11 +107,12 @@ EXPORT_SYMBOL(dcache_dir_close); * (i.e. last->d_sib is unhashed) then it is treated like * the last element of the list and %NULL is returned. */ -static struct dentry *scan_positives(struct dentry *cursor, +static struct dentry *scan_positives(struct dentry *dentry, + struct dentry *cursor, struct dentry *last, loff_t count) { - struct dentry *dentry =3D cursor->d_parent, *found =3D NULL; + struct dentry *found =3D NULL; struct dentry *d =3D last; =20 d_for_each_positive_child_continue(d, dentry) { @@ -124,7 +125,7 @@ static struct dentry *scan_positives(struct dentry *cur= sor, break; count =3D 1; } - if (need_resched()) { + if (cursor && need_resched()) { hlist_move_behind(&cursor->d_sib, &d->d_sib); d =3D cursor; spin_unlock(&dentry->d_lock); @@ -157,7 +158,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offse= t, int whence) inode_lock_shared(dentry->d_inode); =20 if (offset > 2) - to =3D scan_positives(cursor, NULL, offset - 2); + to =3D scan_positives(dentry, cursor, NULL, offset - 2); spin_lock(&dentry->d_lock); if (to) hlist_move_behind(&cursor->d_sib, &to->d_sib); @@ -192,7 +193,7 @@ int dcache_readdir(struct file *file, struct dir_contex= t *ctx) if (ctx->pos > 2) next =3D dget(cursor); =20 - while ((next =3D scan_positives(cursor, next, 1)) !=3D NULL) { + while ((next =3D scan_positives(dentry, cursor, next, 1)) !=3D NULL) { if (!dir_emit(ctx, next->d_name.name, next->d_name.len, d_inode(next)->i_ino, fs_umode_to_dtype(d_inode(next)->i_mode))) --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8FF13148C9; Sat, 15 Aug 2026 04:29:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768197; cv=none; b=LCI9oUh9HXNxHNQptlgnltlKuULrY1EqjlBhkuB6yvrlGy6ub6wXAcCaZOoUJCdCQSYaUtNZWPpdziQG8xT0nenBOldKdQWb++TPQyCu1gMzxwwaTYAqxYkbv+6SNckGBgnXRnwjNgYw9DVies/ze01azl1d7efoopujxSyxQwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768197; c=relaxed/simple; bh=Iw3VALCpZlU5FoCwNGf9vMOQGrtTMvPWAyD6VVPWZnQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cPe2syUOP5EV2J5Sso+BDOFRBU44dxsehunk50Shrdz3wLKMuodpzo4tCx0f6RJZbJvnk7mT8Ty6RWF7BZuVhH6GGpJigt7p0YYMOCSu2jCRMlRN9w8pnC6+Ihc+UUb6Lt2jiOkgrWeltmDsvL1VhyyWleJoMEcgbMqe2jNjheM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=Vau827fi; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=B0I1+2iu; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="Vau827fi"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="B0I1+2iu" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailflow.phl.internal (Postfix) with ESMTP id CECF01380415; Sat, 15 Aug 2026 00:29:54 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-06.internal (MEProxy); Sat, 15 Aug 2026 00:29:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768194; x=1786775394; bh=ipVqCw+8UnsuKe/hZ8nVpr7wwOvOMF0TbptTc3tK3HQ=; b= Vau827fixuD0uFsqSIYWVABs5FAKMTfHxa1uHY652TuKM1fxMil8ZAZin4n1bUfF MKhbf0pdP+TZiOHy5piffVp1m42V+BsL2Amuxt4fZtQNJ1uEVOn5FELgdqsZGtHS H4PeBnBjnKv+I5oZWWfwS73llJzB3Z9kLnka+WaE+nnFlUGjDgdjHHW/mXxj5Ms6 JEoD59T8F9JdV7Oi5Ng0J+NpsI+wHoupn+/u8MWhpSGH0s+gLw81tGsYRvfwyhMO OPtI7oEixQgqwktzqwNpYorNnoh7mfbx0N+ZCHbNkpRxBGYm47IJ0nx+hYBlLGh2 cBbmeNJ52nON3ojH+WaixQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768194; x=1786775394; bh=i pVqCw+8UnsuKe/hZ8nVpr7wwOvOMF0TbptTc3tK3HQ=; b=B0I1+2iu+030Hltrv 5gs4XjIBIQc44/0jsYIRyfL634tHP8c4gzATlYzfGShVWK9k5mO3HVz7riCQpshf F4CoqUDKmlnnINAJxMVqgU3O5fazijrbPCwQxAYVkWzMGsb74unHHjUsA4bAE9bZ V3pJ3NjjqovbMLSdlrX3P9DZEpRvPHmtdsKBRgq+jhiMG+sm7XbtuWlRSL+Ebt5b hAdK6Mc6ugB+jipSrf2DEmCSR4aDw4Ast072I20L+rAZFLj763VooKOSqAwDYBhR fxun3CrOQSL48hY9FmL8Pb4tlzAwoPPpARWJAlKsX/zXSvqWVIPa3XAhFgg9X7tK nyc3Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTECw6EEPYbx+7BaaLSeXge8TL0IFS/e22W0DFWlbDFG9eII2nLkfnvZprtL9LDp1m HNcIj6bmqu83Qm/YUapqU6PBN6WcNm8P6Gy6RDWT6cAAmyaKdoJVe4WWntEcEJw7UAQpab Ivov0q9n39VXDrfptfrf0jUwc+MgicKL4WCNr5zVI2XTGGzlh1W80uuvtEo9Ovpf8kur1R vP/VXSxnYRhNfcG7+F4fSgFn0Gt4iNMYjiANVHauJEWjElKvMPdOxk4oexwOk01N0r04qi 8M218+E0MCoqYMSR4rZhl0wfvSlTNBrLCF/rmquNqRbB0zK7AmmuLtO4fjAl8K2V5bn2Ju AkPgxmk04sv0SEleau/gWRpcN9fQrqXpmy9K17LojMc+D7IS+ERklte0Egn2YkzKsSXell FR52E1sdUw2TizUIpW4CEZcLbUJBhNvYBFS+2dvY093H2f8p4N5j8fgjdIebRRd/FJGjbB djQb4dbqK67dbUq7WVngecIPIps8ykAO0KLmpOYpLSwCd90mOAtZmRVIQHEm5zZR305rko Zzh899W5OkAR69cb95xBD4+5R9sG3O94/j9jk8Y1PlTsYCwdV2n2p7ZgbvwPygbpYg3XbA dXWNy7bJhPiXQtzZglXYUm7766vkbKqSY4J4LlwQX07M90uIC4o33mWR2I8Q X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:49 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 11/18] libfs: replace find_positive_dentry() with scan_positives() Date: Sat, 15 Aug 2026 14:21:28 +1000 Message-ID: <20260815042707.2535717-12-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown scan_positives() can be used in place of find_positive_dentry(). This makes offset_iterate_dir() simpler as 'next' is no longer needed. offset_dir_lookup() needs an extra loop to find a child on which a ref can be taken, as scan_positives() requires a dentry with a ref. I think this makes a cleaner separation as the RCU read lock no longer needs to be held over the scan call. This will be important in a future patch. Using scan_positives() means, after the next patch, that cursors can appear on the d_sib list, so when finding a dentry from the offset, which might be dead by now (dentry_kill()) we need to step over any cursors to find something we can take a reference on. This requires parent->d_lock as cursors are not RCU-safe. We add lockref_get_not_dead_nested() so that we can opportunistically get a ref on a child while holding the lock on the parent. Signed-off-by: NeilBrown --- fs/libfs.c | 58 ++++++++++++++++------------------------- include/linux/lockref.h | 12 ++++++++- lib/lockref.c | 10 ++++--- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 21abe0074c77..44e8dec51237 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -438,47 +438,39 @@ static loff_t offset_dir_llseek(struct file *file, lo= ff_t offset, int whence) return vfs_setpos(file, offset, LONG_MAX); } =20 -static struct dentry *find_positive_dentry(struct dentry *parent, - struct dentry *dentry, - bool next) -{ - struct dentry *found =3D NULL; - - spin_lock(&parent->d_lock); - if (next) - dentry =3D d_next_sibling(dentry); - else if (!dentry) - dentry =3D d_first_child(parent); - hlist_for_each_entry_from(dentry, d_sib) { - if (!simple_positive(dentry)) - continue; - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - if (simple_positive(dentry)) - found =3D dget_dlock(dentry); - spin_unlock(&dentry->d_lock); - if (likely(found)) - break; - } - spin_unlock(&parent->d_lock); - return found; -} - static noinline_for_stack struct dentry * offset_dir_lookup(struct dentry *parent, loff_t offset) { struct inode *inode =3D d_inode(parent); struct offset_ctx *octx =3D inode->i_op->get_offset_ctx(inode); - struct dentry *child, *found =3D NULL; + struct dentry *found =3D NULL; =20 MA_STATE(mas, &octx->mt, offset, offset); =20 if (offset =3D=3D DIR_OFFSET_FIRST) - found =3D find_positive_dentry(parent, NULL, false); + found =3D scan_positives(parent, NULL, NULL, 1); else { rcu_read_lock(); - child =3D mas_find_rev(&mas, DIR_OFFSET_MIN); - found =3D find_positive_dentry(parent, child, false); + spin_lock(&parent->d_lock); + found =3D mas_find_rev(&mas, DIR_OFFSET_MIN); + if (found) { + /* + * parent lock ensures found is still on + * the d_sib list, but it could be have been marked dead. + * So we need to find something we can get a ref on, + * which isn't a cursor, and isn't anything NORCU. + */ + hlist_for_each_entry_from(found, d_sib) { + if (!(found->d_flags & DCACHE_NORCU) && + lockref_get_not_dead_nested(&found->d_lockref, + DENTRY_D_LOCK_NESTED)) + break; + } + } + spin_unlock(&parent->d_lock); rcu_read_unlock(); + if (found && !simple_positive(found)) + found =3D scan_positives(parent, NULL, found, 1); } return found; } @@ -500,18 +492,14 @@ static void offset_iterate_dir(struct file *file, str= uct dir_context *ctx) if (!dentry) goto out_eod; while (true) { - struct dentry *next; - ctx->pos =3D dentry2offset(dentry); if (!offset_dir_emit(ctx, dentry)) break; =20 - next =3D find_positive_dentry(dir, dentry, true); - dput(dentry); + dentry =3D scan_positives(dir, NULL, dentry, 1); =20 - if (!next) + if (!dentry) goto out_eod; - dentry =3D next; } dput(dentry); return; diff --git a/include/linux/lockref.h b/include/linux/lockref.h index 6ded24cdb4a8..9da4fbc2cd13 100644 --- a/include/linux/lockref.h +++ b/include/linux/lockref.h @@ -52,7 +52,17 @@ bool lockref_get_not_zero(struct lockref *lockref); bool lockref_put_or_lock(struct lockref *lockref) __cond_acquires(false, &= lockref->lock); =20 void lockref_mark_dead(struct lockref *lockref); -bool lockref_get_not_dead(struct lockref *lockref); +bool lockref_get_not_dead_nested(struct lockref *lockref, int subclass); +/** + * lockref_get_not_dead - Increments count unless the ref is dead + * @lockref: pointer to lockref structure + * + * Return: 1 if count updated successfully or 0 if lockref was dead + */ +static inline bool lockref_get_not_dead(struct lockref *lockref) +{ + return lockref_get_not_dead_nested(lockref, 0); +} =20 /* Must be called under spinlock for reliable results */ static inline bool __lockref_is_dead(const struct lockref *l) diff --git a/lib/lockref.c b/lib/lockref.c index 5d8e3ef3860e..dddd26100a51 100644 --- a/lib/lockref.c +++ b/lib/lockref.c @@ -136,11 +136,13 @@ void lockref_mark_dead(struct lockref *lockref) EXPORT_SYMBOL(lockref_mark_dead); =20 /** - * lockref_get_not_dead - Increments count unless the ref is dead + * lockref_get_not_dead_nested - Increments count unless the ref is dead * @lockref: pointer to lockref structure + * @subclass: lockdep class for taking ->lock + * * Return: 1 if count updated successfully or 0 if lockref was dead */ -bool lockref_get_not_dead(struct lockref *lockref) +bool lockref_get_not_dead_nested(struct lockref *lockref, int subclass) { bool retval =3D false; =20 @@ -152,7 +154,7 @@ bool lockref_get_not_dead(struct lockref *lockref) return true; ); =20 - spin_lock(&lockref->lock); + spin_lock_nested(&lockref->lock, subclass); if (lockref->count >=3D 0) { lockref->count++; retval =3D true; @@ -160,4 +162,4 @@ bool lockref_get_not_dead(struct lockref *lockref) spin_unlock(&lockref->lock); return retval; } -EXPORT_SYMBOL(lockref_get_not_dead); +EXPORT_SYMBOL(lockref_get_not_dead_nested); --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A255427467F; Sat, 15 Aug 2026 04:30:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768206; cv=none; b=h25606D2HfJG2JjyxkAL4o1/+1EhmYU/HT5JOR8GkFlTtqDVs1gdHYc/vso2KD/sMu4j3JH+sPBJiUADjZIzgDywyonk6Ib/f+TA/hjIGBRC4tciIkIYigBOXmREX23Y8dI2yuveVptpB/5ISzc3ACHDIea6h8nBMyv3Ic0NBJw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768206; c=relaxed/simple; bh=TvnHV2tefMSKKygyPTlwcvcsvYYV1QRkGVk9vr+npJU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MsbngSuLLnj/tMPbD7+T5eI4qWrv6tLYPdVra9Hp+s+qx6yuqBlp9Rwrk54XCeRW++HOri0qBiljOCMOXzaMIoWTGeqTPMGiylb8RV70IrVZt/xiQ+HJfDwUVu/6iCBC2wRbcb/wtDRFgyYhL+/Hmszt2pc/DF60gMOsOpou2hA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=c4fRsT0f; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=UecsG8+z; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="c4fRsT0f"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="UecsG8+z" Received: from phl-compute-08.internal (phl-compute-08.internal [10.202.2.48]) by mailflow.phl.internal (Postfix) with ESMTP id 77F2113803F8; Sat, 15 Aug 2026 00:30:04 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-08.internal (MEProxy); Sat, 15 Aug 2026 00:30:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768204; x=1786775404; bh=4cbY3Uqqm5XV1+h9pYF3ZXa/Sv0rEkjLG5ntSp96UKk=; b= c4fRsT0fg6nwYYgsGA1q93hIxSTIZjpxiT9Ay31esGJSqYEgIjUHKVhchWdsojXr qZEltrvE9G4DiS8ianNPWwDPX0BRjyUK5XWSuFJCcQ2QqRzUTqpWkhCYPt3pahnz 5DZN0iRWsufcTWihUAkllb/ae3mCWJ5YrbW+DHtvwn3AITQkJ9zjcQMV8uksQaEJ UJarSReeilb61lBc63QUlpRKANpsIQTT/eXzmnDzsshy+FeXJUqPqKNFyjpB21lx 2Lnhhk4OV9YkNCXfiCZmrixJ0mGhT6+1lx1hxs9zFQtbqYhzoOcy+U+mBWRXDoY4 CmtS3294wrJeNLLA00ohgg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768204; x=1786775404; bh=4 cbY3Uqqm5XV1+h9pYF3ZXa/Sv0rEkjLG5ntSp96UKk=; b=UecsG8+zJNKMPIbVl L/z3RJtUEBInIuMFRolLm32td4gXm+x+0z1Mq4gZ6bpUqzpJN+zbTXJ9yUJCWhoP Al8Lgt5ND8t9rYgF7vSYMSdbRhWH2694ZDbF2N6k+lw3v876ktRrD4X709ERFPF4 Iz+A77Q6cuVP0lW/+LRjSoRvD3GQfiEvnSVel7rwn5/2nPcZ0l0egn4H2DINz2vS LwUtY5yRvMI8ErOU73xTymzkZYxIaY1FBbFSpd6OOkTYkJ3BJ6gbsvIpll8QSgmT H+cYO7ebp+Wjvu4/vGMO0AWLknq5zHpyJea9Lu0OAdBArXJQOWVNZ1orZGY85B4w yjl4Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEYOd3tLu5dATIbifwhlYvY0qyYOt7s1LgDprEXebOtP02E/NfWDhmB6dUHRD18Mw M/OVd5zhrG+UTD+zvSQphReiWNJaCd0AqwUD63tHfAJF2OAEGvFg1iC8SkfXHW4Cbq3Pnv XZPdOI+4XvyfDrMe9ntOWfnHEDm7Vl4MwVM6/98uzVFr9W5lPBzuk8llcQfOSsZLGGgf8M 1akEE1al0EFoJJ4d9fnySO8LzXZFHrFib9IETFD1LEL7DAdqppQ7UcHFMAN4HHBzYumdeq UmiiM2nwa1tgBmTDGFT6cgwcylPb6+Qw0oEVRuLdEgoMQRjiQsSj7nR2Cv5Z5tDGgputQ4 3+29daZolV23NZs67T+NuJROfBzyINC57Qfs+ZJtKr/KqOA/fZd/+0ZQZ1tNA3t6B8ILOj iYES9QArdR4N7gdbzOKvJ0DBFl4+Xk+YPHKHzL0eHfVFsctb5btjDWMZNRKyNJMeBzStK0 L0B8Yrfeg2eOcN8seNvbU35+K7CLgJJ/fZciO6VJHt9mhN7Ok0Rvlbt90/ZlI42NCCPuzy yGPaiNier6PhwmUM7Wv8aUc75ectYgFjCqDgbN4cHyqhAt/I/7k/SFLzejrm9wXr5LEAa/ oEywIfC6u3zephV6oquEp25psWerxRf7Uk4PXJWbC6J+KxTmp3O5Ixj/U/UQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:29:57 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 12/18] autofs: don't hold ->lookup_lock in get_next_positive_* Date: Sat, 15 Aug 2026 14:21:29 +1000 Message-ID: <20260815042707.2535717-13-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown get_next_positive_subdir() and get_next_positive_dentry() currently hold ->lookup_lock while walking the d_children list, which a subsequent patch will add schedule points to. So this spinlock will be a problem. The only data structures that a protected by ->lookup_lock are the sbi->expiring and sbi->active_list lists of inodes. Neither of these are accessed in these functions, so the lock cannot be needed. I think the presence of these locks is a hold-over from a previous locking scheme. Signed-Off-By: NeilBrown --- fs/autofs/expire.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c index ba1a3a2bfc9a..b6937c5936a5 100644 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@ -90,12 +90,9 @@ static struct dentry *positive_after(struct dentry *p, s= truct dentry *child) static struct dentry *get_next_positive_subdir(struct dentry *prev, struct dentry *root) { - struct autofs_sb_info *sbi =3D autofs_sbi(root->d_sb); struct dentry *q; =20 - spin_lock(&sbi->lookup_lock); q =3D positive_after(root, prev); - spin_unlock(&sbi->lookup_lock); dput(prev); return q; } @@ -106,13 +103,11 @@ static struct dentry *get_next_positive_subdir(struct= dentry *prev, static struct dentry *get_next_positive_dentry(struct dentry *prev, struct dentry *root) { - struct autofs_sb_info *sbi =3D autofs_sbi(root->d_sb); struct dentry *p =3D prev, *ret =3D NULL, *d =3D NULL; =20 if (prev =3D=3D NULL) return dget(root); =20 - spin_lock(&sbi->lookup_lock); while (1) { struct dentry *parent; =20 @@ -123,7 +118,6 @@ static struct dentry *get_next_positive_dentry(struct d= entry *prev, d =3D p; p =3D parent; } - spin_unlock(&sbi->lookup_lock); dput(prev); return ret; } --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BBF42AD3C; Sat, 15 Aug 2026 04:30:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768217; cv=none; b=Al7X+SbtKR55GkZjqo52vTaa6iGxGr7ZEwYKPK5VOmJhvdOrhhJZKx0Sm6ysy6IIZdkP0odFqOyeFVfZh16LfvLHekQDzqyH4aRaVmedBR442ZiJ27iOSF6/hlz4k2sNhozNgu+aUlh68LM5FdofH9e48ny8TddxSl8saxTFHUk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768217; c=relaxed/simple; bh=BZm2UVq6OsgoyMQbfbdWEEOk5+ioSZ2zDrWjXKOpIag=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H4vF/FhtJx9Nm4T0/WukFSyI2QIN6ne1CtWvbKUk+cYGGnn4tjkv+gSp8r5LUx8xTHAZaOxIfctYpYJXJSzLlevHXzBz4hG+1F8IZYep9Oq1jT9bvDFh4B1dRyx/zK/ijbhsPDTLPb4MTiHMgwKjfiOWzQSZj+9qr5bBS9zO/sY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=HwpTey3c; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=lhQlPsyC; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="HwpTey3c"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="lhQlPsyC" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id A399F13803F8; Sat, 15 Aug 2026 00:30:14 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:30:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768214; x=1786775414; bh=dcvwJxBfWYNhpbwtNVR/xleLg/uCSP2USMPR16IVJD4=; b= HwpTey3cfWsnzSUaQYLjFot54WeZZkGBf4g6qPMgzL1cL+XcfqnrvTKO0MzsIgqq H4+XBS0TynT1O/0O22atmeD4MFlN1dCXdcrKDIxc/uZckdQfkAdY8TmSu8yathH1 1kGVi7jMkftlN8AARyipfIAwJYCUt+q8DqcIfnaZBMvqwdXIuu3EeaBFVjFq99Ed LFC+/M1k+kVJvlSfBTGhQQ9Vz2IVwabpui/a5ktt0MXfmA6J1K2PfMIy3sjZ6ePp blcC3QPAU5zJcRuUnDL0ux3NOQvF0nzDLAURqybKncAuHoLq+y8G4lyR/hY0Kf6C yRVShG+nv2Q7YzQuptCGdA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768214; x=1786775414; bh=d cvwJxBfWYNhpbwtNVR/xleLg/uCSP2USMPR16IVJD4=; b=lhQlPsyC9dWigWiD4 A2rwqNxwRzqmknJfkYmpTWZsNluc98Z08qMEzzXTuPfFHjTDESeuzq7yw4M+95R7 d3F7dP2+VFHjZ0eaJIJzn/ef6/BDj2Ey/1bdS+u5+oLoMAYqnBZjSYzw1O+KT94t vSDnP1SkaPe2pE0fk6f7b2yjAOR74dCdkms3+NdKpOOFHHXntT8wGXCmEu6yTCP/ 5oRcuLVdXjIZksWB2IPpUeSQSY8CWaMZvps1HSA1b5jhjodUMG1PhcKGMlhOQZ9n CxB+snUeQR41ZmNkr5Hz4zsKwJss7pLBLEsxdtAi2Sx9lpioCxAdvWeMAokj5lBA JSpig== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTECw6EEPYbx+7BaaLSeXge8TL0IFS/e22W0DFWlbDFG9eII2nLkfnvZprtL9LDp1m HNcIj6bmqu83Qm/YUapqU6PBN6WcNm8P6Gy6RDWT6cAAmyaKdoJVe4WWntEcEJw7UAQpab Ivov0q9n39VXDrfptfrf0jUwc+MgicKL4WCNr5zVI2XTGGzlh1W80uuvtEo9Ovpf8kur1R vP/VXSxnYRhNfcG7+F4fSgFn0Gt4iNMYjiANVHauJEWjElKvMPdOxk4oexwOk01N0r04qi 8M218+E0MCoqYMSR4rZhl0wfvSlTNBrLCF/rmquNqRbB0zK7AmmuLtO4fjAl8K2V5bn2en +Vy7m17pt7Lg9uRvJwL0PplYFyxnWOqvDkRy+Mk+QFd67N2vnwtd0NTrc4VHLSbYIZB06K h9v+4UE8+Nl1Rf7egJKELys+yOrvpPVYgOYdFBFtNUc7K+YX9UlD9+Ew/8lf/pZC/Eq8lm nT0bii1BCFt3jCXUfHemqFCNLKvo/1Ezv6uAI1azxjO8bBid2b37h5TZDesbpYn0ssrEdb zMBPQZqBTwMoibmHYTTxyd5jVSapNrkQg2T84eGNVVWJrk5pe0L1B9A8V4WZH9Jrtc5AW4 TFJPFs72YsTmQTtdOLxn4riyJV2lkLSmy3mxjq+VFwmqA9zWoNTIUnB2vDUQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:30:08 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 13/18] VFS: don't move dentries in d_sib list when they have the same parent Date: Sat, 15 Aug 2026 14:21:30 +1000 Message-ID: <20260815042707.2535717-14-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown When __d_move() moves or exchanges dentries it currently always moves both dentries to the head of the ->d_children list of the respective parents. When they have the same parent, this simply moves them from where they are to the start in the same list. So it achieves nothing useful. A future patch will allow d_for_each_positive_child() to drop and retake the parent's d_lock during the iteration. With the current __d_move behaviour this would allow a dentry to be moved to the front and so missed, even though it is still in the same directory. This might be unexpected. With this change the only dentries that d_for_each_positive_child() might miss are those moved out of the directory, or those moved in after the iteration started. These are unavoidable and should not be unexpected. Signed-off-by: NeilBrown Reviewed-by: Chuck Lever --- fs/dcache.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index ae726f3ff0cb..50fbbcceca01 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3052,6 +3052,9 @@ static void copy_name(struct dentry *dentry, struct d= entry *target) * entries should not be moved in this way. Caller must hold rename_lock, = the * i_rwsem of the source and target directories (exclusively), and the sb-> * s_vfs_rename_mutex if they differ. See lock_rename(). + * + * If @dentry and @target have the same parent, then neither is + * moved in the d_sib list. */ static void __d_move(struct dentry *dentry, struct dentry *target, bool exchange) @@ -3119,15 +3122,20 @@ static void __d_move(struct dentry *dentry, struct = dentry *target, } else { target->d_parent =3D old_parent; swap_names(dentry, target); - if (!hlist_unhashed(&target->d_sib)) - __hlist_del(&target->d_sib); - hlist_add_head(&target->d_sib, &target->d_parent->d_children); + if (target->d_parent !=3D dentry->d_parent) { + if (!hlist_unhashed(&target->d_sib)) + __hlist_del(&target->d_sib); + hlist_add_head(&target->d_sib, + &target->d_parent->d_children); + } __d_rehash(target); fsnotify_update_flags(target); } - if (!hlist_unhashed(&dentry->d_sib)) - __hlist_del(&dentry->d_sib); - hlist_add_head(&dentry->d_sib, &dentry->d_parent->d_children); + if (dentry->d_parent !=3D old_parent) { + if (!hlist_unhashed(&dentry->d_sib)) + __hlist_del(&dentry->d_sib); + hlist_add_head(&dentry->d_sib, &dentry->d_parent->d_children); + } =20 /* * Adjust parent refcounts if either d_children ended up empty. --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54C992AD3C; Sat, 15 Aug 2026 04:30:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768226; cv=none; b=Pn5/QejCvTfZLzaCi6O6SaDUypeipmJNhTyxFXyG+3HTLe8tnuC9eRPGc7MQDul21Gk2rJdVwa3ORh5fF8dBCQI92BOKbZbW5A6rIGHpT2jnW/mi4dBOxWNy5u6TaEVh4zUGYKhIL+K/V77j0EoCMeIVLt9o2mI8WFoNGIl+16Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768226; c=relaxed/simple; bh=WM32gv8y32TBXdzBdBZEPnqOA6Hn/lbJ/5x8jb4D33Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GYELmT3ovW13E5H82rxYLnPhYrpl6hpzgxNorwSG191F2CchINPovwAGjVDpeRj/DiGDjBN42nVJG4sx8+P0P+i6o8jssJ66cVYCyPruYUw9cgccfSucN3j2QT4BD3/iCQQAxIXHwPAKLhTMPa2Rsuo79jKZepcD8fGJAx5KN6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=SAte4HO+; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ZhLfHdoJ; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="SAte4HO+"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ZhLfHdoJ" Received: from phl-compute-08.internal (phl-compute-08.internal [10.202.2.48]) by mailflow.phl.internal (Postfix) with ESMTP id 6F96E13803F8; Sat, 15 Aug 2026 00:30:24 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-08.internal (MEProxy); Sat, 15 Aug 2026 00:30:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768224; x=1786775424; bh=UsX1H1FvrdcE03UajthEohSKFBjuFpKXnOBS2Iq2Qx8=; b= SAte4HO+ap8+GvmLs+BoqP34dNJR38N0emrWUcufy9bclUadCfytvCnK3JHDiVFU 6n/7Gv1AJH2hZoM04yL3jzlW4FtFvLrmj8xcdyxy8mZSPFhl1i44S0/ym9qiYRUK 1IVJPga3bSAovz/oLzPtJV6B9/vmr3UHUyd7kx+nHqtHNSchNW2LO8TRypncQYyP kUWdY4KPscSYrIeVMdp8HnvAe/gXf0ePJIh7PEX+4imcnZKtQR9u37vSoEI/GyoJ NN+jn1slBcyTcwXv3MIdEWELiqKQ5UlreqXRnFib3e6frulhhub5duw3EYFA9l1N 0eizl+OcABEBtlvhp+vlPw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768224; x=1786775424; bh=U sX1H1FvrdcE03UajthEohSKFBjuFpKXnOBS2Iq2Qx8=; b=ZhLfHdoJvwmU0CoyO C7auQVfeWpwkOLloajLvUKQ0nPh14HfK+SJxkpC4V53UIm/BoxtTnJ95ubbWCHOM Lgb+MNUrGASivMD9S/tw4p0Wy06Q5AllOKVBRPL6K5phsqG6bnWoOpUcfzDK7EiF Wld69BbVUJ5r+mbCqe0ecR5wb9IgZBJ/x6TqoWO3wiGXzas9eXY8KFwIgeKrhDB2 D/wguBXqgCZ9X9aGGxiL5SsNDGHgn94pYTemmJTO4Q3KE9yNDcC0eHRt9dizIXKc IjP4zBHcZ9vZKGBttuBbfS39r9DaOztWDkWnnN4HGCox6vjTU+IHWqJf3JlFIQcw 6YX3g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTF35pNQvdHifAS72EypUM+sj4MgVnoYznd+MkmT2mxm0S5KeaXRXN1BftM9su3AO2 L0DE1tpks9ipdnLwrMjtaxoW7Jm3CmxFNWqRz+iT2MzRHv1XvZNIWQAV/Tixn7l805cF3+ Q8b4gpZ5fobrYKJtdmv/+GQNQ9iuDB5NCQuckvHoxAEPiLjJJdcp2eJd2z7c0HfFptq2lb TJFjgDc6cWPJb4ntMivJOZ1sXgZqLUzD/YRGyB79ZazUQXiMjVzdOUJLoaebwTyoZBJmy6 kBdOAkJxOpHMtG6MuKXXU/Ve6NDZzrFEVaMt3ut4hZmQYS3N5+VbGkJdqLENAwza7VOuQe demolYo+8A0so4cOwtrWaAo7fXw1wNikGUTxUYNiXy4CWZfGtcPzoZ4o+nrlm/zUrkPA86 kwPNHd4RnNl4s4835oMvh1Yd7kCWEH7LtEHpjUnEUfqtt9rfJDp6V2CvxSQWf7iPprDFLV V9Px96Y9DE85R1/wmFWU1xjXLn7KHWVUFALObH4W7uYhkY5iHNQr/pnelV9MP+AFNYid13 zUYK0TqlagvmZK40ww/dN4vJ0HK0du0TIkxxp6fJjP+4kSk6GNYERDbqM69KB5B7ADYJZF xSVNIBI8ped5ihSLOPQUWLzc5pc06mo/9dZOgIIIBdqapImCjZ1utb0RufGA X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:30:18 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 14/18] Call cond_reshed() as needed in d_for_each_positive_child(). Date: Sat, 15 Aug 2026 14:21:31 +1000 Message-ID: <20260815042707.2535717-15-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown There are reports that large numbers of negative dentries can lead to soft lockups when walking the d_children/d_sib list, particularly in fsnotify_set_children_dentry_flags(). (See link below) This can be addressed by allowing a schedule during the walk in the same way that scan_positives() (in libfs.c) already does. As we now walk the list in common code, we can add that schedule call to all places that walk the list using d_for_each_positive_child iterators. Doing this involves using an on-stack dentry (about 330 bytes) which is not standard practice but should be safe since Commit 3df5153c5f12 ("make cursors NORCU") made cursors NORCU, confirming that they can safely be released without waiting. Also importantly nothing ever takes a reference on a cursor that it doesn't own. To facilitate this, a new __d_init() is split out of __d_alloc() and used in d_init_cursor() which can be called on an on-stack dentry as is done in the new d_next_sibling_sched(). d_for_each_positive_child*() now use d_next_sibling_sched() if appropriate and they now assert they might_sleep(). Note that d_walk() also walks this list and does not use the new helper. Some instances of d_walk() do abort when a resched is needed, others do not. This patch does not help with those. Link https://lwn.net/Articles/1079407/ Signed-off-by: NeilBrown --- fs/dcache.c | 107 ++++++++++++++++++++++++++++++++++------- include/linux/dcache.h | 23 ++++++--- 2 files changed, 106 insertions(+), 24 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 50fbbcceca01..38a726472d4a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1885,6 +1885,24 @@ void d_invalidate(struct dentry *dentry) } EXPORT_SYMBOL(d_invalidate); =20 +static void __d_init(struct dentry *dentry, struct super_block *sb) +{ + dentry->d_flags =3D 0; + lockref_init(&dentry->d_lockref); + seqcount_spinlock_init(&dentry->d_seq, &dentry->d_lock); + dentry->d_inode =3D NULL; + dentry->d_parent =3D dentry; + dentry->d_sb =3D sb; + dentry->d_op =3D sb->__s_d_op; + dentry->d_flags =3D sb->s_d_flags; + dentry->d_fsdata =3D NULL; + INIT_HLIST_BL_NODE(&dentry->d_hash); + INIT_LIST_HEAD(&dentry->d_lru); + INIT_HLIST_HEAD(&dentry->d_children); + dentry->waiters =3D NULL; + INIT_HLIST_NODE(&dentry->d_sib); +} + /** * __d_alloc - allocate a dcache entry * @sb: filesystem it will belong to @@ -1894,7 +1912,6 @@ EXPORT_SYMBOL(d_invalidate); * available. On a success the dentry is returned. The name passed in is * copied and the copy passed in may be reused after this call. */ -=20 static struct dentry *__d_alloc(struct super_block *sb, const struct qstr = *name) { struct dentry *dentry; @@ -1922,14 +1939,14 @@ static struct dentry *__d_alloc(struct super_block = *sb, const struct qstr *name) p =3D kmalloc_flex(*p, name, name->len + 1, GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); if (!p) { - kmem_cache_free(dentry_cache, dentry);=20 + kmem_cache_free(dentry_cache, dentry); return NULL; } atomic_set(&p->count, 1); dname =3D p->name; } else { dname =3D dentry->d_shortname.string; - }=09 + } =20 dentry->__d_name.len =3D name->len; dentry->__d_name.hash =3D name->hash; @@ -1939,20 +1956,7 @@ static struct dentry *__d_alloc(struct super_block *= sb, const struct qstr *name) /* Make sure we always see the terminating NUL character */ smp_store_release(&dentry->__d_name.name, dname); /* ^^^ */ =20 - dentry->d_flags =3D 0; - lockref_init(&dentry->d_lockref); - seqcount_spinlock_init(&dentry->d_seq, &dentry->d_lock); - dentry->d_inode =3D NULL; - dentry->d_parent =3D dentry; - dentry->d_sb =3D sb; - dentry->d_op =3D sb->__s_d_op; - dentry->d_flags =3D sb->s_d_flags; - dentry->d_fsdata =3D NULL; - INIT_HLIST_BL_NODE(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_HLIST_HEAD(&dentry->d_children); - dentry->waiters =3D NULL; - INIT_HLIST_NODE(&dentry->d_sib); + __d_init(dentry, sb); =20 if (dentry->d_op && dentry->d_op->d_init) { err =3D dentry->d_op->d_init(dentry); @@ -1969,6 +1973,75 @@ static struct dentry *__d_alloc(struct super_block *= sb, const struct qstr *name) return dentry; } =20 +/** + * d_init_cursor - initialise an on-stack dentry cursor + * @dentry: the dentry to be initialised + * @parent: dentry of parent where cursor will be used. + * + * A DCACHE_DENTRY_CURSOR is initalised for use in marking + * a place in the d_children/d_sib list. While sb-related + * fields are filled in, they should never be used. + * The filesystems d_init is not called and a final d_put() + * should not be called, else d_release would be called. + */ +static void d_init_cursor(struct dentry *dentry, struct dentry *parent) +{ + const struct qstr *name =3D &slash_name; + char *dname; + + /* + * We guarantee that the inline name is always NUL-terminated. + * This way the memcpy() done by the name switching in rename + * will still always have a NUL at the end, even if we might + * be overwriting an internal NUL character + */ + dentry->d_shortname.string[DNAME_INLINE_LEN-1] =3D 0; + name =3D &slash_name; + dname =3D dentry->d_shortname.string; + + dentry->__d_name.len =3D name->len; + dentry->__d_name.hash =3D name->hash; + memcpy(dname, name->name, name->len); + dname[name->len] =3D 0; + + /* Make sure we always see the terminating NUL character */ + smp_store_release(&dentry->__d_name.name, dname); /* ^^^ */ + + __d_init(dentry, parent->d_sb); + dentry->d_parent =3D parent; + dentry->d_flags |=3D DCACHE_DENTRY_CURSOR | DCACHE_NORCU; +} + +/** + * d_next_sibling_sched - return next sibling, but schedule() first + * @child: current child + * + * This behaves like d_next_sibling(), but drops the parent d_lock + * and calls cond_resched() to avoid any soft-lockup. A cursor + * is inserted as place holder. + * + * Caller must hold the parents d_lock, and must hold a counted + * reference on the parent. + * + * Returns: the next sibling, or NULL if there is none. + */ +struct dentry *d_next_sibling_sched(struct dentry *child) +__must_hold(&child->d_parent->d_lock) +{ + struct dentry cursor; + + d_init_cursor(&cursor, child->d_parent); + hlist_add_behind(&cursor.d_sib, &child->d_sib); + spin_unlock(&cursor.d_parent->d_lock); + cond_resched(); + spin_lock(&cursor.d_parent->d_lock); + child =3D d_next_sibling(&cursor); + d_detach_cursor(&cursor); + WARN_ON(d_count(&cursor) !=3D 1); + return child; +} +EXPORT_SYMBOL(d_next_sibling_sched); + /** * d_alloc - allocate a dcache entry * @parent: parent of entry to allocate diff --git a/include/linux/dcache.h b/include/linux/dcache.h index cabf05e74b1f..f7d5954c58da 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -656,10 +656,15 @@ static inline struct dentry *d_next_sibling(const str= uct dentry *dentry) return hlist_entry_safe(dentry->d_sib.next, struct dentry, d_sib); } =20 +struct dentry *d_next_sibling_sched(struct dentry *child); + static inline struct dentry *d_next_positive(struct dentry *child) { do { - child =3D d_next_sibling(child); + if (need_resched()) + child =3D d_next_sibling_sched(child); + else + child =3D d_next_sibling(child); } while (child && !d_really_is_positive(child)); return child; } @@ -691,9 +696,11 @@ static inline struct dentry *d_first_positive(const st= ruct dentry *parent, * which have at some point in the past been positive. */ #define d_for_each_positive_child(child, parent) \ - scoped_guard(spinlock, &parent->d_lock) \ - for (child =3D d_first_positive(parent, NULL); child; \ - child =3D d_next_positive(child)) + if (({might_sleep();0;})) ; else \ + scoped_guard(spinlock, &parent->d_lock) \ + for (child =3D d_first_positive(parent, NULL); \ + child; \ + child =3D d_next_positive(child)) =20 /** * d_for_each_positive_child_continue - iterate over remaining positive ch= ildren @@ -710,9 +717,11 @@ static inline struct dentry *d_first_positive(const st= ruct dentry *parent, * */ #define d_for_each_positive_child_continue(child, parent) \ - scoped_guard(spinlock, &parent->d_lock) \ - for (child =3D d_first_positive(parent, child); child; \ - child =3D d_next_positive(child)) + if (({might_sleep();0;})) ; else \ + scoped_guard(spinlock, &parent->d_lock) \ + for (child =3D d_first_positive(parent, child); \ + child; \ + child =3D d_next_positive(child)) =20 void set_default_d_op(struct super_block *, const struct dentry_operations= *); struct dentry *d_make_persistent(struct dentry *, struct inode *); --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4EEF92AD3C; Sat, 15 Aug 2026 04:30:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768236; cv=none; b=UaIfmczew7ZW8lAq6qDWOCteCGunQ7WX9sS4Hr5yw0WcIYwxJwuDTPlx3HrGenwAugFKYFq05ySAFYu2KHgpqHf7Bo9HjBlaV240Trk/4HWrF2i1Buw6Kenf35q0TFO7PrNSSlMJxg4iM6OuestVfEl/QXQkU5EB+SfDuVHXn2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768236; c=relaxed/simple; bh=9qZMcypa/gy5kjHN/LBtAlnlzenkV/IzDp6Z1yGYhXw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TegsaRNTroUCzRi1PLn+WPb7ImLTDG1dZ66VwBjt/HZeuN4mLmQmQ2fSq45ws/j/rh9hP66zRhsnZbLbaeaNruNDo7QeISbM4XFVOn/InaBJOWClgRCn+X2fZMDRnsJJhUm/7j/wrC+og7VX5fGjjptXL9+8y2PLZXzUwsxPNHI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=VYK9PzO5; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=KKUsjTju; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="VYK9PzO5"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="KKUsjTju" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id 5966513803F8; Sat, 15 Aug 2026 00:30:34 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:30:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768234; x=1786775434; bh=8omHB5Ik+xex9gC8avsA7r2d4Low0LcWs+AokawDNtY=; b= VYK9PzO5OraQOAQipKRJMel6XhD4dTWDtuRPRWCEHmm5jxki0dbR0ahhJHwACx8E XWoAB2ZWsB3ekKYaxXoXfYBvGFhwNoRTaxQrBEyNea1/unVpSntNazQhKeep4PHh P7Vyz7df6jt0tHh3M5JXdDcVNTttTIOQ3bo9j+3oXyIv65bAanax/VqDPFXV3XOU 5afmKYxRA/F4b7WE8OP0uRZTFfaem+Jv4KD1hhu8/77UYxDkDZVeqffWc1ZLzHIh nHWtocLKnvquMwvkfrt2hUQhj0Lpho4Uu33pwOQNM8a58eR0GeB3gA85JhmFSVcf jKuVP31Y1Xbp16OOqjPUWQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768234; x=1786775434; bh=8 omHB5Ik+xex9gC8avsA7r2d4Low0LcWs+AokawDNtY=; b=KKUsjTjuzdDyamND/ HVM7KSAQPI5fKD2nFN+em5tkjfOc1omraZ3cbkVD9ZO6t1MAHSzayli4/FW0W61c gZc/KQJxNfmfLk5FA5E7ekJb8/JglfFz95ndQpllgerSTHXpIR99Z+G1mfE7huFO iJONThNOV95DxflXKkEwu7nW+Zt9O7sYamHKKySFNNrNTT42XC+iDIIzn6LV1afC SQFdPmZY3cOqcvuZQyFH6dFcTipflnmwxk/vnFG3o5C4YYX4ec5ZRvJI8IXdq388 5R2rZgUHKKFVKnxKOUwqonV/xlc/J/Xktf5oW+VQ7yJQrQGwjvt1zzG9NQ+TXuVZ 3h3aw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTGgH1yB2n7ycrnT317G63mA4K8J+0+N/EMola1f3Yo9FMDyeCxNlCpW0ogG8SDzVK nuqmbd9pMlKrj8W+iYmq1pVTGvt74D3ZCctc/uPGmP05B5l1l0R4ZDIBCIl/8oEandYMD/ 4fMlB5yv+92TDAVOY+2CBU7LrzZy25zRdg8qTNOxVbsq7k24tgXs/5TnSd4dLDpY87DDx3 U3W1uESsjbyhpYP7efCKAtwoUDG8Gecy6pK22NJSQWi5TompJWiG+uhiQDvSBSwloZ0ml1 Gf9seSd/eZq/h5vGIIRNPD6wpSL2TVBhjzDzH8E39xrhx5Ml7hez0SHzhnJuI33Pe/qwXz 9BPKLtVy7zPFrINbO2rPyoNOKAe1gngEwrv45dtD8oe0YHOcWl3Cd21Itg+ZWYhXu1zXFP izSWd7w8lawjwmzwsA51nmDv3SJslCrsKIz3474E3xmZXyeh4LBRduzNlZdbzY7SnLf/s8 +ZdfnyLqRBz+PQKl8cgHMGFZijpGwFGsbktQZlFjWI9vzye6AHJeG52qzurVLBF9DwsD9z Nr27UwJDn07hUhntleOUqHpmeoJKLVpZzdu5Nx+7ppXptLRBfkQJc5499lBWSnIKdc0FF/ 1ZhelzCBZBqz+Y53gMvcYnW1OYfw1HicPeMCgUfN+yTi4x6nYIrtOUzbr4fQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:30:28 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 15/18] libfs: remove cond_resched() from scan_positives() Date: Sat, 15 Aug 2026 14:21:32 +1000 Message-ID: <20260815042707.2535717-16-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Now that d_for_each_positive_child_continue() calls cond_resced() as needed, scan_positives() doesn't need to any more. Signed-off-by: NeilBrown --- fs/libfs.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 44e8dec51237..15dd470198dd 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -108,7 +108,6 @@ EXPORT_SYMBOL(dcache_dir_close); * the last element of the list and %NULL is returned. */ static struct dentry *scan_positives(struct dentry *dentry, - struct dentry *cursor, struct dentry *last, loff_t count) { @@ -125,13 +124,6 @@ static struct dentry *scan_positives(struct dentry *de= ntry, break; count =3D 1; } - if (cursor && need_resched()) { - hlist_move_behind(&cursor->d_sib, &d->d_sib); - d =3D cursor; - spin_unlock(&dentry->d_lock); - cond_resched(); - spin_lock(&dentry->d_lock); - } } dput(last); return found; @@ -158,7 +150,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offse= t, int whence) inode_lock_shared(dentry->d_inode); =20 if (offset > 2) - to =3D scan_positives(dentry, cursor, NULL, offset - 2); + to =3D scan_positives(dentry, NULL, offset - 2); spin_lock(&dentry->d_lock); if (to) hlist_move_behind(&cursor->d_sib, &to->d_sib); @@ -193,7 +185,7 @@ int dcache_readdir(struct file *file, struct dir_contex= t *ctx) if (ctx->pos > 2) next =3D dget(cursor); =20 - while ((next =3D scan_positives(dentry, cursor, next, 1)) !=3D NULL) { + while ((next =3D scan_positives(dentry, next, 1)) !=3D NULL) { if (!dir_emit(ctx, next->d_name.name, next->d_name.len, d_inode(next)->i_ino, fs_umode_to_dtype(d_inode(next)->i_mode))) @@ -448,7 +440,7 @@ offset_dir_lookup(struct dentry *parent, loff_t offset) MA_STATE(mas, &octx->mt, offset, offset); =20 if (offset =3D=3D DIR_OFFSET_FIRST) - found =3D scan_positives(parent, NULL, NULL, 1); + found =3D scan_positives(parent, NULL, 1); else { rcu_read_lock(); spin_lock(&parent->d_lock); @@ -470,7 +462,7 @@ offset_dir_lookup(struct dentry *parent, loff_t offset) spin_unlock(&parent->d_lock); rcu_read_unlock(); if (found && !simple_positive(found)) - found =3D scan_positives(parent, NULL, found, 1); + found =3D scan_positives(parent, found, 1); } return found; } @@ -496,7 +488,7 @@ static void offset_iterate_dir(struct file *file, struc= t dir_context *ctx) if (!offset_dir_emit(ctx, dentry)) break; =20 - dentry =3D scan_positives(dir, NULL, dentry, 1); + dentry =3D scan_positives(dir, dentry, 1); =20 if (!dentry) goto out_eod; --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80A8131986C; Sat, 15 Aug 2026 04:30:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768245; cv=none; b=PXENN8ev7YWVIKexlu/CuSj0doHzj3GkjEdhBGXKqKxzoj+oNCfZICifIVLWZluxEDljKrS7pLDEkTHLzP39ChWMOBHig1jTTzYFj8cLQSqTk67P9BwQCkR5gzdrZC2h8KwxYfNcmX1KslvhneARHUXz8aDNCzJVo4fgzlt4xFE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768245; c=relaxed/simple; bh=nGuTFIwa64Q5IMqunT4+fPd2YQmG03yGK+KuZmFRVLU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ocl2I9upiYrvCy0a1lijtvvildXk7d3rw9QawPClmsnAh2DAFDXC6VZAJwZbtAuA7A0PRe+/n+3RzRAoTYetZt4am9EkSnkeO1YwtdwZC5/Y64psNQAxDyFSGM7h4kGOOVEh3h5OkcFYgsLQq+HcJ0gv82WsZ+cj3r1z8jgPIfc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=CkYQsbIZ; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=KxyRihOy; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="CkYQsbIZ"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="KxyRihOy" Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailflow.phl.internal (Postfix) with ESMTP id 8EA91138041A; Sat, 15 Aug 2026 00:30:42 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Sat, 15 Aug 2026 00:30:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768242; x=1786775442; bh=4uxv7U2UBafJPVlMxOjjLgs98T4HdcbtcWkA9Y7XY28=; b= CkYQsbIZLEM4ihp84qZvq5Hy0eWydToXVogocCx5IkZjzbPGORNuIy7xFKyjjzTA iuaqlXkvrbvh4faeQx0+eSYtn0iFNN6KoQjgYgHLl5th61iyhnjKzTjjRUjjX/DG 7fCZY5nVD3tLHmnBhT93CJIANhbLWRf7fBVGsPRDNTh5NJvp8QLWxUG9mX/YGT2Q CwLnh+EHkT5Y0QRZ+lXOKOeEUkqdgpboZo7IqM1SG/nu5+ROgZbt5PfVQ/sCtwG/ I07eoQoTakzS15tbEKVtSATC5BlVlLBWwH2bRXMOeNWwdZn/b+5h2rWHZZad7er7 79YZ0nOwoKpC7Pn/T9HojA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768242; x=1786775442; bh=4 uxv7U2UBafJPVlMxOjjLgs98T4HdcbtcWkA9Y7XY28=; b=KxyRihOyHXsthM7Gi cJ8RGVQuH6hSTbKcaudbjADWIfh4oNaVvChnPw3hQ26oW5Jhh0jQshAramBtBXy0 8a1AADlt6A59i9z1ijpQytOMAXgLnzoQRVQHHLuRzxeHwQzo3lUOJlCFhGh3eAnu klVClS4iXTIkfFJ8/j/BeHPdw+XCwVtHBwN5zbR7YSN9163X5NDRL/tbOttxClE4 6EKmXglywqvm8OFowcZQqTU29J10BTFA9leouDO1QRnlDA2BaP2seuNUmXvfIvk3 XrScDL52eNfSkR7eiZ8ipuPmsrZVu/Xh0hkjeglEohy2rtOp0ZR2jCZQgnYEw25f MAgWA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEYOd3tLu5dATIbifwhlYvY0qyYOt7s1LgDprEXebOtP02E/NfWDhmB6dUHRD18Mw M/OVd5zhrG+UTD+zvSQphReiWNJaCd0AqwUD63tHfAJF2OAEGvFg1iC8SkfXHW4Cbq3Pnv XZPdOI+4XvyfDrMe9ntOWfnHEDm7Vl4MwVM6/98uzVFr9W5lPBzuk8llcQfOSsZLGGgf8M 1akEE1al0EFoJJ4d9fnySO8LzXZFHrFib9IETFD1LEL7DAdqppQ7UcHFMAN4HHBzYumdeq UmiiM2nwa1tgBmTDGFT6cgwcylPb6+Qw0oEVRuLdEgoMQRjiQsSj7nR2Cv5Z5tDGgputXM X6RF2cOJZTeJ07dPQW6G7k4SIBGBZnJbxFi3yyqLFAnvZuNtNmI1x6fRn1qYGzLLxk/GLU G7To3eDabc57GBDejhJhEq/fJUCqLBGXmgaUpf1usszqSTBMbFXJRfXnm2R1V7EOVqYDG6 9LMIsA1pG6F8OH0Qp1nL0Vc+OuWfjYqIfiJtoLdCQ1cAa04teE0vUdWAo84gWpjVmHXP11 0jI8Z9B3Kr64Wy+iC5JAMxETHAoNB9n/PODF7N0kbOLXXklasqR7ZDh+ul6g4VbUT/Zgml 3OCMP5Akd5Y0h2aPvGdXGCpPW2edPqfDsFLaM4LrQwfcc1zFxchp2t5yl69Q X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:30:36 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 16/18] libfs: rename and export scan_positives() Date: Sat, 15 Aug 2026 14:21:33 +1000 Message-ID: <20260815042707.2535717-17-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown autofs has code nearly identical to scan_positives(). To avoid code duplication, export scan_positives(). Rename it to "d_scan_positives()" to make it more obviously dcache related. Change the "count" argument to "skip" which starts from 0 rather than 1. This makes it a little easier to document the purpose, and makes it less likely that "0" will be passed when "1" was intended. For aesthetic consistency, all calls of d_scan_positives() now pass as the "prev" arg the variable that the result is being assigned to. This was already the case except when NULL was passed, but in the two cases where NULL was passed, the target variable already had been initialised to NULL. Signed-off-by: NeilBrown --- fs/libfs.c | 49 ++++++++++++++++++++++++++---------------- include/linux/dcache.h | 4 ++++ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 15dd470198dd..20cc94b41075 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -97,37 +97,48 @@ int dcache_dir_close(struct inode *inode, struct file *= file) } EXPORT_SYMBOL(dcache_dir_close); =20 -/* parent is locked at least shared */ -/* - * Returns an element of siblings' list. - * We are looking for th positive after

; if - * found, dentry is grabbed and returned to caller. - * If no such element exists, NULL is returned. - * If last has been removed from the d_children list - * (i.e. last->d_sib is unhashed) then it is treated like +/** + * d_scan_positives - return next positive dentry after skipping some. + * @dentry: the parent dentry to scan + * @last: the place to start search, or %NULL to begin at start. + * @skip: number of positive dentries to skip over + * + * Returns the next, or first, positive element of siblings list after + * skipping over @skip positive elements. + * The child dentry is grabbed and returned to caller. + * If no such element exists, %NULL is returned. + * + * Caller must ensure returned dentry cannot be moved from + * the parent, possibly by holding i_rwsem. + * + * If @last has been removed from the d_children list + * (i.e. @last->d_sib is unhashed) then it is treated like * the last element of the list and %NULL is returned. + * + * Returns: a counted ref to a dentry, or %NULL */ -static struct dentry *scan_positives(struct dentry *dentry, - struct dentry *last, - loff_t count) +struct dentry *d_scan_positives(struct dentry *dentry, + struct dentry *last, + loff_t skip) { struct dentry *found =3D NULL; struct dentry *d =3D last; =20 d_for_each_positive_child_continue(d, dentry) { - if (simple_positive(d) && !--count) { + if (simple_positive(d) && !skip--) { spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); if (simple_positive(d)) found =3D dget_dlock(d); spin_unlock(&d->d_lock); if (likely(found)) break; - count =3D 1; + skip =3D 0; } } dput(last); return found; } +EXPORT_SYMBOL(d_scan_positives); =20 loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence) { @@ -149,8 +160,8 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offse= t, int whence) =20 inode_lock_shared(dentry->d_inode); =20 - if (offset > 2) - to =3D scan_positives(dentry, NULL, offset - 2); + if (offset >=3D 3) + to =3D d_scan_positives(dentry, to, offset - 3); spin_lock(&dentry->d_lock); if (to) hlist_move_behind(&cursor->d_sib, &to->d_sib); @@ -185,7 +196,7 @@ int dcache_readdir(struct file *file, struct dir_contex= t *ctx) if (ctx->pos > 2) next =3D dget(cursor); =20 - while ((next =3D scan_positives(dentry, next, 1)) !=3D NULL) { + while ((next =3D d_scan_positives(dentry, next, 0)) !=3D NULL) { if (!dir_emit(ctx, next->d_name.name, next->d_name.len, d_inode(next)->i_ino, fs_umode_to_dtype(d_inode(next)->i_mode))) @@ -440,7 +451,7 @@ offset_dir_lookup(struct dentry *parent, loff_t offset) MA_STATE(mas, &octx->mt, offset, offset); =20 if (offset =3D=3D DIR_OFFSET_FIRST) - found =3D scan_positives(parent, NULL, 1); + found =3D d_scan_positives(parent, found, 0); else { rcu_read_lock(); spin_lock(&parent->d_lock); @@ -462,7 +473,7 @@ offset_dir_lookup(struct dentry *parent, loff_t offset) spin_unlock(&parent->d_lock); rcu_read_unlock(); if (found && !simple_positive(found)) - found =3D scan_positives(parent, found, 1); + found =3D d_scan_positives(parent, found, 0); } return found; } @@ -488,7 +499,7 @@ static void offset_iterate_dir(struct file *file, struc= t dir_context *ctx) if (!offset_dir_emit(ctx, dentry)) break; =20 - dentry =3D scan_positives(dir, dentry, 1); + dentry =3D d_scan_positives(dir, dentry, 0); =20 if (!dentry) goto out_eod; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index f7d5954c58da..a978d1c4936a 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -723,6 +723,10 @@ static inline struct dentry *d_first_positive(const st= ruct dentry *parent, child; \ child =3D d_next_positive(child)) =20 +struct dentry *d_scan_positives(struct dentry *dentry, + struct dentry *last, + loff_t skip); + void set_default_d_op(struct super_block *, const struct dentry_operations= *); struct dentry *d_make_persistent(struct dentry *, struct inode *); void d_make_discardable(struct dentry *dentry); --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E5D22D8370; Sat, 15 Aug 2026 04:30:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768252; cv=none; b=qKtqxffkmyQJTK8ObCBjwGvMQjybk61FqczClJhU3d2tEWjERqZh+qty6gNu/7L3wKFo5dli1L4Z5C2Lxlv9smXuyGo4Kb4yuCNllA/BW9qws6PF2dVoOh5E6Ppq+DuGrOMsUVSfcbaD9ct2d+iKqQOLjhTuKIlosH+cX6lhMGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768252; c=relaxed/simple; bh=LrXLV+ct54yqBJAEGpeQUYESrGN5MdddCq4i8D03BAw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qKyD/KFron+AuJthvIT5mxA5aJSXqRS0RAvRyktJFq13XXWJX+YppdSaAev8XIudaMlral8IwxYdPdTrqdvEHAxXPPEpwxPnTkCNtL4rGXBt0eJInVQFjTvqiEQxX6KblhWE8OpKD/YvV/EZyX4XNCnFTTnZJQDh2lZqpx8yves= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=aEn676SN; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Knrp7mdg; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="aEn676SN"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Knrp7mdg" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id A513E13803F8; Sat, 15 Aug 2026 00:30:50 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Sat, 15 Aug 2026 00:30:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768250; x=1786775450; bh=L3MU5Hjm82YORF0xoZAlkG+Ia5N4nmUoeHPLihiOD8A=; b= aEn676SNg3ahoeYqzxwQm/yuxcqBIes6yTY/eadCcLXEuzTtkcOEEzPaFLnVSe2k LzdjxdcVtoV2zP9cBGR99YPZoOb1vU8AZdBMdcmfdr7x9y22/Uj1VaPcAJqW1YCW MXrUUqac39AhEcOExIDA38t8X1x4vVPEjqLJNkZXCL/CNvYl8MUmf/N3+m2+1Wej UJbpx3oFdx/0QSBz1xi3VvpfQv09hSWUnFKVK2mAuIQSzVO6NDWoh1Xhg6BVqOVC 8clGxFAqfhqyndfe5RZUGnUsCYJrEJUy2YSDryiQRq+CYTZwtSzRakkwT1pf6q/+ mDWisxDN8E4GOKJO8PN4TA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768250; x=1786775450; bh=L 3MU5Hjm82YORF0xoZAlkG+Ia5N4nmUoeHPLihiOD8A=; b=Knrp7mdgWxBKE88q8 x+GO7i8F2SJecspOv2/4tHkM99oJyU2huE++ojR3q9Q4JrRl9KCgkpQqQhfoFpBw qvdVsa1RTNjz5pFNIgGet1e3lYSAOCCwW0YFLgIkTCulGb4TIsp2r+9Trm+TI/cz iZIv6NFo96wf62tznM9G+YhrVl3gSz4RoMHSU5LQe174MK0qow2k2r2nflv3MzJA FWwIZIMRqnTh2xoCUSt7WbGF6HcIS35m+kFBYyIYTJtm/aDFDlaOwIkkb0nkNr+W CUdqY9NV2DXpVgPiQ0lf6UDRbCdmusDmUmedgLvE+2+jvUL2R/iVqfcLHl4i3zXV pLeBg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEE28K/iWMQRt6u3YaTvt/8yo1rhBtjX32u/xlCLGy2hriMKHqsLzAPH/Ho3e6IX3 q1DIXebVci50gQFo+3aX5wAF20l8V522OFg1CRtpPCGlqslShuRFntdCk3QR+wPvHYiD+L +viIImRaY7E/Ckk6k5bGwK8brThKGdHRKCPRDQhUdopVgFc8KEjNeqBCRrSrOZOGrnegqe pBL1TUTRZO/Mj+DVSNoik5H8Sh9TWxtQwvbKU3aBcaOiDVC6EssHahd328Uf1X8qX2KE8O 891t9K16OT/S2J0+RBHQpAbWOYblBnHwFjbVgw4TV8cYklVDQcB5cyuaXvTgCJkBQm29CF 0mCVE6kJP9+irHxn3Q3Hf94SISmmIyj2NtE/bFv3AmX3C5OmNjn3og+1jNcOeDD/qCyyiY WeeB7d2+z5i8v3WAf+EonOPwlu/zsbd6aV4sHZObZYdX1Fxp4LoxvE4B+mipSdOi6FqJn+ q7+gsWfu7E+ZKxG9zKnsTOSlY+w2WTjbFGyoqkjeO/u3dKv0iPcsZZn3SaxAkcrJIHXR7S OmH55mIelZrmZkrGF5+IbheTQwCzy/qR85wAalpSlVTLbXtwdl26J2uJlA0MVtr62c6YnQ oDkAVuTS9jEuERCiHb/f+99P9Oqls6fH/gKc7WKWHyxrCX2+vaICRDfYtKfw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:30:44 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 17/18] autofs: replace positive_after() with d_scan_positives() Date: Sat, 15 Aug 2026 14:21:34 +1000 Message-ID: <20260815042707.2535717-18-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Now that d_scan_positives() is exported, autofs can use it. An important difference from positive_after() is that d_scan_positives() drop the ref to the "prev" dentry. This means that get_next_positive_dentry() must take a reference to the new parent when stepping up, using dget_parent(), but otherwise allows that function to be significantly simplified. The while() loop looks a little unbalanced as there is a dget_parent without a dput. However when d_scan_positives() returns NULL, it will have done a dput without a dget, which provides the required balance. The dput(prev) at the end now doesn't (necessary) dput() the original "prev", but instead dput()s the parent of the returned dentry. Note that d_scan_positives() requires the caller to protect against renames. autofs doesn't need to take any action because it doesn't support rename at all. Signed-off-by: NeilBrown --- fs/autofs/expire.c | 51 +++++++++++----------------------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c index b6937c5936a5..277d9129754e 100644 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@ -70,53 +70,26 @@ static int autofs_mount_busy(struct vfsmount *mnt, return status; } =20 -static struct dentry *positive_after(struct dentry *p, struct dentry *chil= d) -{ - d_for_each_positive_child_continue(child, p) { - spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); - if (simple_positive(child)) { - dget_dlock(child); - spin_unlock(&child->d_lock); - return child; - } - spin_unlock(&child->d_lock); - } - return NULL; -} - /* - * Calculate and dget next entry in the subdirs list under root. - */ -static struct dentry *get_next_positive_subdir(struct dentry *prev, - struct dentry *root) -{ - struct dentry *q; - - q =3D positive_after(root, prev); - dput(prev); - return q; -} - -/* - * Calculate and dget next entry in top down tree traversal. + * Calculate and dget() next entry in top down tree traversal, + * and dput() the previous dentry. If there are no positive + * children, we stop up to the parent and look for next + * sibling. + * As autofs does not support rename, there is no risk + * for the parent changing before we step up. */ static struct dentry *get_next_positive_dentry(struct dentry *prev, struct dentry *root) { - struct dentry *p =3D prev, *ret =3D NULL, *d =3D NULL; + struct dentry *ret =3D NULL; =20 if (prev =3D=3D NULL) return dget(root); =20 - while (1) { - struct dentry *parent; - - ret =3D positive_after(p, d); - if (ret || p =3D=3D root) - break; - parent =3D p->d_parent; - d =3D p; - p =3D parent; + while ((ret =3D d_scan_positives(prev, ret, 0)) =3D=3D NULL && + prev !=3D root) { + ret =3D prev; + prev =3D dget_parent(prev); } dput(prev); return ret; @@ -414,7 +387,7 @@ static struct dentry *autofs_expire_indirect(struct sup= er_block *sb, return NULL; =20 dentry =3D NULL; - while ((dentry =3D get_next_positive_subdir(dentry, root))) { + while ((dentry =3D d_scan_positives(root, dentry, 0))) { spin_lock(&sbi->fs_lock); ino =3D autofs_dentry_ino(dentry); if (ino->flags & AUTOFS_INF_WANT_EXPIRE) { --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 23:56:09 2026 Received: from flow-a8-smtp.messagingengine.com (flow-a8-smtp.messagingengine.com [103.168.172.143]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 47EAE2E888C; Sat, 15 Aug 2026 04:30:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768260; cv=none; b=loEita5q4P2txNtLQurzvjiKjRoeuEX848blF3Bd2EX5COpxBOsE8DM6+uqndUYhajWt4A7nIIAgTy63ecvSCHYboqqXOk0QVfVXu5w4D+IlAY2hoZJRQr263z/H4r/24qASRRcre5O1ikG0XXT/ETZ7imT14Z5yKTXxMsbdVu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786768260; c=relaxed/simple; bh=YV9knnvzcy0sLsdJqwl6xSbTKsoY0oX+VX8+4U3n+kY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=f7QwNQSACRwvBVSvH8kllcDKRZSCXcaeasMTXMwJk1vMBFZkyyjZS5rpNBsbaoCvtZDG5VAoRpqEu5J4+Xs48EsSyYlsOXMqFr0zREHxBHx1mpKdbCuLQZ/LdM3LJaIKobe1TFLaHr082kUOIBb5LlZ7AH6Mt3gmHoVvUTqEjwg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net; spf=pass smtp.mailfrom=ownmail.net; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b=FHY+w+en; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Z+ExhmSx; arc=none smtp.client-ip=103.168.172.143 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ownmail.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ownmail.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ownmail.net header.i=@ownmail.net header.b="FHY+w+en"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Z+ExhmSx" Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailflow.phl.internal (Postfix) with ESMTP id 8E0A5138041A; Sat, 15 Aug 2026 00:30:58 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Sat, 15 Aug 2026 00:30:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm3; t=1786768258; x=1786775458; bh=0ZUxo0XVQx0MV+TeT0L+0fmPiUoaYbXc2QhN9arTG7Q=; b= FHY+w+enKFJX7PjH+lZze3Mfeh/ZaKJy/jW6hXeeOVM5l1fnQ6Nd1qEaTJwME8AY 7hQSSRCXdLSbESlcGtmfQieH7X27cMbHpsV9hgBDtRtcMCq+KtAU2gXG545hn++Z Fl/7CJQDJmk3qoKwc/uuEuMJz4e40UrDzOQ6n/Qn/SHqNbAMR+kT6ahgPl85aRA+ mOAojliI+UUNMDWkhhpxV/skJtBGj35JEZuGFVCfwamFovBiy6cXwSPjGmh3YuGI dMgfWcApfbFvJQLMfD6gexh2nTLzs3ak0INjcvsRjey8LMnZeFCODkDGHY6IZvkZ 8U0ZqhD3aq3s6xvC1YVLKg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786768258; x=1786775458; bh=0 ZUxo0XVQx0MV+TeT0L+0fmPiUoaYbXc2QhN9arTG7Q=; b=Z+ExhmSxiVIQSQoNW TxNPAzU261hSZivA+gXbGYsAF3O2grDiwGRekTHbYN57A72RISucqOv9EYpDtM0R eMPvpHQocYLuyACpV/in0DaOfqxaT777zC2ufOKdABqbq7uaTwvtECzCGHWLBpeR wylhxGevTZ03hMVpKwHkq5KUhycbpxbMO2OLm8j+j7FqKJoWhTE1JjR+LmsGkBfu zG9uHtQT3S3SyyhSRlek9jZIP+5fDbsvL3aPj6VE78cHWRRp4M3SILPz/i8PzLnU Qh5fi263rCxfFfjqlp6bjmxYaWrYKaUasSwqlD9ugnrmICsWUU8DYnn6M6/egURo aVaiw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEEgxiDAqI+NKGka33XJgpMBO/DGhYs8Flsqa2Km3b0PepQC7/8GfuyeA5jzmyQep aCi2aiis434mC/Tk7pwKgVxFObE3aixAuCoIjL6gdxAHLjW6IL1yYbTLlt/BEgF+UU2fSt hWlHFXw2KP7X4V9Aq3bD/0eXRW3pMpKxT8FIezDpG0wWpCM2a99aOq5iO64uy/c1sM2cBv H5X7K0w7/OYrN3gw0/vYCnPslouZWIDUiEgmIdpWMf56spVmUxFemTMS3TY/x0M7Lp5VqK b4Lcg+LhJCZnsVAUnm2IimP+mdAF1j5AUJI2N7qOkUPtZJq90cLj/zsW4WqsUz129GUmBo UiRMFGhu11BHa8HJuNwLX2zX9ZNXPScWQ2CNccGqZ7GkQeESbMn5ZOcUdLgyk6LR2ou72l q4fBZHkplUiccK8dZr6NdgidMUhFWLj+mloN53jWkLfZzii4Cgd6J+RWdOUae9VIzNL2RQ sGSfC+ENz8y5Z8ACDdAIrJQLZdTstam+gOgNASBuIjrBCPkZ/A3hNU747/fZj+IVV2lv7u RGX5KGce9V2IvzlioJRsX5jqFpsZrkJAuvBLg+UEo3UN4RBxJDixWZ/sgsFdZIPxqRqs7L IuuvTqXESa5Vl6CK2Rq7tVVCg7Og0KZfYZFW1/4kzoffZ2mGmofeFONsyWuw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 15 Aug 2026 00:30:52 -0400 (EDT) From: NeilBrown To: Ian Kent , Chuck Lever , Jake Edge , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Jan Harkes , coda@cs.cmu.edu, Alexander Viro , Christian Brauner , Jan Kara , Trond Myklebust , Anna Schumaker , Amir Goldstein , Andrew Morton , Miklos Szeredi Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, codalist@coda.cs.cmu.edu, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 18/18] autofs: change get_next_positive_dentry() to NOT accept NULL for start-up Date: Sat, 15 Aug 2026 14:21:35 +1000 Message-ID: <20260815042707.2535717-19-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260815042707.2535717-1-neilb@ownmail.net> References: <20260815042707.2535717-1-neilb@ownmail.net> Reply-To: NeilBrown Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: NeilBrown Rather than passing NULL to get_next_positive_dentry() to first time round, change callers to use a for loop which does the dget() explicitly to start the loop. I think this makes the code clearer. Looking at get_next_positive_dentry() it isn't immediately obvious what that code is doing there. Signed-off-by: NeilBrown --- fs/autofs/expire.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c index 277d9129754e..2a1844ba48c6 100644 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@ -83,9 +83,6 @@ static struct dentry *get_next_positive_dentry(struct den= try *prev, { struct dentry *ret =3D NULL; =20 - if (prev =3D=3D NULL) - return dget(root); - while ((ret =3D d_scan_positives(prev, ret, 0)) =3D=3D NULL && prev !=3D root) { ret =3D prev; @@ -148,7 +145,7 @@ static int autofs_tree_busy(struct vfsmount *mnt, return 1; =20 p =3D NULL; - while ((p =3D get_next_positive_dentry(p, top))) { + for (p =3D dget(top); p; p =3D get_next_positive_dentry(p, top)) { pr_debug("dentry %p %pd\n", p, p); =20 /* @@ -201,8 +198,7 @@ static struct dentry *autofs_check_leaves(struct vfsmou= nt *mnt, =20 pr_debug("parent %p %pd\n", parent, parent); =20 - p =3D NULL; - while ((p =3D get_next_positive_dentry(p, parent))) { + for (p =3D dget(parent); p; p =3D get_next_positive_dentry(p, parent)) { pr_debug("dentry %p %pd\n", p, p); =20 if (d_mountpoint(p)) { --=20 2.50.0.107.gf914562f5916.dirty