From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D8994106ACEC for ; Thu, 12 Mar 2026 21:45:57 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 419D16B00C0; Thu, 12 Mar 2026 17:45:57 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 3DA396B00C1; Thu, 12 Mar 2026 17:45:57 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2D3F06B00C2; Thu, 12 Mar 2026 17:45:57 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 1C7CD6B00C0 for ; Thu, 12 Mar 2026 17:45:57 -0400 (EDT) Received: from smtpin29.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id E1D6D1C4FB for ; Thu, 12 Mar 2026 21:45:56 +0000 (UTC) X-FDA: 84538743912.29.93E9F2F Received: from flow-b6-smtp.messagingengine.com (flow-b6-smtp.messagingengine.com [202.12.124.141]) by imf04.hostedemail.com (Postfix) with ESMTP id 170E440002 for ; Thu, 12 Mar 2026 21:45:54 +0000 (UTC) Authentication-Results: imf04.hostedemail.com; dkim=pass header.d=ownmail.net header.s=fm1 header.b="pPGvE0/w"; dkim=pass header.d=messagingengine.com header.s=fm1 header.b=eFIhTwRQ; dmarc=pass (policy=none) header.from=ownmail.net; spf=pass (imf04.hostedemail.com: domain of neilb@ownmail.net designates 202.12.124.141 as permitted sender) smtp.mailfrom=neilb@ownmail.net ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1773351955; h=from:from:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=pOd6V7aKWFyKrN4KTkaFsGguAEcn5SSc/x2IfH39lBE=; b=wcukBQYIbIhxZu6AKBdAALweZUi9Q8NnsJrLmAP0cZOJMYvinzZVN1hxWaHMoy1LSC+VPN HsRr8R5uLYRITtTDUonRP5N5f+j9Jq3kyRzahBBIczTGvCxsi3NE5G5nB6dOFr+yZwzZOH zQdcmL3a0C219q+Tw3EJLsDcWayvCuE= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1773351955; a=rsa-sha256; cv=none; b=cfaFjChpvWWlzMJgPWtRcFOdds0o7Fy88GNYY/4H4LB5sVFIgZ03e0ZwRRY9m33GnNb+7Z XPnqM889DCB/OkgFme7Uurix7HU1JgemhO49wNbysdEgaP9rhpdxzoSIjGL4wxDBSu2yn2 IUSHcfcpN3LkfA/bTg/wTCVFl67/tKI= ARC-Authentication-Results: i=1; imf04.hostedemail.com; dkim=pass header.d=ownmail.net header.s=fm1 header.b="pPGvE0/w"; dkim=pass header.d=messagingengine.com header.s=fm1 header.b=eFIhTwRQ; dmarc=pass (policy=none) header.from=ownmail.net; spf=pass (imf04.hostedemail.com: domain of neilb@ownmail.net designates 202.12.124.141 as permitted sender) smtp.mailfrom=neilb@ownmail.net Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailflow.stl.internal (Postfix) with ESMTP id 3580F1301B45; Thu, 12 Mar 2026 17:45:53 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Thu, 12 Mar 2026 17:45:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm1; t=1773351953; x=1773359153; bh=pOd6V7aKWFyKrN4KTkaFsGguAEcn5SSc/x2IfH39lBE=; b= pPGvE0/wze36tWU9meYWm71B5TEuwgjRl7cD7NY/VsCrs2UOu2H4cZhD6kfNHK43 Gr8Z3X40uCciBPHCc3eRyAxd0EHgpM0FWGMKdxp/Lit40UuawYIoChKd4ytFu+bO CTK+mieDXDcRAN+U05ePX8ZprftdvXdJsHYS8r3C+1MTsutJNW0FqPdRKSFiYaFT Pqawe5NhNacvc0OkXGvVXjEQqAlmMwvgk3rU83qWlvWjsWS/ZnyYUGpZ/usSmSdc AGeM7LfKykjTRzE1phaKDqaKG02WaJ0E/+KnLi17wRz8EFCnEX16D9eXuio1p71E oCnNMDE2YXOHhTwDCTQM5w== 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=fm1; t=1773351953; x=1773359153; bh=p Od6V7aKWFyKrN4KTkaFsGguAEcn5SSc/x2IfH39lBE=; b=eFIhTwRQmdA0/ycbp 8k0ZJ7O9a3vmHkwPo0UDJPa38tcW6T9LKWyKQHfAjkADzC3U71y4B7rTKoW0jIaf tsM6beiXSWuOpcbEyCcfhU2jv/1y/Kts15nH7ihQoxLpfH0I6VRBmHfyeRReNVo4 b0/JsGh7FRaLG/C/GLScSrCB7cbwYMNlzSOG6FyDcYRBiotzXpc70QmG2mbiCaDH YTYQtO5R/TPsIHwSTrhlkKSrP8toQTjRONGsz3tAKHk5XSLxx7gESTZIV43TxO1L PBtIW4sJGXH9emjdJB3Qa/nCukQmQopIL/3vXMQ6YMNKVJ66Fqn16mg5BqQSUbEA ifZ5g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddvkeejkeelucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhephffvvefufffkofgjfhhrggfgsedtkeertdertddtnecuhfhrohhmpefpvghilheu rhhofihnuceonhgvihhlsgesohifnhhmrghilhdrnhgvtheqnecuggftrfgrthhtvghrnh epveevkeffudeuvefhieeghffgudektdelkeejiedtjedugfeukedvkeffvdefvddunecu vehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepnhgvihhlsg esohifnhhmrghilhdrnhgvthdpnhgspghrtghpthhtohephedupdhmohguvgepshhmthhp ohhuthdprhgtphhtthhopehvihhrohesiigvnhhivhdrlhhinhhugidrohhrghdruhhkpd hrtghpthhtoheplhhinhhugidqgihfshesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgt phhtthhopehlihhnuhigqdhunhhiohhnfhhssehvghgvrhdrkhgvrhhnvghlrdhorhhgpd hrtghpthhtoheplhhinhhugidqthhrrggtvgdqkhgvrhhnvghlsehvghgvrhdrkhgvrhhn vghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqnhhfshesvhhgvghrrdhkvghrnhgvlh drohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgv lhdrohhrghdprhgtphhtthhopehlihhnuhigqdhfshguvghvvghlsehvghgvrhdrkhgvrh hnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqvgigthegsehvghgvrhdrkhgvrhhn vghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqvghfihesvhhgvghrrdhkvghrnhgvlh drohhrgh X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 12 Mar 2026 17:45:39 -0400 (EDT) From: NeilBrown To: Linus Torvalds , Alexander Viro , Christian Brauner , Jan Kara , Jeff Layton , Trond Myklebust , Anna Schumaker , Carlos Maiolino , Miklos Szeredi , Amir Goldstein , Jan Harkes , Hugh Dickins , Baolin Wang , David Howells , Marc Dionne , Steve French , Namjae Jeon , Sungjong Seo , Yuezhang Mo , Andreas Hindborg , Breno Leitao , "Theodore Ts'o" , Andreas Dilger , Steven Rostedt , Masami Hiramatsu , Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko , Tyler Hicks , Andreas Gruenbacher , Richard Weinberger , Anton Ivanov , Johannes Berg , Jeremy Kerr , Ard Biesheuvel Cc: linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-xfs@vger.kernel.org, linux-unionfs@vger.kernel.org, coda@cs.cmu.edu, linux-mm@kvack.org, linux-afs@lists.infradead.org, linux-cifs@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, ceph-devel@vger.kernel.org, ecryptfs@vger.kernel.org, gfs2@lists.linux.dev, linux-um@lists.infradead.org, linux-efi@vger.kernel.org Subject: [PATCH 05/53] VFS: introduce d_alloc_noblock() Date: Fri, 13 Mar 2026 08:11:52 +1100 Message-ID: <20260312214330.3885211-6-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260312214330.3885211-1-neilb@ownmail.net> References: <20260312214330.3885211-1-neilb@ownmail.net> Reply-To: NeilBrown MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: 170E440002 X-Stat-Signature: pd9zer7c9rj5wt5mhw8i5k786fi8455q X-Rspam-User: X-HE-Tag: 1773351954-14441 X-HE-Meta: U2FsdGVkX19MAprliaxAO8FdFzrXo27xuAQEvKKAFztNcxbE6xu6gplnvix/dMk/rq1VkU+4rb/hiG4rRq0hbyuLzsO84tqUhYHxErYJW4ZCk5JoNPanN+6OJ7rPDU6ZIvaB1U2qjTfntpTRQBVrDsoJOaB6dk5NjAf5GPaviBeShWilQqpjzDqp6or8+XpkTI1v6VIe+uwLIo+Wvy/hOAos1j8nu6Voj/LN5pEF1pUkEM/830/71TaQ1wrFCEM58+qUuLqD3x3ABG4BYVc++IYgx7HtrSqHJT6tTS7wpyQIHjolqH/6BBwIrmMnTnXGYIV+7hgK/pBBSpfHae6r98wMzUgDpVuN7fAoljNdzthPGpub1sacDnLjm3RSg5DmzJxxFKvkJluDIJfwpExAeNHTpFN/7Xnc5Btp+7qsDjDavkyooGl81GFjtJNCT1dNdrgANtNDp9MVW+X2FwJ7WX2EA1Ma06LK6ylrSXwPAcJm54k/0qJhIyJve1DZ/Z9spGrG5I8Ckqh0fjztBz8+c3Nm25Gll2qLY7DjClaXN7WIrDLLtoOD+N6BGN9G5r/ciLI81yRF2PUUezrpX1rxmfUh2vnXHIyjamL6+nU2JKTrwKrsYLs/1w7x/xIc5tfRhWAWusxwlQ7XLhknBVuTSlZcuJlFkAI2nH2VTmFkDNP/ZD1VIPOROms24A88B2BAFij/JYfkTza3uaQwLARY4g9v+zBBVHJSldPkA4oVK+ouMzOrzWtx/AhYUDS0x/MJcKMnekU0+v33Po4hYyyBJf6L2/jaJQ9ihJo+mJKvmCXVjB5dLR7xRHFzSahxH3sS8LgPY2/sQSKbvNXm78Li0G3PkXcLZPH3wP1/n6XMiSTBIC4KnNfUCahiK7uCwd1ugBe0QbCqwnxz8YPKv4eFY+omQRUFScFbQXfJR6dtRduta1FoizULYg8oqIFvF+23kTOGkj4gcrVMwstED2u v6N2tvhn mAfYpsOMXbAVViuXPndJfeXVNroFI1MR0bpj6EbOBZZZ31hyzeC6mhT/eIhQMJys7Uwi2QpkueWW8DkooaEc9f8guUyQEpEIEWIWMl/2ltswLoGibGfEfj1dkHQsGx9HJTuLp1QG63I/XdixBU11e+dVByRVRxli7zwhYWybork15qbAe60fOU0FusbO+jPleZ+S2pfRnrKF2vYj0pv6rpTVILNvacw5nwGJ0+mBTIgo1Q7jaNyHeYKtN/tHPSaGyfrKbFRecrmWrOfUxyCXQYdJPCSK/p/4FfI8reOPranbG/SXkhiC08egUGY1lDgOJfCgWE+oOx3jeT+8= Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: NeilBrown Several filesystems use the results of readdir to prime the dcache. These filesystems use d_alloc_parallel() which can block if there is a concurrent lookup. Blocking in that case is pointless as the lookup will add info to the dcache and there is no value in the readdir waiting to see if it should add the info too. Also these calls to d_alloc_parallel() are made while the parent directory is locked. A proposed change to locking will lock the parent later, after d_alloc_parallel(). This means it won't be safe to wait in d_alloc_parallel() while holding the directory lock. So this patch introduces d_alloc_noblock() which doesn't block but instead returns ERR_PTR(-EWOULDBLOCK). Filesystems that prime the dcache (smb/client, nfs, fuse, cephfs) can now use that and ignore -EWOULDBLOCK errors as harmless. Signed-off-by: NeilBrown --- fs/dcache.c | 82 ++++++++++++++++++++++++++++++++++++++++-- include/linux/dcache.h | 1 + 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index c80406bfa0d8..f4d7d200bc46 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2661,8 +2661,16 @@ static void d_wait_lookup(struct dentry *dentry) } } -struct dentry *d_alloc_parallel(struct dentry *parent, - const struct qstr *name) +/* What to do when __d_alloc_parallel finds a d_in_lookup dentry */ +enum alloc_para { + ALLOC_PARA_WAIT, + ALLOC_PARA_FAIL, +}; + +static inline +struct dentry *__d_alloc_parallel(struct dentry *parent, + const struct qstr *name, + enum alloc_para how) { unsigned int hash = name->hash; struct hlist_bl_head *b = in_lookup_hash(parent, hash); @@ -2745,7 +2753,18 @@ struct dentry *d_alloc_parallel(struct dentry *parent, * wait for them to finish */ spin_lock(&dentry->d_lock); - d_wait_lookup(dentry); + if (d_in_lookup(dentry)) + switch (how) { + case ALLOC_PARA_FAIL: + spin_unlock(&dentry->d_lock); + dput(new); + dput(dentry); + return ERR_PTR(-EWOULDBLOCK); + case ALLOC_PARA_WAIT: + d_wait_lookup(dentry); + /* ... and continue */ + } + /* * it's not in-lookup anymore; in principle we should repeat * everything from dcache lookup, but it's likely to be what @@ -2774,8 +2793,65 @@ struct dentry *d_alloc_parallel(struct dentry *parent, dput(dentry); goto retry; } + +/** + * d_alloc_parallel() - allocate a new dentry and ensure uniqueness + * @parent - dentry of the parent + * @name - name of the dentry within that parent. + * + * A new dentry is allocated and, providing it is unique, added to the + * relevant index. + * If an existing dentry is found with the same parent/name that is + * not d_in_lookup(), then that is returned instead. + * If the existing dentry is d_in_lookup(), d_alloc_parallel() waits for + * that lookup to complete before returning the dentry and then ensures the + * match is still valid. + * Thus if the returned dentry is d_in_lookup() then the caller has + * exclusive access until it completes the lookup. + * If the returned dentry is not d_in_lookup() then a lookup has + * already completed. + * + * The @name must already have ->hash set, as can be achieved + * by e.g. try_lookup_noperm(). + * + * Returns: the dentry, whether found or allocated, or an error %-ENOMEM. + */ +struct dentry *d_alloc_parallel(struct dentry *parent, + const struct qstr *name) +{ + return __d_alloc_parallel(parent, name, ALLOC_PARA_WAIT); +} EXPORT_SYMBOL(d_alloc_parallel); +/** + * d_alloc_noblock() - find or allocate a new dentry + * @parent - dentry of the parent + * @name - name of the dentry within that parent. + * + * A new dentry is allocated and, providing it is unique, added to the + * relevant index. + * If an existing dentry is found with the same parent/name that is + * not d_in_lookup() then that is returned instead. + * If the existing dentry is d_in_lookup(), d_alloc_noblock() + * returns with error %-EWOULDBLOCK. + * Thus if the returned dentry is d_in_lookup() then the caller has + * exclusive access until it completes the lookup. + * If the returned dentry is not d_in_lookup() then a lookup has + * already completed. + * + * The @name must already have ->hash set, as can be achieved + * by e.g. try_lookup_noperm(). + * + * Returns: the dentry, whether found or allocated, or an error + * %-ENOMEM or %-EWOULDBLOCK. + */ +struct dentry *d_alloc_noblock(struct dentry *parent, + struct qstr *name) +{ + return __d_alloc_parallel(parent, name, ALLOC_PARA_FAIL); +} +EXPORT_SYMBOL(d_alloc_noblock); + /* * - Unhash the dentry * - Retrieve and clear the waitqueue head in dentry diff --git a/include/linux/dcache.h b/include/linux/dcache.h index c6440c626a0f..3cb70b3398f0 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -245,6 +245,7 @@ extern void d_delete(struct dentry *); extern struct dentry * d_alloc(struct dentry *, const struct qstr *); extern struct dentry * d_alloc_anon(struct super_block *); extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *); +extern struct dentry * d_alloc_noblock(struct dentry *, struct qstr *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); /* weird procfs mess; *NOT* exported */ extern struct dentry * d_splice_alias_ops(struct inode *, struct dentry *, -- 2.50.0.107.gf914562f5916.dirty