From nobody Mon Sep 28 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 26E381531C8; Tue, 25 Aug 2026 22:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696153; cv=none; b=R6NyGFwPvsqRGJ1Xu0N5fwVFHwb4ikmdNEgMp9YKxdf1k2tD0TTC/nVS8awv8P4dCMCfuEJAZJLUZaL9ba6VC2ON+TtsDjNFEC3qM6TJw/udpQ5Obgk2tD0HpQWrSigGGx0viv3Xb8jRojCmCoARAqoL0dMQJZlA6nvO6QXMgMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696153; c=relaxed/simple; bh=UCAAok+BZYu6YTH3Wj/Brqpfukp54ANy80JXJV2mDhI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DDeWqplLrhKDvI6fXPCY34qk4OLH2IjT1KpZvv4zhkYEEdqksYAwJvIyh1QXIAsRQKGX01o/PbqfB5K4T2xU68nQKxUQZZNPYXaDm0rbGDxne5j2KVhC8/hyBPmZskpfTXMqrKz0a8U6tOXi/bMFVT3qJldA2iP/hbenOI1brc4= 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=k0bGwqEp; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=eD8wFb41; arc=none smtp.client-ip=202.12.124.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="k0bGwqEp"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="eD8wFb41" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.stl.internal (Postfix) with ESMTP id E5289130017A; Tue, 25 Aug 2026 18:15:50 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Tue, 25 Aug 2026 18:15:51 -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=1787696150; x=1787703350; bh=QuYNRtqRuLgD/wM/mc74+AFvPzaBrC7/+rJ+XyEW874=; b= k0bGwqEpMDqSR+rBvaXuUqnr29LP/l8X/TkvNqeFG/KL3Vulwnz3IY67alvtPtLf XaqWNV/34pXY/hpoZmKVIsyPgl/1H3kh1fRSvznEV/3G8kkeN0PRAXOpOkyUN4by K5bBbF25+F/cwjARaNlb8zDe4HhGKU0m0gWUwVTU82CK3v3aRUAbi7xXMTTIcnGm 6WBfgLARSX0fm8qPbdnzHVb9OdWt32AQywrcfA1Pr0bb1XtXdgpoXD6R9EpS/xXV v2w+HbAdlishlfa+hBhVtAjipF2BzswnyB5Vg8XmnApsCbqt+3iGGiwHfCAAJzqy F2/9piT6Mzje8P5pztYRSg== 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=1787696150; x=1787703350; bh=Q uYNRtqRuLgD/wM/mc74+AFvPzaBrC7/+rJ+XyEW874=; b=eD8wFb41DN38Y+0vM BFW2D07E9U4O2TMf121UZ4yj59BYT4Mjk/KtP6IA/JBTuXphLMrl6swgnH6Gotf8 xtoMqg9VS6ZZh4HIGa+SIFbcsivZIvMDQmrpH7yZ+8OLoKWazmTmEOKRMnbx/v9a 4lUY5gFlll725XURahz3XOvKfNjQco2PRotNYPNwlH6AS4SOAiOzIOT68YvbL17C bxPP1NwbKIVUZxqaO6/z/9iuxT9OVd7YsRh292H2B7x3ZO2HBH8aCs1pHjVfyu4+ NWzhQuawNbmoT47fr488ubQ1hZH6kVjQ9opi1YFqFc01BYEqrnaQSBclYnRGqs5b +ssGw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEp9gD1tNJOvQDhtypWMDariy1lQZzyPCbTbVWnxI6bdpy2XSc1MIE8cjy3IG5prk 7eXXKQ1+AzawqwVafFnkSQVq3nCftIMNELyf+GmUuKYTB18VwsCSA8x1h9bnf7yYLuIe9s 5/khboCUq8wQeamlgoG70tpcU6O9vPbdw1ApHAaCVlIPXTbjfAhkfSz569KefjxusIkwqg JSlqRrJD0X07dcItAiTmSeecqH/sccyG90oRqGAhsyPnna+gbbNa6u+OTNC0+oiLPN9Hl5 FMsl0L+8C6nVE/5D5EiMbFYLm13buMsfddxLmGjqhI2v2n1p1xvAzA+rwFt4OQHM6ek8TS LROdH5ITYNym7DYMThd5ytddkEUPE9ow9ATan8jyC06t0IkTL6qRs/GiOFfb7o83PkWAjX bhfUQdDUbo0EGqxsJRY5q3MQLNHgFGIZLlxMYjj8siCmdFvzz1cfxA3WaIQHH4+jGxSAbT x8/b00HZNGyJmRG6+Cx8xJ8JttmdjGZdswazMrgv/AclpQnXMyRH5es9dsirbIHgLlIMAL bzkwIRRdvBfZGoMTZcTmhdckZw2qn20/ltdDd2eemBtgCUiq5HMSok/pH8p7rplYOWnUYm s3jeBfBd1S596LVwOoxa1VNzy76436DycfwNnCnzX0bl/bVm43pfskPlJG5g X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:15: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 v3 01/11] VFS: don't count references through ->d_parent Date: Wed, 26 Aug 2026 08:06:18 +1000 Message-ID: <20260825221459.966875-2-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 1b1a81f10da6..241a686f7c5f 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; } @@ -1991,7 +1993,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 @@ -2010,7 +2014,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; } @@ -2772,7 +2776,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; @@ -3100,12 +3106,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); @@ -3118,6 +3133,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 c658c8a5ebd5..59b2b8030b6c 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -235,6 +235,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 27d7dc16fcb0..60586fe65895 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..3b595adff7b4 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 1)) + 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 77fb62f79928..a94eec20275f 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -1123,6 +1123,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: 45c13f3f9e3bb15fd89ff2864c6f627a3b4b4229 --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 8759C3C1978; Tue, 25 Aug 2026 22:16:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696163; cv=none; b=kiJFmhfXUv3rXy57ja6+PPF3WOyPZYGuhxxAq7po4vgeMWC/cgDq07O2KI956bSrVWP1iBJ5lR/3/UvrraCSrG+5VYb83cL/W2PbAU00xJ9vBHOM+s+TaUbTWCrhfzWgGvassidRIQ09VVllJL1MXa6GbicFNid8PZ1aFzCH4l0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696163; c=relaxed/simple; bh=fK4pkggTgr/GElrO3rxQO1XcrT9ZojAb5qmiikH1sBw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UAcNVq6NMGTyf+QZpB9POB0IHrPcEfHdtwUwG8S9yJVqz/NuNggYPINLYOAmpqndIyx9OuFLmVzElw+vFFPA4Rb6cnC36KT0g8SdGCl/hEJQ3Z6DDi0kNdrLz+ob4ukigk3wYiaucz+RGd96caR494ezmXOBzYhrYC92UYufBMY= 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=gC96cYpw; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=RA38Tfi/; arc=none smtp.client-ip=202.12.124.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="gC96cYpw"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="RA38Tfi/" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.stl.internal (Postfix) with ESMTP id 374251300170; Tue, 25 Aug 2026 18:16:00 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Tue, 25 Aug 2026 18:16: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=1787696160; x=1787703360; bh=rYYlq9O8ZKV8pwZJch2/bKtl/152Z5a/VSK8IJLw7bE=; b= gC96cYpwyw5gZtHDIyDhIlq6pRAYKjK1H3hXyvpBJqqPQupOt/8F2M946t4xWjoX FLARhrEvc1FauUM4jT2jDCQ+j0+7KlqPY49DuccUn6fRdb2p6Bb/uSEtGU9BDDX7 XKKttKUau6YZNifWDo1VC/4KVm3uje2j+ZpyvqYXNcke9OSTIgD+tV6TkmRxM/1A 8Rzvg34QdbJdtM26v8AzYIumx/c5LWlOPNsaqqWLgL/3GJV6LLcMLaf5C4CixLJx V5mdIS4EJ1IT9HPa7zriX3B7f/N+tUFW34cgrVSdXlV5FT5RgKvjV8IAdkjdOaJ9 CIThAp6aojyfC+gyPzaTYw== 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=1787696160; x=1787703360; bh=r YYlq9O8ZKV8pwZJch2/bKtl/152Z5a/VSK8IJLw7bE=; b=RA38Tfi/EZMCAjgM4 nRt/D8Dackq1cFjR6fFseS4K/hg8q09S6jnmH8rsnKtnBbUwPyUlCskknsUMNbRO 4zSzbXzlPF8u0B+IsgrkQw0eXXONz7CRW3pKdTyKWsY69iXHA9/W/1L6N/uJ/pIY oTuHEgmPsoKIciVCbqoYpzfgIOtbYs1wKanERib4hPuYdlShhcUFjnHbOW9QL287 4nMp2MY4mlMszia8QXOpvuZi5bxXFa6dRVVy6j/amnIwc3LCr5utYGEbjyFOGn4p 4E+/yPAlQRYY+GcVK3MMWSnIhkj3g2yApf0obhQnWVkqeRMdBycWj1KAarkBLzs5 h1SDg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFZyCPQuUwX0w0Z5hHkugwPAowg8ZqRL0EUJUZiPtXvJZRipsV2j6GBoH6/2TolcI pIaDSXfa9UL+P1e7YKejjhDTypimUgVJWoibsJ08J+UNxZEAN2M0rOKL/X2wAaG6VdROGH 2js0dJSUyrM5O8KgDYoSJa8xImUdoiHPExG98WcYEBg60nxF8P79mFkDGnnVr4BQbxlwj1 PAe2OlHy/75wfPm0Pmi7hlaD4pY0uUf78uU2ncPd1qs8u2hWhVIjcVVzgLy9cfnBm8i5PC k2pldhiFO3LmqWOFjSIfTkKphRFaKcy4gfk1PpVptC5Un0yBMNfjnnvXMkLw/Gt5SLS8Kw UDx78Tb0LoOerx05v1pd9d5gBvtcuLk4VuQ+QNrNBkSK/AJ29mtbCFILa7XNk9+TgsMV7r Q3fGEghRLGZ42/wRjciEeK42uqIUIF8/SAIb8k6TsOIbzqwtOCqqgDpT8rmDTwZu8l7Zte lyKnRkUwAHtCHh2ptzOqWy10BLsA6Xn9BXIgTtujnbH7SpqcBD6cqopruCaaJuvsy0Bmq6 0Z2SnpUHkvu/F+dkDC14qVxluXp1ISRw0KfPNZiTyFTXTQpa3Ryy25Dh0mxUJl4kMRkJm7 EC+W1K855jLBlOqNQ9Io/kvsu6A27+mp+MPIapFs6OY+9aVnUCpH1bBADaLA X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:15:54 -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 v3 02/11] autofs: change positive_after() so it takes d_lock rather than the caller Date: Wed, 26 Aug 2026 08:06:19 +1000 Message-ID: <20260825221459.966875-3-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c index 5c2d459e1e48..bc2be7428158 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) { @@ -80,10 +80,12 @@ static struct dentry *positive_after(struct dentry *p, = struct dentry *child) if (simple_positive(child)) { dget_dlock(child); spin_unlock(&child->d_lock); + spin_unlock(&p->d_lock); return child; } spin_unlock(&child->d_lock); } + spin_unlock(&p->d_lock); =20 return NULL; } @@ -98,9 +100,7 @@ static struct dentry *get_next_positive_subdir(struct de= ntry *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 +119,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 +126,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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 BCBEC496914; Tue, 25 Aug 2026 22:16:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696172; cv=none; b=uF5ty1TyXqJ6HyvjODCbnsQkG6P0X2RlrFSUW42oReI03QN3xmKdmXklQW5aWwY3dJXtc+OMBcNTpGZnzDhkI5Z84H/Or1Wiihr2xewUo+bwv1Cqk2nTNXfU1xQ9Mdr/amTfxn2ZF8XP9QECCwyLAsO279b4LRzDL9i5ueGZE7s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696172; c=relaxed/simple; bh=yIHtNJ55MhE2MaPIfXvzHiwBMs0J+NWpXiu+PMzC4oQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M/XyRiulyJH7ypzhzjALG8+h0Cf+xqA28EkgyBSKpwu3xyuDE1+l+b4F1OZD3PIxK4xQEIr1KXdnyNyn9xoUEJaWS/5SKMZDF8xTFeX+iTXjYR6AH1dSUT0C/rNFPPdpAirFza4MeIjLu+0Db4bPnKOvGySawVF/9+gymPTSGlQ= 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=Qc1mAlMd; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Dn3CPRJb; arc=none smtp.client-ip=202.12.124.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="Qc1mAlMd"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Dn3CPRJb" Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailflow.stl.internal (Postfix) with ESMTP id 57038130017A; Tue, 25 Aug 2026 18:16:09 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-04.internal (MEProxy); Tue, 25 Aug 2026 18:16: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=1787696169; x=1787703369; bh=QBxhcF/9xx0fJVzCRbVatWLSoovuhY6RZpsb7+BVY1I=; b= Qc1mAlMd5IaIWN3dP6CN1WK1l6E6INgVITrFBuVLiKxXSAE9cE0moT9cRNwk8mcJ t31yE7l1Ip8TaNx0UumKBiP9vzapL4EaE8+eUsB3iJ9wBPgJBU606xpYdCx2PC/d Yq9pomzsj3c8006YPA8WprD6sLIsS+xYA+FBXSTRhDvD/wTLT29KacwRaSmRy6/c l5Kk6+suPdMiCSFYgdeZ0QCQsCXWTgunJmyuZcmv7d8A1Bd0rFz4fVmGKUTwIolY J/yQw7D9430RGymy4k0FtaFefYDDntPK/MBreCV3LErhxZf+dNLj63URdgC47uRo 3lWyFPtEyCB7TLxNotJdlg== 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=1787696169; x=1787703369; bh=Q BxhcF/9xx0fJVzCRbVatWLSoovuhY6RZpsb7+BVY1I=; b=Dn3CPRJbdsYQIDuwb /CNxBZ6k5sV5a9vt20sEmXGJg0eb3NMpbOE51s2MXNnmZYbJTFXojWYhY/q80By5 I2tjAOfvtlJAdcH4FUGYQwQD1z5zLQvaNONzWvlhE2szDGEzT6xaaOOiupN4GhK9 HF0TSkZPDZlfl6ylezFo0VOza4v3XYhvn4ZtS1xcTsNBsRkybYlU9TAqWmwsrW9G a8h5enkX0QCJ2a6cLkhD1Sshx7iHv5cnL0IO/ZbLqI2ukEDnftzA0dfThi+9xJ2p 4EuuKJY9HbHzcfJdYGZsFcvguSlnwffFEUEFNefyyfbDh6/VAsR9CTPB3x1K03A2 IIsow== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEp9gD1tNJOvQDhtypWMDariy1lQZzyPCbTbVWnxI6bdpy2XSc1MIE8cjy3IG5prk 7eXXKQ1+AzawqwVafFnkSQVq3nCftIMNELyf+GmUuKYTB18VwsCSA8x1h9bnf7yYLuIe9s 5/khboCUq8wQeamlgoG70tpcU6O9vPbdw1ApHAaCVlIPXTbjfAhkfSz569KefjxusIkwqg JSlqRrJD0X07dcItAiTmSeecqH/sccyG90oRqGAhsyPnna+gbbNa6u+OTNC0+oiLPN9Hl5 FMsl0L+8C6nVE/5D5EiMbFYLm13buMsfddxLmGjqhI2v2n1p1xvAzA+rwFt4OQHM6ek8GL e9rrbDQ14nKf3dquBu2TzJSJilvbxCdNj7is/ITM7c8Dt4h8Xt30EdKD0bln2z5Q6Bo7tP J/yt0PQNWAcTycIzGri4Ckg4gyf3nsXROSzyRB6hxabcACL2pxZYIysh9xoqVx4y6VeDub oMOn3VbdtqX8NOHz+c8DzaD3AL7QbChk8Ufbi56osxVyU7AKVKyZsJ6xm091Qq12IgiMHM qs/JW2I3jJ3jB1PsMfg6Xbv/P/3VYTs0YSfV4blY0jyOZmptQ34BMrAWNmNRPC7uJW8AeZ lPdZ5gohfpRZQMb4nBDWEsR3mqJhdf6Qc+PrmgO3d8Pg5iYGnQsrNOmcldNQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16: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 v3 03/11] coda: don't take rcu_read_lock() in coda_flag_children() Date: Wed, 26 Aug 2026 08:06:20 +1000 Message-ID: <20260825221459.966875-4-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 D61CA490BE9; Tue, 25 Aug 2026 22:16:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696182; cv=none; b=IHDA1MpHErUXrNeiL67D/vpc9sGQeUPdYchONtwAKgi6jLmhMbWs/AXe392jikBn1F/3VCyZz+WeqEuczxBmMwa5XvjaZTW86UILWdFZWFKhdKhjGPlVFOKBha6sIGcRaoqupvvYqfRjX9H84Gcgw3nbJfuOfzkmLFHG4DEBX0k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696182; c=relaxed/simple; bh=5KrhxkfmhuYCFp8k0XOx8NDcmyJfXGghu8RtKBBMvWQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jKfFahblhT86Xf0gD4dIgEGMU3hOosVk8yg11eQPc2/Xu7Iq2+oi5EuctH9bL76yo7wFPlAT19HMbypS31C80BP66xhWy7DmXvuVi+SMYkgDM4Ug8N78H1Np1qzZvJMY2oaQADUUXgpiArymhgOnIDnpKmRHdYUfjmviBc2Lm50= 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=LR0tMSb7; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=YYPKGSSR; arc=none smtp.client-ip=202.12.124.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="LR0tMSb7"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="YYPKGSSR" Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailflow.stl.internal (Postfix) with ESMTP id A048E1300170; Tue, 25 Aug 2026 18:16:18 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-12.internal (MEProxy); Tue, 25 Aug 2026 18:16:19 -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=1787696178; x=1787703378; bh=d8jSa3AAjciJsnljgFzbEoiUesnCHMntledjgHsqTTk=; b= LR0tMSb7OUQhawgtMd3vuUW/p1G2sGx4fH9oDpB+JfjSP2KT1qJVwdmvKScBVrXm XlSHxczcAg0q5eRO1emFv6ff6if4mpgwI8vQWUC7sDdkTOSJ19FxVwt3ngnV/JLx 8SkfrwhLMaxPCQ+sBREWxy4VALj9gC3eKd+TY+DvyJCzEI0u+YCwGcDm3I0NYFHj Pfg+ZtBgroTg+5ebQFRW3F98dCK0p7K4uZ/ShS+MQ/pitXzgAHh1f92rHYt2lhDV WGOWWJPTgKaQMH6Offkveu1oJ1v3wVp2cKGEmQ8UEs0979BJh03SAW+HBcaLSt6d pwpLobogqSkU51Db13URgQ== 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=1787696178; x=1787703378; bh=d 8jSa3AAjciJsnljgFzbEoiUesnCHMntledjgHsqTTk=; b=YYPKGSSRWGOfY5Lrq pE8yuMnoSS/eb6KuZ1MQLGwCc45g1mdDII7dc/8dCQEefJ3+DoYacnmNZ5lHx1CQ ePdCJrM25AGEWS281LEKEamzCCLX6mNvt8wSI47r7ZLl5uawBxAzV07S1dS7rd9x 9sI70zWssKaLJmESDmWtaS1nTq2ujGD4tix4MOgCK8toGy0Qpz1WxHNTVGLrg7Yw mJHcdJ1iv1hm4TZjMf1zlcZS6TQFwerqbPf09MFF9qfR08en2rIdsOm2P8C1rwKl 3/byMzEyy9Wtlm3ONo+LkwpI5Fppw52AKJXgm0Yg2yKRHNKrMZZp6xVMhOh7d6dH by/NA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEp9gD1tNJOvQDhtypWMDariy1lQZzyPCbTbVWnxI6bdpy2XSc1MIE8cjy3IG5prk 7eXXKQ1+AzawqwVafFnkSQVq3nCftIMNELyf+GmUuKYTB18VwsCSA8x1h9bnf7yYLuIe9s 5/khboCUq8wQeamlgoG70tpcU6O9vPbdw1ApHAaCVlIPXTbjfAhkfSz569KefjxusIkwqg JSlqRrJD0X07dcItAiTmSeecqH/sccyG90oRqGAhsyPnna+gbbNa6u+OTNC0+oiLPN9Hl5 FMsl0L+8C6nVE/5D5EiMbFYLm13buMsfddxLmGjqhI2v2n1p1xvAzA+rwFt4OQHM6ek8uH U0kWh0PSng0n/7kgd88VBnv4FmmolfwPYxMoLALKFpD9myUJvzhPG5+NrIzXHlw55S5gMS RPhsBuJfGgrlpos1CAwVtuIqakLJQGIyvDmYd91NL0MWNGZF4SJrdWA+pjV/B92AxsD6cJ pGkpPmIvE9kVMx+IAmePgwcm8z+0nmkdkP9GBkvl2GagzTWTXouRizUopXo6IINaOlpY7w 1BRIqDp/mN38b+Cr8ns3obBbArHjI4LWw6O2DjP82vhfPXPIY1R2DF8F+E3SiI7k2Xz490 UUUZOOl17nqMYhju8F6CGQfwTtLydYiQ4xS3EUHQw8fzTqvuT85j+MCSp15g X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16: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 v3 04/11] nfs: separate locked regions in nfs_clear_verifier_directory() Date: Wed, 26 Aug 2026 08:06:21 +1000 Message-ID: <20260825221459.966875-5-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 36f2e8588922..ef708bbb8acc 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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 C994C4908CD; Tue, 25 Aug 2026 22:16:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696192; cv=none; b=YlDJUdQHJAOVv2qp64iswkYHzgMQKrVn/BBlm8DupMO19OT4ccceNCMlwDkkEEkcJP73jfzFcMNkZaqHXJUni1W353Dy3Ob+fkCJgagIzNeoVrWHQ9dwZWE+BuVVF3PD8PHbcQVG9D5Sa6Y03qd6U8VlAPq4R0eQVI9XeMFJP1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696192; c=relaxed/simple; bh=6aoCjyg6MIezqiXigoJU19gujPvcZ2a+krqzaN6R7uQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gv1MTt9BuNeN5Mqdg4qY1snP14i83zrMpVkmR28deP+YmOuJk7E/coPy7mEaj5oRlPIeoWy07gi4n46ARDsvss/EvGLqFnPmp9QU42GSGszFzpxb4MTVs2CpfCSDbTLHcGqGKGGTVGa4m83XfScADjzMQM8TGc2ccE+lwI/cIzs= 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=R8/HMe9t; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=b+IG9EwO; arc=none smtp.client-ip=202.12.124.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="R8/HMe9t"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="b+IG9EwO" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailflow.stl.internal (Postfix) with ESMTP id 66845130017A; Tue, 25 Aug 2026 18:16:28 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-06.internal (MEProxy); Tue, 25 Aug 2026 18:16: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=1787696188; x=1787703388; bh=Djw9koOjpUMNVE7yG/oVlhtyHMqwB/kRtf5a4gs2snM=; b= R8/HMe9t0DuC6WhIDn1i3MxG6qvcQ+N7j4Oq3UXORNFBHGhZIbp+mNr/PtwvRiC4 Wi9qOzTMEAsytql54wU06pitrO8g5t/c9GvQA6TV4w77YQq9PE5b4sWuOrnJYx+2 sqqF4hkdtRR06Ds7ohYF4xpUpCWse3nYdDXWs6wew2khpWNPSSoVaC0FbHF3C9n+ Q8sjXgvS7BnMtpFRWRYLm79RrVY5m/AA5+wa3UjY/vBJEtQGxVmTIqcPgEo4jz+X 6QYig2CQ0GjEJ4a3A8ribvq4xicbWcs7yYaAujqeDkyZx8XUyA8kuHd1QlzakbYo 30j8GOwQYEvkd/ZpDCmY8w== 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=1787696188; x=1787703388; bh=D jw9koOjpUMNVE7yG/oVlhtyHMqwB/kRtf5a4gs2snM=; b=b+IG9EwOYvbw4v5se dbPgqEN9zLtAuQpc1zRKal92aGISj1MOrQlz4mQiSiU+HnRBPJa3Oai1qzDLEdFv k9Ukmp8HgaEArKrfqiwuPRmiM/o7tmgEy3uApooQUNcnZzQhNV4Jo1cdNBRkNPeL zoOyxOJACUx47Ukc28Elwc3nYoUcS1qMt5cO2cHdyvoRb85H4sa6r/bQvDKXWxwq QtvgWHy/o5M7tJ8Qw7v2iBdeTiy9rCSI4YE8DD5w/Qu9qgJHofq2fUOwsjSiVGuu OzO9jCDOD4KCrB78ddQxDIz0SpDcm0WgVs3SWog4fibmNkMYk7DkAk0u8veUGAS2 8gN4g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE1D9RHiQxYEMTZM66ZwYWPXMa5da/YLC+asllp2LW/9AzO59nDbIWZ/WJDafUyFp uQaTnJVoM5zeNV7PU3Y5Sxe6sA3KXuzbkNtIeFEk21vnmQNZ++SlHK1xc12Wi6N9bKT3Nd l2Jew0OcpEW6pknEcsl3U5kWlcxIcGyDVCcdakxFha864vAOuxadUTtnPo9vV8kQZOtGh4 t615j3/PJH3yhet8tW8bKj0XWaL55deZWQpLJVbikNK8UvNeSeZ0y75HchjkQdooZXWGuR agEorB2pRIG2wLJFguZ3GUkqAvVfWJvN2myN34TtgOMsQRUTFpr+RStZVbDkRTC4KoXuhX jNd7XF10/oFgci/zNfw6syDIXcdujrrXxcHZeaO6Fb9BRacT/HsWb+a7LnUSfFvEjlvd4z l2cpz2NdTohM0ibINNUxxjkExeO1duYw4JV8c9/RQaQbHyji5kO1Lp+moRS5hO5gWLvsIY h6KJ4ZurLgmmc8sygexVAWAYx1nQhps2aGJ0A8mQBYMq1w5BD6+d7SonVRbu79w5hmMTPa EON5byxmjWA8ypjM8yVIT4fvPeSJXwaElXOo1sp5h88bzrzekF7l9ZZUi8kIWkd6C0c3wT 0y0SXbkjNH8z44SWzFfJxWZyOtDbQiNK8GfA59RYMVbkH0cQfwZp7pzmmSVw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16:21 -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 v3 05/11] Add and use d_for_each_positive_child family of iterators Date: Wed, 26 Aug 2026 08:06:22 +1000 Message-ID: <20260825221459.966875-6-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 bc2be7428158..3a70f861ad32 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); @@ -85,8 +82,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 60586fe65895..427f5686decb 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 ef708bbb8acc..748c8388c4f0 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 3b595adff7b4..010d9d47ac01 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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 1A7C949481A; Tue, 25 Aug 2026 22:16:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696201; cv=none; b=EErX8FxDktLtH57ESuVv5l6NaZ6/qVSJaQw6wUMQJfLqht5f1IMPkcwqksC+nWOuhv6AS8VRyfWD7xSmeR3+QL8KCGoVHEdjYhT8rygJTvnwQKv3rbNaHr/5iE7DwJRHMoWrRfMwMd5s4y3XPZHeemYluKZDnRgZNrecSaUeQiY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696201; c=relaxed/simple; bh=Q6gqY00KMt9BpOecieK7oAl5ZowGJd4T4zMUkkyPO+s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tK9p0W7WCdKLKqGviiDRui5bundaauYw1vGM4BUo+nj6ZDdXv38KQ5KNoR8EVmaH2aKLiXBBCEXi+ArMsut1yAGffhcqo9zOpomLFvnhlZtzMW1s59NviTjun5v7ZjbvYpo/OKzU1jCijZqcHAQrqmVavWm8kLKKJ3iEhwyRXi4= 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=A0EUfyWG; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=hol5saBk; arc=none smtp.client-ip=202.12.124.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="A0EUfyWG"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="hol5saBk" Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailflow.stl.internal (Postfix) with ESMTP id B98701300170; Tue, 25 Aug 2026 18:16:37 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-05.internal (MEProxy); Tue, 25 Aug 2026 18:16:38 -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=1787696197; x=1787703397; bh=c7FhbgUvbUThyOjjJ0ZYThL2VJzjUqdTeoa3w2iC71s=; b= A0EUfyWG8dFhy2RZiOV8tm3iq4vMOeiNSj2bTI/wTVnslqvhWDycPiX02Pm2PnZ5 DzxVkyhgNaTPmegqoVaRCh9sKKY447TFH8P0ncb2dZKrcOplzufeXR4ktGKNcEKg aI7qFwrRUcnvTwmh/rmN2Pj1F0yUHXDUsx6wwedy6AfkgY3KWLiA1yT016oxs3Uk NSKuhd+YBAlv/gvV0tj94nYBtMlXqFZoV0lvSon73mAHS4lJnYgWCIIM8sBK06xP JadDtAKV7C+O/VQvLHYQAdwWhgtZcSWruDhWu7+YtFVh+EtohHzjer6nz8lg/os7 sUzMibArbljlCr54C5xOuw== 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=1787696197; x=1787703397; bh=c 7FhbgUvbUThyOjjJ0ZYThL2VJzjUqdTeoa3w2iC71s=; b=hol5saBkwwkWe81oT 2BS8KzCKALmpcqyCpk0ts3K/uBq7Ropma08hC5AB5VIw0s/j0Cm/1D71F5IeXsqM go9NpOJ3nnWKba9Oj3VJNpuE3Qq71T2iqNaZafW/ZxgVFRw2BLkmKY09ARBrHnDG M7SOWeonNf6iHUlZzPg18E73ZEUWBkQZ2oNM5kk2i498FE6JrOSwDNIkA7GD6Epd 8sJW/var+x/xZFrMwTWHpOHIjKtUQXIRvUwDPb/Kghhn+kSkSQ5QU49hpwvyKQKh r21VxKTTr5H0D5fcZkrD1Ipv9zI8eFg0RbMp4L2RpgzFnv8Git60rva40hFrPcms WRfTg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE1D9RHiQxYEMTZM66ZwYWPXMa5da/YLC+asllp2LW/9AzO59nDbIWZ/WJDafUyFp uQaTnJVoM5zeNV7PU3Y5Sxe6sA3KXuzbkNtIeFEk21vnmQNZ++SlHK1xc12Wi6N9bKT3Nd l2Jew0OcpEW6pknEcsl3U5kWlcxIcGyDVCcdakxFha864vAOuxadUTtnPo9vV8kQZOtGh4 t615j3/PJH3yhet8tW8bKj0XWaL55deZWQpLJVbikNK8UvNeSeZ0y75HchjkQdooZXWGuR agEorB2pRIG2wLJFguZ3GUkqAvVfWJvN2myN34TtgOMsQRUTFpr+RStZVbDkRTC4KoXunX 0xlSXTBxCkqk1ethAjDseG3XDUQQLyeqyxkYYveRdHUcYUMvEMp6r/HEz9zqlgl+02CypL x6i2oN4xecX8T6niSfnJ+axjOtkNjSh6wPRd/l3FMaxjGqhml+cl+kGJ4kzqGAuJHMUqpk qXy3qoTDqE55BETkiYUXuKyYZAtOwLKfnbFKVCmMQtOSN+iYdEgjjzPTCwuPClfr5xXyAj REoN7MMYPN9Ig5NvddXomPOJgmQvMul7UlIvF9Ze1yF734Cr8BHXqwwmQyQJf/+RVR2Nyt 2jZogc7XUho4D+TyHqn2h9eox3MADTGcwVvCRCys6qQk9QsXZWOaYbo9aQgg X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16: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 v3 06/11] fsnotify: don't hold a spin_lock across fsnotify_recalc_mask() calls. Date: Wed, 26 Aug 2026 08:06:23 +1000 Message-ID: <20260825221459.966875-7-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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. Normally fsnotify_group_lock() is held to keep 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. In some cases it is safe to move the fsnotify_conn_set_children_dentry_flags() part of fsnotify_recalc_mask() out of that spin-locked region providing fsnotify_group_lock() is held. In the case of dnotify_handle_event() fsnotify_group_lock() is NOT held, but there should be no need to update the child flags as we only need to set flags (they are cleared lazily) and dnotify_handle_event() only ever clears flags (for one-shot events), never sets them. So create fsnotify_recalc_mask_noupdate() which skips the fsnotify_conn_set_children_dentry_flags() part and instead returns %true if that is still needed. Then in places where fsnotify_recalc_mask() is called with a spinlock held, call fsnotify_recalc_mask_noupdate() instead and if needed call fsnotify_conn_set_children_dentry_flags() later when the lock is dropped - except in dnotify_handle_event(). dnotify_recalc_inode_mask() also returns this truth value that that dnotify_flush() and fcntl_dirnotify() can act accordingly after dropping the mark->lock. 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 ++++++++++++++++++++++---------- fs/notify/mark.c | 15 ++++++++++----- include/linux/fsnotify_backend.h | 3 +++ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 9fb73bafd41d..156f6f821c29 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 fsnotify_recalc_mask_noupdate(fsn_mark->connector); } =20 /* @@ -116,10 +116,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); + /* + * We ignore return value and never call + * fsnotify_conn_set_children_dentry_flags() + * because it shouldn't be needed and we don't + * hold the needed lock. + */ dnotify_recalc_inode_mask(inode_mark); } } - spin_unlock(&inode_mark->lock); =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_conn_set_children_dentry_flags(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_conn_set_children_dentry_flags(fsn_mark->connector); =20 if (destroy) fsnotify_detach_mark(fsn_mark); diff --git a/fs/notify/mark.c b/fs/notify/mark.c index b2640d836a71..fadaec74dbde 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -307,8 +307,8 @@ static bool fsnotify_conn_watches_children( return fsnotify_inode_watches_children(fsnotify_conn_inode(conn)); } =20 -static void fsnotify_conn_set_children_dentry_flags( - struct fsnotify_mark_connector *conn) +void fsnotify_conn_set_children_dentry_flags( + struct fsnotify_mark_connector *conn) { if (conn->type !=3D FSNOTIFY_OBJ_TYPE_INODE) return; @@ -322,12 +322,12 @@ static void fsnotify_conn_set_children_dentry_flags( * this by holding a mark->lock or mark->group->mark_mutex for a mark on t= his * list. */ -void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) +bool fsnotify_recalc_mask_noupdate(struct fsnotify_mark_connector *conn) { bool update_children; =20 if (!conn) - return; + return false; =20 spin_lock(&conn->lock); update_children =3D !fsnotify_conn_watches_children(conn); @@ -339,7 +339,12 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connect= or *conn) * When parent stops watching, we clear false positive PARENT_WATCHED * flags lazily in __fsnotify_parent(). */ - if (update_children) + return update_children; +} + +void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) +{ + if (fsnotify_recalc_mask_noupdate(conn)) fsnotify_conn_set_children_dentry_flags(conn); } =20 diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_back= end.h index 618eed4d6d72..4e2708e39a2f 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -887,8 +887,11 @@ static inline __u32 fsnotify_calc_mask(struct fsnotify= _mark *mark) extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn); /* Calculate mask of events for a list of marks */ extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); +extern bool fsnotify_recalc_mask_noupdate(struct fsnotify_mark_connector *= conn); extern void fsnotify_init_mark(struct fsnotify_mark *mark, struct fsnotify_group *group); +extern void fsnotify_conn_set_children_dentry_flags( + struct fsnotify_mark_connector *conn); /* Find mark belonging to given group in the list of marks */ struct fsnotify_mark *fsnotify_find_mark(void *obj, unsigned int obj_type, struct fsnotify_group *group); --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 068A348EBF7; Tue, 25 Aug 2026 22:16:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696209; cv=none; b=NW+aOc/reCzSJ655iJdHqXio0XYFjhfUjolwkgKLjeti2nxqtE4Bza0a0rqIxO3L7R1FzRSwTqPbqFijEijkoHPaVFaAHcTJFxUejvVhv0XVOQINtz8HD+1N7PxI+shKn4+hUsJxphZJEJOnxpUTxsGiTidoq8b5Cdn8u4emEfc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696209; c=relaxed/simple; bh=ZE2AWEM7O60kQNA58ZkvgPkhSH4ss7eUl3SaCWj191U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Yg+pJb6lFL+aBwKq70hIwdWJzUYNwRocDrHVdADZZxMkgaUy3OAjjKNtatere4Fe7fGGCS/rxDu1uf43h93mFBHTNCwLDRUlLJ5dj059TyLCe2y/Lbc1iwdbfLKCfmEiNh9N1qLmLmdFuAOJo59i0zko/bVi3CvcHkwpS774UJg= 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=Z6c/HUN3; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=VR2GjH5L; arc=none smtp.client-ip=202.12.124.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="Z6c/HUN3"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="VR2GjH5L" Received: from phl-compute-03.internal (phl-compute-03.internal [10.202.2.43]) by mailflow.stl.internal (Postfix) with ESMTP id 020711300291; Tue, 25 Aug 2026 18:16:46 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-03.internal (MEProxy); Tue, 25 Aug 2026 18:16:47 -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=1787696206; x=1787703406; bh=MTJXqUkyboP6nT1GdTre2i6fxL2R8FyE2y1tAnQFr54=; b= Z6c/HUN3MCtEQq0acidtkPkLV30vLvd4jBO02+/YjdUWIsWEw8qNcTl7qM/rEuRJ rnN7tjnDmGnyQIH/JRC9a3QECWKREJldBnithAGLgNrIikkdrE7rpBUFAeTfmAmq xM8eHNmyq/7H+bXjn+KlU3UkeiONjet6LHPYw91CnwgK+2UkiE0qBLbkIQ/dHsT/ ht786Ntm5H/5vxLBJjmav9EjJRwidcLZbm5W5GvmYKPDc33Dw/IONCqYmqvgvlSQ jJZjcIXyzloG0ZvRU2HjfA8nwVHa5tTzyxdAqI/XkYuqqHBIzzgKM7M+wQ7137lw wRerkaqMMMqJm1q4DtpCaw== 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=1787696206; x=1787703406; bh=M TJXqUkyboP6nT1GdTre2i6fxL2R8FyE2y1tAnQFr54=; b=VR2GjH5LGvdhouzrq wy4L44fFfLE1BCTj6MQLcBW3oNJ45Dr5oKLl0OAyiNlaNdbIJN+yFY4FgPZAjJHP 6r2F7FqOQ3wEvQ6itU4yMujeb6+/tpzyAnN7iwJhHX46FBo0TryXsugzOZfqs7CB 9opPgntc3s02iLnVb2vHXLYb3oxOXDY9VGEu9yS5T+htPqqZyUMBR1nVohRr79bb Qibl5X3Zjb4VLSXC6HuaJv7ZDMJzLHzr50kY5nuHXTN2fONAZmRYZBvtb1oc19hx L88pD2YDot+C1AuNo4gm1hpiwSaOmfCKa6+DGbnSEXDEXwvoTTL7DQoM6Sn8mqS9 IZ9aQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEp9gD1tNJOvQDhtypWMDariy1lQZzyPCbTbVWnxI6bdpy2XSc1MIE8cjy3IG5prk 7eXXKQ1+AzawqwVafFnkSQVq3nCftIMNELyf+GmUuKYTB18VwsCSA8x1h9bnf7yYLuIe9s 5/khboCUq8wQeamlgoG70tpcU6O9vPbdw1ApHAaCVlIPXTbjfAhkfSz569KefjxusIkwqg JSlqRrJD0X07dcItAiTmSeecqH/sccyG90oRqGAhsyPnna+gbbNa6u+OTNC0+oiLPN9Hl5 FMsl0L+8C6nVE/5D5EiMbFYLm13buMsfddxLmGjqhI2v2n1p1xvAzA+rwFt4OQHM6ek8HP PCcHqnbTXpPt/gDr285uSlpzxdQTDEuS3eYGrcqGdpn+PwsNXF4hRi6KKVkbXv3Pt42sbt IcBiUnmINFi/rO2wuq63WwlDrZfcsmr9ehSpH+6v+Bu0gqKXERn3g41yy2BxVDrdI0ItvU rHvt/SoeZ00W9Kv849lHsg4LIVWdthkLDmIBaafbrX7w1Y3aB9/AOt3Ey1yy61Sev3pb/C 8wnML5IrFWWvqJiHpnR4skRF+HTN1yl9/Ui7zIuw8OtZrVot3+fMFyMhnfnpa2LUWp4ZDd kk5OT7+iDPcWQ5osFrqgdJN9Ts9GQOlZHp3VOzB0FTCliNbc147p/kyE6MiQ X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16: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 v3 07/11] fsnotify: don't hold i_lock while walking d_children in fsnotify_set_children_dentry_flags() Date: Wed, 26 Aug 2026 08:06:24 +1000 Message-ID: <20260825221459.966875-8-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 E367C495042; Tue, 25 Aug 2026 22:16:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696220; cv=none; b=TcPNia5AY4Zr2+Dy06eeuoHvNNddhKTlFqOaVp7Bqjsfe+CeN8P6IrwbEdT9DJ6kUdY0anouRCvo1Rf7FcrqsTryBtK2O1Q4xI3h63G4x4Z3pRXC3bnEBC9AD63Nfwe2w4ffJgi807wnoJ/0yUlFWV1MtZ/x8ygXpd5EWhX4LwY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696220; c=relaxed/simple; bh=HDxxbvnKL+ov/G4Gf+VV6/PKhBoJBh7leGj7TWH7J54=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sob4nhG6qp3MiHAdfexfxn/rXuPAipLurP8kQ4pbsJTH1MLOEZTe6kDwJhmTeUeuMbtEhl0u+t2JTRJDD4UNGyCqSTtJfuS9u9g5gFw5IMNlERGrlv0zpV6/qifMpaKYuhoDjqTUga6MYyeQW44Q7GLA/h7JhykRYACwdE8pFps= 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=Oy9fjj9E; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=kHitmo0G; arc=none smtp.client-ip=202.12.124.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="Oy9fjj9E"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="kHitmo0G" Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailflow.stl.internal (Postfix) with ESMTP id 45AE91300170; Tue, 25 Aug 2026 18:16:56 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Tue, 25 Aug 2026 18:16:56 -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=1787696216; x=1787703416; bh=L8BfRwSOcOjHJq96pMoI0xfny+sOYLUqv3Ul5GwElQ8=; b= Oy9fjj9EIB0jkZrxklcpsSo+77j4uQS1o0cjgjEToIB7zryYmr/8B/n/6sBHjrHw w1FkN4xrhPHNy2iRJSMxHkSAVasJrBLhJnqwEhMXM+PQjXih+9iNCSozXR3yr+uj lVaVgi7tx70jlzzylKqcQxIlYy8QnUk9RyzwHlYZ1r1xS8YIkC7SyrWviOI8PWc6 9itkifvNpqQ56HIEJbf+GoHhbTR3uz6kL/qlyhZpxBfqNa1b1uSbAFZTVMlaq8xF MMw64J9EEtNrjxaB5IGPfXOWefRgCcELCLcWxkSuUUeHadhjO+y4jtKrRI0Cw4ie 69eUAuGwMBhuNeYeA+vSbg== 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=1787696216; x=1787703416; bh=L 8BfRwSOcOjHJq96pMoI0xfny+sOYLUqv3Ul5GwElQ8=; b=kHitmo0GwUpMH+RBG JvGKXKPissVedHYjaTOK3+u10FOC/nP3q9P5ZOQJmne89fSi5Rt45nib/oNiW7Tc bXy6G4frSUom42f2WtC/X0t6A/9vEXfWTzolYCJBcD9uyKRBNw/YgxMRzA6TPviC PsHvuzCUIAadg9D+1RSw1MyOVn85z8s1ixN5B9jBWZVOC0QTJIsqyWQEOOF6YvPR Rwd3nlIUBG0czU7DRMZLHcg8568A+0z84UyuPJIwW1c7NwsjCRQqNuPaHmVanlJW rJ07gkLOOJ3OyrHxkDSoKoHf+2fTjbsNDVRb29dMuUlwXXror5qu7PqWFQgZfAQS DrZuA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE1D9RHiQxYEMTZM66ZwYWPXMa5da/YLC+asllp2LW/9AzO59nDbIWZ/WJDafUyFp uQaTnJVoM5zeNV7PU3Y5Sxe6sA3KXuzbkNtIeFEk21vnmQNZ++SlHK1xc12Wi6N9bKT3Nd l2Jew0OcpEW6pknEcsl3U5kWlcxIcGyDVCcdakxFha864vAOuxadUTtnPo9vV8kQZOtGh4 t615j3/PJH3yhet8tW8bKj0XWaL55deZWQpLJVbikNK8UvNeSeZ0y75HchjkQdooZXWGuR agEorB2pRIG2wLJFguZ3GUkqAvVfWJvN2myN34TtgOMsQRUTFpr+RStZVbDkRTC4KoXuFx VeC8Yg3v+N0Nu5TlT9cE1lVrtJFrL+tSoJY4P52D+mb0qquFS+9pivvmbtGYac/xucfuf/ qpdzgzefP3uqtuCh4QlwWbGkU4wI72E7VUrTS6wqxODDy0kNhRa8JvQr/afZMfJTUARPz0 1E19LtPysBCYCtPA898nMtkWlRIOhKSNw5OSF417wBSn2QC9YtvWNF3iUwSGqPYhV9qIwn AX+g5MZcMvNieMDmRATaeCA/GbJKvm3tcXYwTO53NeeNpHHO1bxirjhWsf7y7sj20YbSbv HHYd8U+5bVzM6PeiGhPnDzCVE5owJos1zkpfCDt2LuMnv6bIN2Ck9Nm7vHJg X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16: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 v3 08/11] nfs: Don't hold i_lock while walking ->d_children list Date: Wed, 26 Aug 2026 08:06:25 +1000 Message-ID: <20260825221459.966875-9-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 Instead of taking i_lock in nfs_clear_verifier_delegated(), take it only when it is actually needed. This means i_lock isn't held while testing the type S_IFMT of the inode, but that cannot change so it doesn't matter. In nfs_clear_verifier_file(), simply take i_lock for the whole function while enumerating the aliases. In nfs_clear_verifier_directory(), use d_find_alias() (which takes i_lock) to find and get the one alias, then dput() it when we are done. The import result here is that we don't hold any other spinlock when walking the d_children list. Signed-off-by: NeilBrown --- fs/nfs/dir.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 748c8388c4f0..a5f6fa57fa39 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1469,6 +1469,7 @@ static void nfs_clear_verifier_file(struct inode *ino= de) struct dentry *alias; struct inode *dir; =20 + guard(spinlock)(&inode->i_lock); for_each_alias(alias, inode) { spin_lock(&alias->d_lock); dir =3D d_inode_rcu(alias->d_parent); @@ -1485,10 +1486,9 @@ static void nfs_clear_verifier_directory(struct inod= e *dir) struct dentry *dentry; struct inode *inode; =20 - if (hlist_empty(&dir->i_dentry)) + this_parent =3D d_find_alias(dir); + if (!this_parent) return; - this_parent =3D - hlist_entry(dir->i_dentry.first, struct dentry, d_alias); =20 spin_lock(&this_parent->d_lock); nfs_unset_verifier_delegated(&this_parent->d_time); @@ -1503,6 +1503,7 @@ static void nfs_clear_verifier_directory(struct inode= *dir) nfs_unset_verifier_delegated(&dentry->d_time); spin_unlock(&dentry->d_lock); } + dput(this_parent); } =20 /** @@ -1519,12 +1520,10 @@ void nfs_clear_verifier_delegated(struct inode *ino= de) { if (!inode) return; - spin_lock(&inode->i_lock); if (S_ISREG(inode->i_mode)) nfs_clear_verifier_file(inode); else if (S_ISDIR(inode->i_mode)) nfs_clear_verifier_directory(inode); - spin_unlock(&inode->i_lock); } EXPORT_SYMBOL_GPL(nfs_clear_verifier_delegated); #endif /* IS_ENABLED(CONFIG_NFS_V4) */ --=20 2.50.0.107.gf914562f5916.dirty From nobody Mon Sep 28 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 4215848D882; Tue, 25 Aug 2026 22:17:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696229; cv=none; b=ENOjg/QlX4p02r7EBjLYek4pFa4jNAj/xjUaW+N2upG5hA8IgWW9kbPup6JwVPrR8xGX+EJP8bph/wy0/GtCVWq8LVqOCY+zq1r0HiKwXvwVLzwS6dmlUsPUVu2A1pWhRAYjhR3c+B8XWM1p3n3X2RcPWRMNVh5WyJPKkKKjPFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696229; c=relaxed/simple; bh=Fm6xHhCkZjtxiXpBHP/xrRjaExSJTlDx8x8+SJ0yzhw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rArkFd1oBdV0mICiRZI9K3Vn9A7vdlLuZEMgaCLdN32rFeFrpR/Dey8NpwSwGy03J7Cn6p2xft/UMb1rmUVKlZyLm4GS2GANbILXveZVdMt8SwhSbyGD4t+C4kebH7dzk+qmMvHY0gC7Gm3ww/8udC1AepTgHlB0kSk6GeT7oW8= 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=pnU2LsrX; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=RGuHdiI4; arc=none smtp.client-ip=202.12.124.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="pnU2LsrX"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="RGuHdiI4" Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailflow.stl.internal (Postfix) with ESMTP id 5CB1A130017A; Tue, 25 Aug 2026 18:17:05 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-01.internal (MEProxy); Tue, 25 Aug 2026 18:17:05 -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=1787696225; x=1787703425; bh=gWfvCddiL95g7aF3HuSf7fyTkicRc4rwTmcdcNoKwZY=; b= pnU2LsrXVFhWceDm0Iiv5tsiRbgjqGIEk0grlwIhEiQl2QII8vIdn7gOZ32DobtA delgYe6nF6h8b+I6K48OOvLnOCRBLonvDtN52BZ+XJ3j1zBXK3XnjGkIV6pf6vP7 Nn2GXo6+xj59prJlcRAkAPtpGLL/giYD1q0GGLSaBh/fMH0p3ovK4AOYyjeAIjnj 9pAbCI6kXS5Gd4XVe/P4wNLLYfVGWVTmmh0L2NYdeep7GzjoiN0v5WheCInI5AJO HCOihDADhnsZB4u2yU1u1JXanu4u+RtwY+tuThyP5ZtkK//FiBZDRjViJvYo2RSt 9dxiZrR1SAfD94VzVaGJ7g== 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=1787696225; x=1787703425; bh=g WfvCddiL95g7aF3HuSf7fyTkicRc4rwTmcdcNoKwZY=; b=RGuHdiI4bEQhgWrQ3 4gMgLCOUOSVYzLelqCVtvO/KQhu9nc7klrvy7a1TBfxC4+IZwvFAS0CGxf51+1PS X3cuqycizh6UAr4kd3pREE8S12+tef84yesd8aCrHItP8cACVIwYiKUpXXEAiJ8P I1tXXEfFO1jAdKDlenxxwnnt4ShdZOa3vDruASXkQQenN6ak2KC73fZUGc7tv6aG uz0cwXVQ+PI6Z/Uk5M65oaVIojPlTJEbN9DWdCxQBhBurtDznznFYQGbQNdeE3Ea VeOJb6A6hU9m9TXwZB4YAgIDqngYSZ82smG4UExqOwqAH+1xo8o6XuE0dDNkb1kK cSdWw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEjJ6W0pcv5dKdBouhAeA3W1aBgLlKUugU6GgJEe14GlOW3sqsKABKbiwQbJ/fhnC 08rS3L5+nyLVGVEl53EbOBH413gsqznjvALzKGI2w6xxkZTK9kVpUzqbInp2P/zHn32egQ fbo+xbxKrE3W063gtvBfsGJY+4a/GENFrlKN+jgA9PT7gxbetJJs7zoKTbHRWcbnq04XFx Vqogj5GlCQ2eRDL1UggSUnm0pkXFG1ivud2B/ZAs+pu6/L8iCWuNjQj6Wckw9lzCyE4Suh SbIvegTnRH1aMPQmF96L4x1YdiiUn3LaW6be9Due+JczR4uCvQU7J/6xYUWeSTX4maHtXv LdZklf9dq9Q/Jm4OQVtKuWFLlU4aP93Aplm1kF5E0mVUrUbjRDwB01fpkXzGpcUVTcr0tT ieDUvUvkyzMwL6ZN69980eu52IXXTVGihmCCyTjDeXkBJSsG/wgDZNcReh+LGsVW3aykBB /Ow+6yT/mO+WQikDsHsAQKkQZkEWhG4BI+7hOb3lER6IUolF2kEbclHMYijTEPYPcZ5x2l wgkhKrOAGxra6/+TQMIUnqbW+sfhqyYB4eJjTYI7w4kxs2yIfI0nNCKhHnzFe1HmL3o+qn dbIlSdHzLxeCzssJySxA5m7PWguHAbXaj1R0xO3ZfM8OXqgjIwA/0cb5Uarw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:16:59 -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 v3 09/11] autofs: don't hold ->lookup_lock in get_next_positive_* Date: Wed, 26 Aug 2026 08:06:26 +1000 Message-ID: <20260825221459.966875-10-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 3a70f861ad32..330c40a17a74 100644 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@ -91,12 +91,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; } @@ -107,13 +104,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 @@ -124,7 +119,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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 B50414908A2; Tue, 25 Aug 2026 22:17:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696238; cv=none; b=aATf/XbmoMnVrRGiENrju69g6ozYUV+kApBftWXIWBNq8xV0Y7wZg3j4ad1J5ldxV2gWDfr+H9TwXmKvnlNsCYfrtcmPkeng6+Ta+u/Vp3emRlIARbNGEUTVJLmiXX9JB8Sa/eoaXZvCcygAd6xPonbmpw41qN2588x4uljoPUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696238; c=relaxed/simple; bh=s//JsVIUoa+s6iE42hfofApjPvizmcqSc3HK9Tj0r2M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l89MaTprKuaaPBdcU7Bbua5JZZB3ppp+YaRuRQw37GS+PctyUc21IcByh7pOAKIbxQdpsCcn6c54sHeNkRPt3Zc5zL/mBmzgvhMJXR45lSA6I1qTOxVkGC0HAsgaq5ZAA/3CtBTT7arDOGD4Kp+p6Kev7wgpmC2EYwArSvAZQRM= 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=it1s+zuO; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=T/910T/V; arc=none smtp.client-ip=202.12.124.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="it1s+zuO"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="T/910T/V" Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailflow.stl.internal (Postfix) with ESMTP id 873431300170; Tue, 25 Aug 2026 18:17:14 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Tue, 25 Aug 2026 18:17:15 -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=1787696234; x=1787703434; bh=XkZEdkvy3hsD5NEcUC8HDQWrdk5Wasl/68IjurHzbr8=; b= it1s+zuOd7FNall8BPJsalEnkdT6B0noq4AwQvv850NOWoEByBsx5HV4EgrtOGEv G9g/I4ED0aOzsChDY9jAgDDJzlM952B/VB8EZakqcqrKOd6vm0j9hbkHgxEH9NbR 61g5ChuNkL63z7VTISRfRahmz4qDz1ZTJ+job43LS0GO30Jux5DfCBqKGDw0aMFM 0aozHC7DdO19BjnSLAMj+X3n1fYir1Tphaoxfr3P9QxIGt9vlhTHsRssC2fw1Mlv euZw70Wq6l9Dt3h0UdDqL0NOMcz9S/ed7KkpfIIp+D6dMw7/wG6Vnl+02n4ZFBBa rejbYjumpuVsrYzdffFW2g== 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=1787696234; x=1787703434; bh=X kZEdkvy3hsD5NEcUC8HDQWrdk5Wasl/68IjurHzbr8=; b=T/910T/Vht1Kq1RAP Xds417Ez9AyLrbf8UCwK61u4rmXjjebqiViGMWFgFr82R4/fDw/NX5n5KpiSkGz8 o1VJ/X8DTQDHye/0lu4LVpXMK3zdGLuXj8w8f0/sHfvn+ptVEgYg+tKFN4ZkOzuw 9hfFvvfP1l0LeCRbfiQKa8/FzbMLQrlGFTW9EUrtjf7F5Fok3SU2x0sMYWlbXsdf kIAWuRYGx20cRbdyZPjxryzpD2NijDrKqISDAOpjIUmTmMJzQEdGd/YcDzP9IcnY IEOA15Leti4gAgR/lh+TN3KfkKA/HHbpHcglr9GbJFo7fBjMmkzMAbsTk6FW1LUU fkGXQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE6VRUgEK5ROGQBK+7Yv25IHM6oNhlVJ+Iru1Xs1RAmv8plZONqNy/4mJeJFYHfiL qzfpIkiTth8WFaNSYBgd/LUQ5fNsLRpXtoSL1udeJ1Fx2eZawujQJUtspwl6nVo68T2489 prqZfMadcdleoHMYjIDO6sFDYy5d1Sq5tzNa9P/H7itNNil0KQM0s6ubEZPKP6TXuIx7nU 3pccFpJgGF1M9hQaRbJh6qJpoljc5zmCnIzW/ohLhVHnadN4E9060RUXboO6Ikd4mjEuxQ GrO5pFlFSkagYdbkVUsSQxy1vIX7S1eA88dwukjZ6NXiPAFso2uqp4GPuRe7gNWCJmerhR AEP//oMP2+h/CbWBgwvNK8BSHSn7N2L/UShCnsWktX/1SHbC4C8F49ExEJBmnz1z6LJZlX CfzK+r1v3v1YJNE7yWHLhpjUedcBPf6X3PXzrHvnDCto+Q6nOCvlG96CXHFMrTdi8WZG8J 6UNjaRT/wFD1Wf+Ie4r/t9JEN7ALrh/geAwas44ocJu32BVd4Supeu7omb3yHwZXyVe2Z+ L0CL1t8QR3/es++o4w5S+m2IQm7skY0Abdcl2fBCoCMC9XO0+46fj+Rc4QcNvl4+CRbdbg Q1DltOUCWG8CaDSs6Yku9q3F7Le/s77G/heKLlXehRTbHhL4T3pGG20eQz4A X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:17: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 v3 10/11] VFS: don't move dentries in d_sib list when they have the same parent Date: Wed, 26 Aug 2026 08:06:27 +1000 Message-ID: <20260825221459.966875-11-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 moves whichever of those dentries that survive to the head of the ->d_children list of the respective parent. 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 --- fs/dcache.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 241a686f7c5f..16b9ea6b0dba 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3057,6 +3057,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) @@ -3124,15 +3127,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 05:45:35 2026 Received: from flow-b8-smtp.messagingengine.com (flow-b8-smtp.messagingengine.com [202.12.124.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 0DC5E499F05; Tue, 25 Aug 2026 22:17:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.143 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696246; cv=none; b=cy3bh4/rayaD3YHbhfQUAbauDhtA7sCdxBXt8t121rqSqS8AKGAMzwelwHsna4CyWpgx87JBUPfy4Bq1mMJEr7n0KE2sPaUYGrOAHynhEUD372zNu0U0u/6PbuQ6IwFZ08y+xDdh7zK6o4VUpHwLnJ1EW6ewGBriLDd96ylr0j0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787696246; c=relaxed/simple; bh=a2CabzHJoTG+hhKHw3vEvynX0oIaEA+hEsH2xlg70iY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EwGt3c139mjj0kT1Tzk94bQ/UOMFCe0di2LlRcflfCDyMi9rwyXjO6ReLL2zH3L8HVOl80q0NZap6eh0T6yTRL15mLL5Kf8xv3/gZYGA6ulun6HLFYAqHNk44G+3rmAIWUe3YzpwH8Qq/6ekJfH6AxCGZ1k8Xvl6fmQuFj0Y19Y= 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=JvEQi1cg; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=XUoZeTMb; arc=none smtp.client-ip=202.12.124.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="JvEQi1cg"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="XUoZeTMb" Received: from phl-compute-03.internal (phl-compute-03.internal [10.202.2.43]) by mailflow.stl.internal (Postfix) with ESMTP id C42B8130017A; Tue, 25 Aug 2026 18:17:23 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-03.internal (MEProxy); Tue, 25 Aug 2026 18:17: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=1787696243; x=1787703443; bh=UBHpINBx7VpvzE09q7PdBwOx6AkTQUjP/c1v2gUqMPs=; b= JvEQi1cgFHv6FAZVbFI8HXZFC11AyoNiJU/kCFBmy7Vx7cm6BHGlP/2Q8wJ3reW5 5ELj22h5lnbmM/X6Fq3zrGqz6RFXyaSuLXpc3MePK1mEjyfTRQ21pmUOm7jTBFln yZlO84r6K5g8MMCpEeiRXqi6uC8uRCWoEBJCIFKsay/BtQBjwp3dxTu1P4khlVwd C+81DiwpnpCN+rDWrcpANOv/LOQkOzYHBoSTCd0iqQKwDanq8BDtpYSxmozNos6x JsKAQCR6twXDjaxE5ZzuWaC7O0uoV0Obt0SKbcbWSQvuCvUh5IqJcviZRvXsH8/z B9q1vZlJ9is+5D6YQIZq+w== 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=1787696243; x=1787703443; bh=U BHpINBx7VpvzE09q7PdBwOx6AkTQUjP/c1v2gUqMPs=; b=XUoZeTMbUiUVy9QXZ aFyxsv9uZdg3cvwe112ySQUPWWzSGqX4CXtHhepHlM5Z2HhLdkLieVfj3l9X1cR2 x5YOk4xiXTjCwejuXip+Yda3JGKikSIXgGAdGlHw9CPcJpRY4clx9PsmBnIIYRXv s9QhbaH1v+L9SUk+h34IYr++YPtGOfQf4l+laFJfv1QoJlqbsz2KggSmWEnq2B3y sohGzvy9A4WunuTMucs4WSQ2wm9JuWJzekMQNkZlCaxWZWki9m2oCCJo6TTpoSKR O2BirXfNHAqkiPUQ6z9eVZ7+FeCZEldomBUbgVHx3U9BN1c1IjpTjeNDfdE2qUaU BKcIw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTG3XHstY7oCKVsQdeqHBdBuufcL/CA2QIo6EvAmZ4DJma5jqyLguXmtZz1oV5gGKM JCEjUhdv7rmdEGEOLAaZLpBU1Q66TxI/zZMqNpIt0C13TEMeyhIfscK1jE7F1qNOMydH0t A5dAmKrJhtCAdCa7hg9xvPxRe0dE/zk1kxscLUDttafsczEWN7oOwsWP0kH42KqwbOw+CV S1Ja8pCR8OZYPPoh75DaFRX4LyMBuZHB81G3BkZTKJQySTwonosPQytaGGN+xVjh52eonq ej95qkgeaTpeb6AvXzkRFTQqDaqGPeC86IY9QcPV0uy78rknTA3sPKayiCUxSyZoFPTwIB LBkBfoNJWtzlw0foJAyWxYZuf+BUwcnddJUeibn0Aci9cFsUfz2sXUyHQrEPWGXfjwEsF/ FZCbrOkW+LZGBJf6XsPkvq6OKja0QYyQSMdR4Udsdyjn/T91mS/qDRNf8VxUvjcvJBk9+P QUgk7nOFMQkVGzPFwbmtAAueMvGk6RleUnzwinuSJzbyuNriB8OKrqlmFt2zGwFY61R2U8 f2CZwa4YYDHFPAoDWV1/cjfKZKuzeK8UqMjBY8kvUljSyPX/ulnPnR/kPpT389BB7wuJg8 PYbym9lkrPiva2q97zGQnbuX9lXp01jYMD0jogD4bsqWK652N5CtGX/eoBOw X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Aug 2026 18:17:17 -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 v3 11/11] Call cond_reshed() as needed in d_for_each_positive_child(). Date: Wed, 26 Aug 2026 08:06:28 +1000 Message-ID: <20260825221459.966875-12-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260825221459.966875-1-neilb@ownmail.net> References: <20260825221459.966875-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 16b9ea6b0dba..59c936d30dee 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1890,6 +1890,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 @@ -1899,7 +1917,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; @@ -1927,14 +1944,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; @@ -1944,20 +1961,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); @@ -1974,6 +1978,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 010d9d47ac01..2923a8ab16f5 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