From nobody Sat Sep 26 03:10:50 2026 Received: from fout-a4-smtp.messagingengine.com (fout-a4-smtp.messagingengine.com [103.168.172.147]) (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 1B082438488; Fri, 4 Sep 2026 21:53:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558806; cv=none; b=faNznEsV10UuAx4CMzWZS9/FWD3xHxLFcdWryKFGErACTxOHbsBGLEUujYX/wkZt9K3CWETlsksTgQVRf3kKuK9naVBheLRcEyrPr94TFU1PBcRsa9SqDBSXzft55uPgpJEtGm0VKD0jvfc0Milq2SyETZfzjUTSW5iQvpZYZSc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558806; c=relaxed/simple; bh=85DynhXkr+hqotCALLziTC6eMfYHwSakefI7Y+Thsvc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JPZniU0j8mvWR1JaF22Ne7MQKFe15tRpZQ+V1qvkp4/SlC5LoCYFfTiT7BD1lEE/D8JWBwsvjWqIYuVgTOVCE9c0qXoqshsS0v5jW85fdlbD6oLRbs2SNuSdcnz9+iPgYI8Ws5zFWx7N2P8uAvCinhkn+9CcDz/zvlrczT8n+ZE= 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=DndfaxsM; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=qtDp5doh; arc=none smtp.client-ip=103.168.172.147 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="DndfaxsM"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="qtDp5doh" Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfout.phl.internal (Postfix) with ESMTP id 3948DEC0177; Fri, 4 Sep 2026 17:53:24 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-04.internal (MEProxy); Fri, 04 Sep 2026 17:53: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=fm1; t=1788558804; x=1788645204; bh=ffp/q4O+ehQP4wOXC4Hjwke9m+zN+xkUyMSMNGMBba0=; b= DndfaxsM8+Mak7SRlUux3CVNkD792tmLf5QIhtbbOAacnRz/MH0ySA4rUaa+DLvP aFM9G6SZPTC6xcllnM1mhfaRAogPuzW2UEC7oppzRvPEoVPVsmh2wOV2lSMEFbRv v503CoMYG9jCGkRwrIf9ItQvBAH1TrW5EYUOb7KyFuN9Y76F9P6e9QQfUwtOXD9z /BwwjOVzECZM5OscuTpgsVHdzarH0CDslmY+pQvVfY9fkovRw+teR4pAoj5aluYS 4/SppNYTUZUnWeGSR7tR6WqkdQnrwT/H667le2FksehKj/XQMDOaiV7wF11Q6H0i H4gLivimQSlOYereLbKj8Q== 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=1788558804; x=1788645204; bh=f fp/q4O+ehQP4wOXC4Hjwke9m+zN+xkUyMSMNGMBba0=; b=qtDp5dohMqgPlf8mg IWvGvFHoLFr4jfyp2wrXmMCOJ0H/FEt0TmvmtNEFESRAr1n0zHa5Z5Mr+o6sAjBo 8+XccYfk7uvzGw/qgR1KeG4c5MO+46asFrMjWvLZgyuWzeNbHr584TGPRqDjeEy3 28lbQpdtnJzBIaZj3eWEFS5Cl6ZdQmw0T8NVkN2/LKUXafN9jt1+jxFhOGEUJpcm LBJUde8T9WsPIWpXwA/4ESexVH1LKe9w40HDNqsHVE3o7I3hF3uLeLsYxcFjX6g1 UmLsw2lqVHd60AFlsHowxFi8w5g/WWfjPRagPcvbSW8odq3NuRavYNMVGdwk+nvn cRPeA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFDVljjZPAYZ1l/aqq4nrL+3Kba1UGdgNzRbLHxNyZsBntb6givVbdJfo5BU3j95t +UQU7WjR6Go54RULzYYdNoUTzLStmDkBzIg7iAUMGGPyun7cXaJ/tB+RDeFqAMJs98sAqA 8UTNhC/OQM/aHTCEgRGMWo/qNqW4Cm4ZpbUAGc1yB/wYZCmyUFIFjHNO+nBl6KHnpd3kh5 kJGEMNZuUD6j2jJVpJ5tURud5waXhGOgIEZWqqHFhojd6ln7NIlrB7SgqCD/laD7h+xaRU I5R2WpSXAH/sDdSGVPXGsuUa9Zu1lOQJK4tOelP1k+iwmt4tCWllwcYTI4lONAt5xo76MI uZ9x4KzI43xEJtyuhOyf/J/QGWj8/7Ngd2otOnD2SkxwuROzkZWYzXH5yCiZNgCthKVZ4I +QgwLYBADSgcVsZPAcCrL1kVChscRFNeuO1GxarzyUkhRiPluOHUHJd0vSZ0DHmcx4ssQJ BXQCZQsK0OykZrB1BTFGrOeOkDTmnkdUOP1SX+ibISCyh8RKEEcHP2DVkIN21kJpD4TGYt IdpCeZ5Jv3NstDsDxwks1pjxXBogDxiXL7YwsYMVocFDdDk/I/Cf/Ra9Uw4OjIJnQGr8zR FqDAamx4TBkj+4Pi7989yKwLDFzi02sPSEbtpS7WtvJji0iEYHd+YhfZcibg X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:21 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 1/7] VFS: fix various typos in documentation for start_creating start_removing etc Date: Sat, 5 Sep 2026 07:48:10 +1000 Message-ID: <20260904215142.1060510-2-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 Various typos fixes. start_creating_dentry() now documented as *creating*, not *removing* the entry. Unwanted spaces in Documentation/filesystems/porting.rst removed. Signed-off-by: NeilBrown --- Documentation/filesystems/porting.rst | 10 ++++---- fs/namei.c | 34 +++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesyst= ems/porting.rst index 60880eb0c49d..4e015f1bf1f8 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1203,16 +1203,16 @@ will fail-safe. =20 --- =20 -** mandatory** +**mandatory** =20 lookup_one(), lookup_one_unlocked(), lookup_one_positive_unlocked() now take a qstr instead of a name and len. These, not the "one_len" versions, should be used whenever accessing a filesystem from outside -that filesysmtem, through a mount point - which will have a mnt_idmap. +that filesystem, through a mount point - which will have a mnt_idmap. =20 --- =20 -** mandatory** +**mandatory** =20 Functions try_lookup_one_len(), lookup_one_len(), lookup_one_len_unlocked() and lookup_positive_unlocked() have been @@ -1229,7 +1229,7 @@ already been performed such as after vfs_path_parent_= lookup() =20 --- =20 -** mandatory** +**mandatory** =20 d_hash_and_lookup() is no longer exported or available outside the VFS. Use try_lookup_noperm() instead. This adds name validation and takes @@ -1370,7 +1370,7 @@ similar. =20 --- =20 -** mandatory** +**mandatory** =20 lock_rename(), lock_rename_child(), unlock_rename() are no longer available. Use start_renaming() or similar. diff --git a/fs/namei.c b/fs/namei.c index 20a6534ea3ef..8d8d2af185f1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2946,8 +2946,8 @@ struct dentry *start_dirop(struct dentry *parent, str= uct qstr *name, * end_dirop - signal completion of a dirop * @de: the dentry which was returned by start_dirop or similar. * - * If the de is an error, nothing happens. Otherwise any lock taken to - * protect the dentry is dropped and the dentry itself is release (dput()). + * If the @de is an error, nothing happens. Otherwise any lock taken to + * protect the dentry is dropped and the dentry itself is released (dput()= ). */ void end_dirop(struct dentry *de) { @@ -3210,7 +3210,7 @@ EXPORT_SYMBOL(lookup_one); /** * lookup_one_unlocked - lookup single pathname component * @idmap: idmap of the mount the lookup is performed from - * @name: qstr olding pathname component to lookup + * @name: qstr holding pathname component to lookup * @base: base directory to lookup from * * This can be used for in-kernel filesystem clients such as file servers. @@ -3243,7 +3243,7 @@ EXPORT_SYMBOL(lookup_one_unlocked); /** * lookup_one_positive_killable - lookup single pathname component * @idmap: idmap of the mount the lookup is performed from - * @name: qstr olding pathname component to lookup + * @name: qstr holding pathname component to lookup * @base: base directory to lookup from * * This helper will yield ERR_PTR(-ENOENT) on negatives. The helper returns @@ -3259,7 +3259,7 @@ EXPORT_SYMBOL(lookup_one_unlocked); * the i_rwsem itself if necessary. If a fatal signal is pending or * delivered, it will return %-EINTR if the lock is needed. * - * Returns: A dentry, possibly negative, or + * Returns: A positive dentry, or * - same errors as lookup_one_unlocked() or * - ERR_PTR(-EINTR) if a fatal signal is pending. */ @@ -3381,7 +3381,7 @@ struct dentry *lookup_noperm_positive_unlocked(struct= qstr *name, EXPORT_SYMBOL(lookup_noperm_positive_unlocked); =20 /** - * start_creating - prepare to create a given name with permission checking + * start_creating - prepare to access or create a given name with permissi= on checking * @idmap: idmap of the mount * @parent: directory in which to prepare to create the name * @name: the name to be created @@ -3413,8 +3413,8 @@ EXPORT_SYMBOL(start_creating); * @parent: directory in which to find the name * @name: the name to be removed * - * Locks are taken and a lookup in performed prior to removing - * an object from a directory. Permission checking (MAY_EXEC) is performed + * Locks are taken and a lookup is performed prior to removing an object + * from a directory. Permission checking (MAY_EXEC) is performed * against @idmap. * * If the name doesn't exist, an error is returned. @@ -3440,7 +3440,7 @@ EXPORT_SYMBOL(start_removing); * @parent: directory in which to prepare to create the name * @name: the name to be created * - * Locks are taken and a lookup in performed prior to creating + * Locks are taken and a lookup is performed prior to creating * an object in a directory. Permission checking (MAY_EXEC) is performed * against @idmap. * @@ -3469,7 +3469,7 @@ EXPORT_SYMBOL(start_creating_killable); * @parent: directory in which to find the name * @name: the name to be removed * - * Locks are taken and a lookup in performed prior to removing + * Locks are taken and a lookup is performed prior to removing * an object from a directory. Permission checking (MAY_EXEC) is performed * against @idmap. * @@ -3499,7 +3499,7 @@ EXPORT_SYMBOL(start_removing_killable); * @parent: directory in which to prepare to create the name * @name: the name to be created * - * Locks are taken and a lookup in performed prior to creating + * Locks are taken and a lookup is performed prior to creating * an object in a directory. * * If the name already exists, a positive dentry is returned. @@ -3522,7 +3522,7 @@ EXPORT_SYMBOL(start_creating_noperm); * @parent: directory in which to find the name * @name: the name to be removed * - * Locks are taken and a lookup in performed prior to removing + * Locks are taken and a lookup is performed prior to removing * an object from a directory. * * If the name doesn't exist, an error is returned. @@ -3543,11 +3543,11 @@ struct dentry *start_removing_noperm(struct dentry = *parent, EXPORT_SYMBOL(start_removing_noperm); =20 /** - * start_creating_dentry - prepare to create a given dentry - * @parent: directory from which dentry should be removed - * @child: the dentry to be removed + * start_creating_dentry - prepare to access or create a given dentry + * @parent: directory of dentry + * @child: the dentry to be prepared * - * A lock is taken to protect the dentry again other dirops and + * A lock is taken to protect the dentry against other dirops and * the validity of the dentry is checked: correct parent and still hashed. * * If the dentry is valid and negative a reference is taken and @@ -3580,7 +3580,7 @@ EXPORT_SYMBOL(start_creating_dentry); * @parent: directory from which dentry should be removed * @child: the dentry to be removed * - * A lock is taken to protect the dentry again other dirops and + * A lock is taken to protect the dentry against other dirops and * the validity of the dentry is checked: correct parent and still hashed. * * If the dentry is valid and positive, a reference is taken and base-commit: 89a312991dc6e638a36adc43ccb91dbc25504c04 --=20 2.50.0.107.gf914562f5916.dirty From nobody Sat Sep 26 03:10:50 2026 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (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 28EAF439F9E; Fri, 4 Sep 2026 21:53:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558814; cv=none; b=i84XPU66RRF/4UeU83UQERhZvWuRrTYDVTHch81IsRVe9cQTag8s7cR8vY9XGAV4SH7gZzFlQINQuUN58UAlzn3WOHFfhHpjob0XAs/xfR6mWZobqCbQeE3mJwrjljXkGwW9YSHYksX2pUswEiJ6VLR2XO6FTpwmbRnm8ySYMHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558814; c=relaxed/simple; bh=XwfTSvsAss395NbUmNfD0BvIpEUe2T4vCMZGNsmwnsQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KgVpRjpNScFYWOFWqK3EYtCt0Ym2tOZVPkXZ8FWkZkV8jf6ocAcQGd7YZC3TS3BxO1/c5Yxu+kxdeVG2LMnASquumE2bZbYEHAJ/d+S8/460y4aRclEeNqrv4D2gDyYHyg0Pvgwt6pWHDvFMBPvhffJviCJedfjMA0wJ7j6uviE= 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=HAozJU3D; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Sknuf1iI; arc=none smtp.client-ip=103.168.172.158 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="HAozJU3D"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Sknuf1iI" Received: from phl-compute-08.internal (phl-compute-08.internal [10.202.2.48]) by mailfhigh.phl.internal (Postfix) with ESMTP id 377341400156; Fri, 4 Sep 2026 17:53:30 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-08.internal (MEProxy); Fri, 04 Sep 2026 17:53:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ownmail.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:reply-to:subject:subject:to:to; s=fm1; t=1788558810; x=1788645210; bh=pwDhUtabD1EY8UJKERYdpDzwVgnQzJgdv/ipJhB6Ltg=; b= HAozJU3DaXrUtXPQnRY/mB00j8IVS4SMWu5hQqmSmBqPU2CDJCbLG6wi5pNBv5F6 fgIjp0JGE0xYplYU77DV8yWrKVpHoHif0ZkFqKeESMmUdM4AipDxgebkpSMvrQra mNQNnDaqtM1jAqU49xVeYsW1BFpP+H2bPxKay5qMzGO6mLDsiNwAHz9aCUNiyRvb cXytumgUSSPUQ801vdw33TE/n2NQjzI4Fa/39yDqsucWhkrQuJuN3CJ1quVUqs7V IlxuyTQoX1gHpmb+bPymAJ/XeH8+A/0GidVbi7F8Uvid3nAfSD+uxhCLMnTR4tbH RMrWq0ooPr5ptD5k4gJgxA== 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=1788558810; x=1788645210; bh=p wDhUtabD1EY8UJKERYdpDzwVgnQzJgdv/ipJhB6Ltg=; b=Sknuf1iIjcPX8CioY aqtLzHuiueIdawwyiS3QSvrPKK4cPA4SKesBn4EE4WGw1jpcZX5MmU1lQknueTXP f6TmzZ9gFarEKWaNg63r7Syt7qQZOAdmSo6tovc9lWudTXhQg+3cnETmMFV7MlrT NXp1AxLEJnip6mhZLFECxil6Ry3FdVML/VqKzLJKCby7cIae5VCNT3fuPIo6ngcr W3Yj5xy9ZBsUiOYVSTb59ZFiVUSVv4FdMpXt+OHzW2fRBGJXi/ep/gNRhrdfX/7A 1oBGdPMtSrWjisjV9DDZpE9r9j3gDqEhIMcfdgKs9FQTnd8o1aNugXWxu1fj0Jhy BLM/A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTE9kA3thUlpLT361si23coA65UhzUPhrTWwkKM78lnPGqsN4WqGhrX6sVxsTEwsLH ORMYgoSmolSLTX+O1vlWByuNkCl9wjBDZIO33pyh+0tWhR4K4noJM/+vI1MBmqcIftaS2b /GtiqOatuq21RBzGugW3uasufhqhKX8qbUnLt2Dldix1ZFEwWdsaAp+5wDCTunbmew5pzc xd+xD35a9GCDgNKa3CYep28eFOpAh1Fsh18RmdQxkxptLMj+Iewv6oaB6vjlrs4TcpQgo0 oinx301X3CEL9C1Yt9g+Z7sWJOv0dzlKXMlUgOscrJyVCHG9gHFPEU/kaA4ys8FbuoMDIl pZhYJ0WXjtNUlUhgv80JxjVZdF12mO3RBMsWFPrqWDm7Q+xMFfB2ADxNjdFyjWYPW9VMJK raVAak8HD+B81AJYeVy7vx5bi77nGvibFFZofjVQHYqP4rnQ+bgFlCnVuxqNv7CluU2AcK ggCj9S9GO13iyV6VUseaxeiwOdtjcKndElRhPolfDgmZNQ7MEiqG0xdRWPkrgrJauz0e5q bFwFbtzX2bk4WPvSAQQQEu2vLKA5VzDmN3nfrd4pKoorcwlWnDiK+w+oTNvWFKzhAlvKet ujrwvFMaRjHZHSR3h3TAHbX9xzj+tg4yP3xKw2fvusik8ozLU9s3cvTbfrag X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:27 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 2/7] VFS: enhance d_splice_alias() to handle hashed dentries Date: Sat, 5 Sep 2026 07:48:11 +1000 Message-ID: <20260904215142.1060510-3-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 We currently have three interfaces for attaching existing inodes to normal filesystems(*). - d_add() requires an unhashed or in-lookup dentry and doesn't handle splicing in case a directory already has dentry - d_instantiate() requires a hashed dentry, and also doesn't handle splicing. - d_splice_alias() requires unhashed or in-lookup and does handle splicing, and can return an alternate dentry. So there is no interface that supports both hashed and in-lookup, which is what ->atomic_open needs to deal with. Some filesystems check for in-lookup in their atomic_open and if found, perform a ->lookup and can subsequently use d_instantiate() if the dentry is still negative. Others d_drop() the dentry so they can use d_splice_alias(). This last will cause a problem for proposed changes to locking which require the dentry to remain hashed while an operation proceeds on it. There is also no interface which splices a directory (which might already have a dentry) to a hashed dentry. Filesystems which need to do this d_drop() first. Some filesystems (NFS) skip ->lookup processing for LOOKUP_CREATE|LOOKUP_EXCL which includes mknod, link, symlink etc. So these inode operations might get an unhashed or a hashed-negative dentry. There is no interface for instantiating these so again they need to unhash first (nfs_link) So with this patch d_splice_alias() can handle hashed, unhashed, or in-lookup dentries. This makes it suitable for ->lookup, ->atomic_open, and ->mkdir as well as others. As a side effect d_add() will also now handle hashed dentries, but I have plans to remove d_add() as there is no benefit having it as well as the others. Once updated to handle nr_dentry_negative as is required for hashed dentrties, __d_add() contains code that is identical to __d_instantiate(), so the former is changed to call the later so now: - d_add() calls __d_add() which hashes and might call __d_instantiate. - d_instantiate() calls __d_instantiate() with appropriate locks. It was suggested by Al Viro https://lore.kernel.org/all/20250813050717.GD222315@ZenIV/ that rather than allow d_splice_alias() to handle both hashed and unhashed, we should have a new d_splice_alias_hashed(). I chose not to follow this path because, as noted above, there are several cases where the filesystem has no a priori knowledge of the state of the dentry, and so would need if (d_unhashed(dentry)) alias =3D d_splice_alias(inode, dentry); else alias =3D d_splice_alias_hashed(inode, dentry); which is clumsy. Also I hope to minimise the distinction between hashed and in-lookup (they will both be hashed, just with different DCACHE_ENTRY_TYPE) and reduce the use of unhashed dentries. Unhashed dentries would only be created by d_alloc_name() and all of those are passed to d_make_persistent() (though configfs passes some to d_add(dentry, NULL) first!). So the use-case for d_splice_alias() on unhashed dentries would disappear. Note that d_make_persistent() already handles both hashed and unhashed dentries - just not in-lookup. * There is also d_make_persistent() for filesystems which are dcache-based and don't support mkdir, create etc, and d_instantiate_new() for newly created inodes that are still locked. Signed-off-by: NeilBrown --- Documentation/filesystems/vfs.rst | 4 ++-- fs/dcache.c | 30 ++++++++++++------------------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/= vfs.rst index d3a93eec3945..de8f8502056e 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -507,8 +507,8 @@ otherwise noted. dentry before the first mkdir returns. =20 If there is any chance this could happen, then the new inode - should be d_drop()ed and attached with d_splice_alias(). The - returned dentry (if any) should be returned by ->mkdir(). + should be attached with d_splice_alias(). The returned + dentry (if any) should be returned by ->mkdir(). =20 ``rmdir`` called by the rmdir(2) system call. Only required if you want diff --git a/fs/dcache.c b/fs/dcache.c index 1b1a81f10da6..fd74753e7715 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2168,7 +2168,6 @@ static void __d_instantiate(struct dentry *dentry, st= ruct inode *inode) * (or otherwise set) by the caller to indicate that it is now * in use by the dcache. */ -=20 void d_instantiate(struct dentry *entry, struct inode * inode) { BUG_ON(d_really_is_positive(entry)); @@ -2931,15 +2930,10 @@ static inline void __d_add(struct dentry *dentry, s= truct inode *inode, } if (unlikely(ops)) d_set_d_op(dentry, ops); - if (inode) { - unsigned add_flags =3D d_flags_for_inode(inode); - hlist_add_head(&dentry->d_alias, &inode->i_dentry); - raw_write_seqcount_begin(&dentry->d_seq); - __d_set_inode_and_type(dentry, inode, add_flags); - raw_write_seqcount_end(&dentry->d_seq); - fsnotify_update_flags(dentry); - } - __d_rehash(dentry); + if (inode) + __d_instantiate(dentry, inode); + if (d_unhashed(dentry)) + __d_rehash(dentry); if (dir) { end_dir_add(dir, n); __d_wake_in_lookup_waiters(dentry); @@ -3241,7 +3235,7 @@ struct dentry *d_splice_alias_ops(struct inode *inode= , struct dentry *dentry, if (IS_ERR(inode)) return ERR_CAST(inode); =20 - BUG_ON(!d_unhashed(dentry)); + BUG_ON(d_really_is_positive(dentry)); =20 if (!inode) goto out; @@ -3297,6 +3291,8 @@ struct dentry *d_splice_alias_ops(struct inode *inode= , struct dentry *dentry, * @inode: the inode which may have a disconnected dentry * @dentry: a negative dentry which we want to point to the inode. * + * @dentry must be negative and may be in-lookup or unhashed or hashed. + * * If inode is a directory and has an IS_ROOT alias, then d_move that in * place of the given dentry and return it, else simply d_add the inode * to the dentry and return NULL. @@ -3304,16 +3300,14 @@ struct dentry *d_splice_alias_ops(struct inode *ino= de, struct dentry *dentry, * If a non-IS_ROOT directory is found, the filesystem is corrupt, and * we should error out: directories can't have multiple aliases. * - * This is needed in the lookup routine of any filesystem that is exportab= le - * (via knfsd) so that we can build dcache paths to directories effectivel= y. + * This should be used to return the result of ->lookup() and to + * instantiate the result of ->mkdir(), is often useful for + * ->atomic_open, and may be used to instantiate other objects. * * If a dentry was found and moved, then it is returned. Otherwise NULL - * is returned. This matches the expected return value of ->lookup. + * is returned. This matches the expected return value of ->lookup and + * ->mkdir. * - * Cluster filesystems may call this function with a negative, hashed dent= ry. - * In that case, we know that the inode will be a regular file, and also t= his - * will only occur during atomic_open. So we need to check for the dentry - * being already hashed only in the final case. */ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) { --=20 2.50.0.107.gf914562f5916.dirty From nobody Sat Sep 26 03:10:50 2026 Received: from fout-a4-smtp.messagingengine.com (fout-a4-smtp.messagingengine.com [103.168.172.147]) (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 CFE45439916; Fri, 4 Sep 2026 21:53:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558819; cv=none; b=G7f9VQuhj7mU+ftWmFnUgLUx1T4ljtUePz+dr+a7HX56SvrJpRZl1KdtDWHwRet67ulJ5WT3KZAaASxsJcxTu294Cbk4oWFwtIgMDexjzLlqDEPyr43EVKDtP0VEuGyS3gHgsHqOALqHLsiiWMT72wfMNXmIfIizmM6rOQ3FL7U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558819; c=relaxed/simple; bh=litQKQpxq4Wvyjuf2fzuVAMeubOciQd5GfzX88tQytw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ae4CL7hoRdDBLpLiFjuktdUz9aKsZRSU/rHkeWRSniNfkD93VKffGZ7E1IovHSgx1nSORFsbrJlfyhS2TPnnfUDwpdWtOHK7t2Cv7lOk8e65Q15jvKacHMSLxZb8f3Wa8orqKgQYQSXgBUnrzvlf/VTUV771T5ZggChBAwKA3N0= 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=WqODwf97; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=fVxdUNRD; arc=none smtp.client-ip=103.168.172.147 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="WqODwf97"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="fVxdUNRD" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailfout.phl.internal (Postfix) with ESMTP id 8F844EC0148; Fri, 4 Sep 2026 17:53:35 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Fri, 04 Sep 2026 17:53:35 -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=1788558815; x=1788645215; bh=Kt2NwALlbn71BGQUotT5OMUi/Oh7eR7WXE5EosRsD0I=; b= WqODwf97e7In19o8nIsInTM6H+z5cECf4JUj9J68ccbgIm4l2qp1RqImoCMZ22O8 0DfkIEGVrvxL8QfQ1AHHmAvZj/OPpZJ2YHr4QjHZHfXvFO5ZAEWaU0i7pumB1FI6 aDV/Z73QdILOyPp+iNiOCJ7dr5uwOrRYv07Y1iiRD5kzwdCRlQZDLNVvrrIZG6VE P4Hx4Uw7Y6evdt4wESeuAPa4sbLe84qEi6KVHqnkGgeWPKILB4bUFmyLHAZ6cigZ 9mwK8k4nnIaf6lgVYxp7FXV2ck79py9DxukBXI78vs4Hg7lnG+Vfp77ePtSTwCvl 4LvtlMghU6MkHqwoznsxBw== 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=1788558815; x=1788645215; bh=K t2NwALlbn71BGQUotT5OMUi/Oh7eR7WXE5EosRsD0I=; b=fVxdUNRDFDNTkKUZV yolBALOlXorVh5oO8ibPITH4/3P0fu3f7lyYxXEBOG4ljLNOCf0Z1FH+ws3xpdjg 98noa1vdmW8ezNuxgwtbub4vDyCutv/qPyg3tY2UtPS9NMjV/HFTXmAf3f6lRxHe Rfhr9P8xhmWRn5qaNL0tdjDTh7/zkCbgoKou3xygu/JmmcZ4qFwyVQNixGKhUh3z ogBs/CGQdfoEc9m7VfTlDamaUOx+IkS5CtJI2mBOuIAAOFEm8syvvnbx7XMkj8u3 lBhNtRvHjl2sjxvMsqGPDJiaMs9tDrakeFluFug/9cz3HnnYtyrYJqCOgcCrejgd 60BrA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFDVljjZPAYZ1l/aqq4nrL+3Kba1UGdgNzRbLHxNyZsBntb6givVbdJfo5BU3j95t +UQU7WjR6Go54RULzYYdNoUTzLStmDkBzIg7iAUMGGPyun7cXaJ/tB+RDeFqAMJs98sAqA 8UTNhC/OQM/aHTCEgRGMWo/qNqW4Cm4ZpbUAGc1yB/wYZCmyUFIFjHNO+nBl6KHnpd3kh5 kJGEMNZuUD6j2jJVpJ5tURud5waXhGOgIEZWqqHFhojd6ln7NIlrB7SgqCD/laD7h+xaRU I5R2WpSXAH/sDdSGVPXGsuUa9Zu1lOQJK4tOelP1k+iwmt4tCWllwcYTI4lONAt5xo76Pq hlGh/72u4tuQRb17E5/sphiIlu48OG6JGAc3TOBAspDQXILE49eS1TSd6nMc8l97o++gQ2 Aiv0yLPpk+6R4pEpIjVQG8pKEN/R0nvb8n9kRsybpC0b6TvGf/3VxXKMmkSqccUSkMu6vz +TsTG3GDYGcCSKRN3Sa+LCCEQPEECHCnEibyH+vPHwjigVTYTLra81K3BlwWaVmo+8C5bo go3tDOOZzok7BSTz9JCqFW8eRxOcqeiOFW16c7aXJS3VtxpE8Eex/f8Ifd4/5NErDlxpG3 UEEEpUsYXCMV5jM+c+Ak6GLQPOMisiFS5aGcva/YsqIKGXeYmgCvpGbjByKA X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:32 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 3/7] VFS: introduce d_alloc_trylock() Date: Sat, 5 Sep 2026 07:48:12 +1000 Message-ID: <20260904215142.1060510-4-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 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_trylock() 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. Unlike d_alloc_parallel(), d_alloc_trylock() calculates the hash and performs a lookup before an allocation, as that is what all callers want. This is done using try_lookup_noperm(), necessitating the inclusion of namei.h in dcache.c. Signed-off-by: NeilBrown --- fs/dcache.c | 81 ++++++++++++++++++++++++++++++++++++++++-- include/linux/dcache.h | 1 + 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index fd74753e7715..43149c7849d9 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "internal.h" #include "mount.h" =20 @@ -2756,8 +2757,16 @@ static void d_wait_lookup(struct dentry *dentry) } } =20 -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 =3D name->hash; struct hlist_bl_head *b =3D in_lookup_hash(parent, hash); @@ -2830,6 +2839,12 @@ struct dentry *d_alloc_parallel(struct dentry *paren= t, spin_unlock(&dentry->d_lock); goto retry; } + if (unlikely(how =3D=3D ALLOC_PARA_FAIL)) { + /* mustn't wait for concurrent lookup to complete */ + spin_unlock(&dentry->d_lock); + dput(new); + return ERR_PTR(-EWOULDBLOCK); + } /* * somebody is likely to be still doing lookup for it; * pin it and wait for them to finish @@ -2863,8 +2878,70 @@ struct dentry *d_alloc_parallel(struct dentry *paren= t, 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); =20 +/** + * d_alloc_trylock() - 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_trylock() + * 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 need not already have ->hash set. + * + * Returns: the dentry, whether found or allocated, or an error + * %-ENOMEM, %-EWOULDBLOCK, %-EACCES (for a bad name) or + * anything returned by ->d_hash(). + */ +struct dentry *d_alloc_trylock(struct dentry *parent, + struct qstr *name) +{ + struct dentry *de; + + de =3D try_lookup_noperm(name, parent); + if (!de) + de =3D __d_alloc_parallel(parent, name, ALLOC_PARA_FAIL); + return de; +} +EXPORT_SYMBOL(d_alloc_trylock); + /* * Move dentry from in-lookup state to busy-negative one. * diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 4b1ff99608e0..7afe16d4664d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -257,6 +257,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_trylock(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 *, --=20 2.50.0.107.gf914562f5916.dirty From nobody Sat Sep 26 03:10:50 2026 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (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 B3A3343B3CE; Fri, 4 Sep 2026 21:53:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558823; cv=none; b=u/VLMKd6qiy/EqFoXgNNcXW+zgLL2e9TagPRlKLUEHLg4bh0lyZOwcwdj0AvhHFoxnbgfk5sDUps0gQYHuUCqv8FwmOd1tI3Sgom076WZjsI6Z8QEb2P1tG2ZQvbDQNhXit1lJ7LiCUHE9J/1fIr03fxsJp8/07krA69xb9ww/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558823; c=relaxed/simple; bh=ZQvaC8dFecVpds878fbdcXZVKMpD3woowzwCpCb4u9Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RwAVz8sAStEiVOwkeIJkpa2nt3fL0vQ+aS/ChVBOtxGVnPDSzl7Dr9Z+bbf/TLXwpB0NdheOLFwpFREu0NVgV8a6G8xfkI965K5XbUG2wluTbj0Rhiy1YKFuBtCipErtsFvzW2EFf5Td5z43BqyrR02XuvFiJ2IsFZAAVkCCeqM= 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=UyLQL+cW; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Q2RuxB6F; arc=none smtp.client-ip=103.168.172.158 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="UyLQL+cW"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Q2RuxB6F" Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfhigh.phl.internal (Postfix) with ESMTP id B5FE11400012; Fri, 4 Sep 2026 17:53:40 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-04.internal (MEProxy); Fri, 04 Sep 2026 17:53:40 -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=1788558820; x=1788645220; bh=C5zeecdiXDFUM4KIYX///uvKg7YTspSiWbXqcfJhCrk=; b= UyLQL+cWCZwggjN5YaZkyHdTzwikg4JPPRHAMJUpNPx2YJFfcrqLL6w28LHDoGD5 BUmfkVQK9IZ2RjXkyQ6uHE704A9lbt0RxAtTgHGkGtIZF8ApqGcgN6kyzw9MC1uX ON8kCkoKdbx0WLKIs59rc/bBhfwMh4di2+dvX57r3bH6eWGxHU3X07u7FATNLywL 1U6AMTkh/Vufh0OdTvAprIxscLzwqmCAEItPfMxNAY+K09ldMo9KCRuK8OmtjuPk PdqAM7nEYYGMbm4MzyxvQunhSTDzXibBqcCrNeLkY6yG8uSyCjkyRHKuIHCHMYlY B+f9umkkT7Qih+ocViOazA== 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=1788558820; x=1788645220; bh=C 5zeecdiXDFUM4KIYX///uvKg7YTspSiWbXqcfJhCrk=; b=Q2RuxB6FISo63kPx/ wGgxNxhjwQMn3zmPNyf8ZjJ6+YNncPuB1yy9zQABjYWsuOlmRYfEuT35Q6xMljUs tqv8cesRTxMOxPiPdAaW8RiE8/ZrTj/ChliIDEDdceR7STNz1GNuHg4PKW95pdsA O5Z/843OaxYtBXyoRaiB4cvPA0mnikZN5exvM0tWhyFLBP8WV0YGruOCfwLToHw7 b0eJPOhmwXqLMLwXQAfOYGV+UStI3WHdP63yhkXx+I1Dpm0JqVz2UYdh4gD6zkik 8BotGvRQx5/H0Yn/WCA4JqQOLjhB1fkFXcM98p6Z0bU3tUPLVcMOcBpeBQBAt+f4 ooWvw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFiAOSj3LUvbMyTizwFG8S0Z77/oyH2J2g/uycK/oy+xjfWiF27uJMr9H7g3QAOe/ XYsAVApeSvodxh0nJXqm+2ih0Zs0UFQnZPCwAsQgYJh4bKlGJCxAFvJ28DiVFZcSJ1v4SN eyofj/RHn+C6wmmzYsHzdQWXaMLzQ5qjTmyCk6u6FNaJzHTyX3mRZJWbQlLecUBL+8R9uF oXPgTkabZ8M+0wwMRuzFqlmpEXjU77OKNTiGAEqZPKyJRGqwLIf4volXBc3DcquHRoaijA Ked+eKVy/8jzE5J4p8iliYop7ExvhRi8QZDkpUnJW3mwzA4SzmVm5+ia17mBgI6SpbQsZZ ROG3vVGdz0eExPr9nwP/a7Ac0MWGotd3LzCIrgaWYQDZ9HkQXPh8G59X6mtm0OB3ydRSVW N981RvJoaUo0wpIiZXWImf9hmQFGbQJMzSLaVAGz6TmWtZ3xQCQzd12YZ9uhO53HRUO+SV iTeCjsFuybjku9EIoMb5UbnsUaBJCkoho+ubDlYisJGK5azdcTIvPpXTVqf1RBePcLLjX6 nJnLuMD8gNiGPk/RkiaDefEmzTXgUBLaWHyLXsOhwKZaXyYg6FW2aw9qQxs/A6n7/f1X9y X472xqcA63bM7259sZ3ZhH+SiY2m08WudF2gmzaID02FTrg9CtByjRjymkWg X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:38 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 4/7] VFS: add d_duplicate() Date: Sat, 5 Sep 2026 07:48:13 +1000 Message-ID: <20260904215142.1060510-5-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 Occasionally a single operation can require two sub-operations on the same name, and it is important that a d_alloc_parallel() (once that can be run unlocked) does not create another dentry with the same name between the operations. Two examples: 1/ rename where the target name (a positive dentry) needs to be "silly-renamed" to a temporary name so it will remain available on the server (NFS and AFS). Here the same name needs to be the subject of one rename, and the target of another. 2/ rename where the subject needs to be replaced with a white-out (shmemfs). Here the same name need to be the subject of a rename and the target of a mknod() In both cases the original dentry is renamed to something else, and a replacement is instantiated, possibly as the target of d_move(), possibly by d_instantiate(). Currently d_alloc() is used to create the dentry and the exclusive lock on the parent ensures no other dentry is created. When d_alloc_parallel() is moved out of the parent lock, this will no longer be sufficient. In particular if the original is renamed away before the new is instantiated, there is a window where d_alloc_parallel() could create another name. "silly-rename" does work in this order. shmemfs whiteout doesn't open this hole but is essentially the same pattern and should use the same approach. The new d_duplicate() creates an in-lookup dentry with the same name as the original dentry, which must be hashed. There is no need to check if an in-lookup dentry exists with the same name as d_alloc_parallel() will never try add one while the hashed dentry exists. Once the new in-lookup is created, d_alloc_parallel() will find it and wait for it to complete, then use it. Signed-off-by: NeilBrown --- fs/dcache.c | 51 ++++++++++++++++++++++++++++++++++++++++++ include/linux/dcache.h | 1 + 2 files changed, 52 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 43149c7849d9..cbd5738de168 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2000,6 +2000,57 @@ struct dentry *d_alloc(struct dentry * parent, const= struct qstr *name) } EXPORT_SYMBOL(d_alloc); =20 +/** + * d_duplicate - duplicate a dentry for combined atomic operation + * @dentry: the dentry to duplicate + * + * Some rename operations need to be combined with another operation + * inside the filesystem. + * 1/ A cluster filesystem when renaming to an in-use file might need to + * first "silly-rename" that target out of the way before the main rename + * 2/ A filesystem that supports white-out might want to create a whiteout + * in place of the file being moved. + * + * For this they need two dentries which temporarily have the same name, + * before one is renamed. d_duplicate() provides for this. Given a + * positive hashed dentry, it creates a second in-lookup dentry. + * Because the original dentry exists, no other thread will try to + * create an in-lookup dentry, so there can be no race in this create. + * + * The caller should d_move() the original to a new name, often via a + * rename request, and should call d_lookup_done() on the newly created + * dentry. If the new is instantiated then the old MUST either be moved + * or dropped. + * + * Parent must be locked. + * + * Returns: an in-lookup dentry, or -ENOMEM. + */ +struct dentry *d_duplicate(struct dentry *dentry) +{ + unsigned int hash =3D dentry->d_name.hash; + struct dentry *parent =3D dentry->d_parent; + struct hlist_bl_head *b =3D in_lookup_hash(parent, hash); + struct dentry *new =3D __d_alloc(parent->d_sb, &dentry->d_name); + + if (unlikely(!new)) + return ERR_PTR(-ENOMEM); + + new->d_flags |=3D DCACHE_PAR_LOOKUP; + spin_lock(&parent->d_lock); + new->d_parent =3D dget_dlock(parent); + hlist_add_head(&new->d_sib, &parent->d_children); + if (parent->d_flags & DCACHE_DISCONNECTED) + new->d_flags |=3D DCACHE_DISCONNECTED; + spin_unlock(&parent->d_lock); + + hlist_bl_lock(b); + hlist_bl_add_head(&new->d_in_lookup_hash, b); + hlist_bl_unlock(b); + return new; +} +EXPORT_SYMBOL(d_duplicate); + struct dentry *d_alloc_anon(struct super_block *sb) { return __d_alloc(sb, NULL); diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 7afe16d4664d..2b7d99ec9306 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -259,6 +259,7 @@ 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_trylock(struct dentry *, struct qstr *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); +struct dentry *d_duplicate(struct dentry *dentry); /* weird procfs mess; *NOT* exported */ extern struct dentry * d_splice_alias_ops(struct inode *, struct dentry *, const struct dentry_operations *); --=20 2.50.0.107.gf914562f5916.dirty From nobody Sat Sep 26 03:10:50 2026 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (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 EC74D426438; Fri, 4 Sep 2026 21:53:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558828; cv=none; b=ZHf2+8MfZ65ZsVU1veypAm701dB4BUNXODGyplWW9BJGHFLxqJkNBk5yycgYjZnI10P9AfPzbdkSamEbNzS8BYZyQnKi7kLwJ0jFEnYmQi6zDVdxXa0+AZ3YwyQlJcq8vJkQLF3WRbmM/yhUeZpAeBzLWb0deFL21QENWR63Cgc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558828; c=relaxed/simple; bh=DKn3mH6e5UW5ZKmdIoCgZcupxdHkXvCEbmNshn0Ohwo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J7upI9b8khvARBXO4X5tHPH+obd1TDq09U6svZODDyNmpTpPJQ0AAKWHJy02ZSRbBgYgFvPRHv62ggxASnpkajrb/879YOr8/Jcmd9kNN6v8pUsrZ9TyW4iOiFKizp9uMXi5wTp6YmdlPpZkv9aowkVhdKutFyRYBWn98vb5Nro= 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=O/PUQwGC; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ShGahM1R; arc=none smtp.client-ip=103.168.172.158 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="O/PUQwGC"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ShGahM1R" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailfhigh.phl.internal (Postfix) with ESMTP id 0AF471400156; Fri, 4 Sep 2026 17:53:46 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Fri, 04 Sep 2026 17:53:46 -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=1788558826; x=1788645226; bh=x76cWHKe6pufS6Tmmh9Hg+tYaejNmWztL1qC220hXPo=; b= O/PUQwGCcCBQMAHLIb08w2AdXwZhTJUorguAwS3+iJrgFPZrWmxhtCFh3gQW51Pc DRMaWfTllRofe7pzTDlIGLM08elnW6BJiQMdCBniV0rOcNnpq0NCluh+fIixbSer DVs58A2w05yz/qxhPWJwrgvSE1YWOzzplyyKuybGGtRJebJMPRagKtUt3KjjuqlT 8XQIwIImcYU1ww42P5pae3S8PLNdLPrUkautSfwfBalyZd3mKseGoMq4JFh6XVpR IEuBDsDk8LdHzA2PQ0H2+MfxGtNQoDDDXFBKH5rK/M7JCIIizN4hr5D9InM7/0NZ kNGFsgMj47x1dcrYkfXWKA== 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=1788558826; x=1788645226; bh=x 76cWHKe6pufS6Tmmh9Hg+tYaejNmWztL1qC220hXPo=; b=ShGahM1RL2AY4v70k x+xAB4QCU2bGDAyZEored5cX/qxzTfOy1caRdMRDQ4qWAvM4JW93XUtAGrhR/gMJ O1p24JB7Js5+bG5a6MI7Ck4hiF1EwBPdA/bilro2u/0h/nUvGxYOMZYCpHaqcwOk m0or0LpJuFKVOF8X8oVQg2mztgEfLVUme+KO33Cp5njfrvnK95kmraBQ67xTcoES brpEk1g8uhZE5CSdTZxF7b6ke8WbeF0mNzQINI6weiiUOQeYD81dF+HH0v2dKrId T/AY0S9Apqo1mhFi72p8fz2BaecFdZzeXbb1BDFYsA8u76typeRJRtQjPOtgU+Zf Y9ogg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFiAOSj3LUvbMyTizwFG8S0Z77/oyH2J2g/uycK/oy+xjfWiF27uJMr9H7g3QAOe/ XYsAVApeSvodxh0nJXqm+2ih0Zs0UFQnZPCwAsQgYJh4bKlGJCxAFvJ28DiVFZcSJ1v4SN eyofj/RHn+C6wmmzYsHzdQWXaMLzQ5qjTmyCk6u6FNaJzHTyX3mRZJWbQlLecUBL+8R9uF oXPgTkabZ8M+0wwMRuzFqlmpEXjU77OKNTiGAEqZPKyJRGqwLIf4volXBc3DcquHRoaijA Ked+eKVy/8jzE5J4p8iliYop7ExvhRi8QZDkpUnJW3mwzA4SzmVm5+ia17mBgI6SpbQspn KOe1ipPvDb1dZcGdAxFpFgmtv2gIpIjaL+xSGRg8zmijYpytkhaOM24PfPWocRKSaqDsQE DSNdCbjO/5pyusvzxyzKyH21CrHy1U3KZ35FyuLclBUYC0vupR6nRRD6zTQC4sgILITPmH UqaZHbzj0H6wJ3ksSKCLZOvAcJlKsMofbRL1mJfPFYajkGiQTZBqpMyAm4yNw1orJbRluU whmjuIcisBYvApjNIiSqOhwTBeBltl83AbNKrA17/sG88V8ypgQFGDIIMfazC4JRT4o+w7 PzMIJ65MYyczH7KFBjNWmnQGKhocuDnom5ZBYfgjEPpe3PWA3SVF9FQSt7iA X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:43 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 5/7] VFS: Add LOOKUP_SHARED flag. Date: Sat, 5 Sep 2026 07:48:14 +1000 Message-ID: <20260904215142.1060510-6-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 Some ->lookup handlers will need to drop and retake the parent lock, so they can safely use d_alloc_parallel(). ->lookup can be called with the parent lock either exclusive or shared. A new flag, LOOKUP_SHARED, tells ->lookup how the parent is locked. This is rather ugly, but will be gone soon after we move d_alloc_parallel() out of the directory lock as ->lookup() will *always* called with a shared lock on the parent. Signed-off-by: NeilBrown --- fs/namei.c | 20 +++++++++++--------- include/linux/namei.h | 3 ++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 8d8d2af185f1..e978a75eb8a1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1933,7 +1933,7 @@ static noinline struct dentry *lookup_slow(const stru= ct qstr *name, struct inode *inode =3D dir->d_inode; struct dentry *res; inode_lock_shared(inode); - res =3D __lookup_slow(name, dir, flags); + res =3D __lookup_slow(name, dir, flags | LOOKUP_SHARED); inode_unlock_shared(inode); return res; } @@ -1947,7 +1947,7 @@ static struct dentry *lookup_slow_killable(const stru= ct qstr *name, =20 if (inode_lock_shared_killable(inode)) return ERR_PTR(-EINTR); - res =3D __lookup_slow(name, dir, flags); + res =3D __lookup_slow(name, dir, flags | LOOKUP_SHARED); inode_unlock_shared(inode); return res; } @@ -4440,12 +4440,14 @@ static struct dentry *lookup_open(struct nameidata = *nd, struct file *file, int error, create_error; umode_t mode; bool got_write; + unsigned int shared_flag; =20 retry: open_flag =3D op->open_flag; got_write =3D false; mode =3D op->mode; create_error =3D 0; + shared_flag =3D (open_flag & O_CREAT) ? 0 : LOOKUP_SHARED; =20 if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) { got_write =3D !mnt_want_write(nd->path.mnt); @@ -4454,10 +4456,10 @@ static struct dentry *lookup_open(struct nameidata = *nd, struct file *file, * a different error; we'll be dropping this one anyway. */ } - if (open_flag & O_CREAT) - inode_lock(dir_inode); - else + if (shared_flag) inode_lock_shared(dir_inode); + else + inode_lock(dir_inode); =20 if (unlikely(IS_DEADDIR(dir_inode))) { dentry =3D ERR_PTR(-ENOENT); @@ -4526,7 +4528,7 @@ static struct dentry *lookup_open(struct nameidata *n= d, struct file *file, =20 if (d_in_lookup(dentry)) { struct dentry *res =3D dir_inode->i_op->lookup(dir_inode, dentry, - nd->flags); + nd->flags | shared_flag); d_lookup_done(dentry); if (unlikely(res)) { if (IS_ERR(res)) { @@ -4574,10 +4576,10 @@ static struct dentry *lookup_open(struct nameidata = *nd, struct file *file, if (file->f_mode & FMODE_OPENED) fsnotify_open(file); } - if ((open_flag & O_CREAT) || create_error) - inode_unlock(dir_inode); - else + if (shared_flag) inode_unlock_shared(dir_inode); + else + inode_unlock(dir_inode); =20 if (got_write) mnt_drop_write(nd->path.mnt); diff --git a/include/linux/namei.h b/include/linux/namei.h index 86d657b24fc6..65f0f5712885 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -32,8 +32,9 @@ enum { MAX_NESTED_LINKS =3D 8 }; #define LOOKUP_CREATE BIT(17) /* ... in object creation */ #define LOOKUP_EXCL BIT(18) /* ... in target must not exist */ #define LOOKUP_RENAME_TARGET BIT(19) /* ... in destination of rename() */ +#define LOOKUP_SHARED BIT(20) /* Parent lock is held shared */ =20 -/* 4 spare bits for intent */ +/* 3 spare bits for intent */ =20 /* Scoping flags for lookup. */ #define LOOKUP_NO_SYMLINKS BIT(24) /* No symlink crossing. */ --=20 2.50.0.107.gf914562f5916.dirty From nobody Sat Sep 26 03:10:50 2026 Received: from fout-a4-smtp.messagingengine.com (fout-a4-smtp.messagingengine.com [103.168.172.147]) (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 45A0C43D503; Fri, 4 Sep 2026 21:53:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558834; cv=none; b=V0R14Lakq7TWtIvvANhPw8sig1SePJFEOfz11glag69gecPkyOhYdUwii3ldcfUdPPT+JJK12NUhtYE4B7buM2SRsrYdk59SzeGjvHrYtjD/uY/F6W2BaI7+h4LmcUoSgrGCyBPgVSet6v72Ok6VyC0tPsxYiyUe9CcHd1e2wik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558834; c=relaxed/simple; bh=QyziwjqPMuKUE0Ywdu8lOJLdi6iNAo/ZH9vHAtT5uy4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ctLC3kT3jY2m7zhSQWpsoIkmKrGX7ouCWnakDe/zAtd1dVKzMcAsSXJHhUu4rlNsj/LHo0bvnrx9sSKcwwhbstude7xVzny2eH/RpUUyQ6seB1E55wDWQhBwUJ1UO8DS67CNdcUnR8PYpWGrZcw4odYsIQ2zOXj/mPmnmeQuu5E= 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=nhrta9X7; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Hrwp4K6u; arc=none smtp.client-ip=103.168.172.147 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="nhrta9X7"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Hrwp4K6u" Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailfout.phl.internal (Postfix) with ESMTP id 406AFEC0148; Fri, 4 Sep 2026 17:53:51 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-05.internal (MEProxy); Fri, 04 Sep 2026 17:53: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=fm1; t=1788558831; x=1788645231; bh=BM84miZIdMOU+h52rKqAXVXjLVrvMNKt0AXMbFVF+8k=; b= nhrta9X7GX0M3ZwZ3XCrXHXNOs+HxbD5/C/9z9wpWZjBnYRhHbHq4kh9zwiyG6kH +XUIqLZ1MqbM1WkrjPY1Ffo0b70lGymj2bzZ4qak+fkww8RCTWzEDZ3mZcZJMBrs Hka5/1d7iruC9GNXx9DfegQNFaOA9OgRZ+2o31uBBGEGe1iFByOLHkpfAb1k6Cq2 f2sgZ1U/7pFuaYicf4ruPYmaBD2H89P2Hyv2oEsmdg0IPBffiK7O0DT7w5ygt5F0 QONTqrhlUt1IHmka/Fxen3dysLhnSWo8wlHyCVleBHaQ62CTJiXtowwFRnzMzixp QoRlbqo5oAcwJ6/rFlvr1Q== 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=1788558831; x=1788645231; bh=B M84miZIdMOU+h52rKqAXVXjLVrvMNKt0AXMbFVF+8k=; b=Hrwp4K6u3j5crd1pZ VlVZwVML3G/CcKPDYRlim35qLemloeCZD/6lcOh+o8wOiw3EY5iPGjJ3/e2kDlpu 0XJse7DFWJod7HvKF9ffN5rIs3+6X2ORTQh7uU8VpxrTteaNDNn715MLY5svwXdY 7mgknh7PBLRS+ND+mOTWkQJf4+uB9pdzOZZoR0dA9tOvMzT5Sn4aKq7GsmEcjFgN 1/DQcVapAQbkmThRdCenV/hCOEhPff4bnOjsI8E6AFuiIWnPQBWxusd48Y9TTXxB rp2QSfStR22xOx48vo8aFpLashoJEwjiS4S2I9/h6Vp64qdON03P+7O75APIq5CL xHu0w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFDVljjZPAYZ1l/aqq4nrL+3Kba1UGdgNzRbLHxNyZsBntb6givVbdJfo5BU3j95t +UQU7WjR6Go54RULzYYdNoUTzLStmDkBzIg7iAUMGGPyun7cXaJ/tB+RDeFqAMJs98sAqA 8UTNhC/OQM/aHTCEgRGMWo/qNqW4Cm4ZpbUAGc1yB/wYZCmyUFIFjHNO+nBl6KHnpd3kh5 kJGEMNZuUD6j2jJVpJ5tURud5waXhGOgIEZWqqHFhojd6ln7NIlrB7SgqCD/laD7h+xaRU I5R2WpSXAH/sDdSGVPXGsuUa9Zu1lOQJK4tOelP1k+iwmt4tCWllwcYTI4lONAt5xo76VK ZbQgvL7/1f8FZ6kq8yTsgb2Y+kN/+A7R9zGfLM2zvYWA+LdZ41luRJh2lPVylusqyP5aBh IR3RAWxfhpP/4A4ZbYSFCly023+qulKqlDxnXdpdtzF51nhmFjuv/LL+PZy/4+iIxG+W6X v1o0rr4V5gLZeuy3O9FgIk00V8pfVBnG6c0qhTQ8y9f5NCK5JA/3dXLSKP7zz8Nbp/nlVm qmkwdc2BwJlpynoGFR9v8zCMo/m1Ci56SDJMCJMKh8SZXRDWedTMgS2pMIhClgTpyoZQMr xEm1oAVcIUHr8cLCiPsYt9m/4DyyfLgt87YdFQZ/FxfuZF7cPHqlqMDXQJ9Q X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:48 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 6/7] VFS: add lockdep monitoring of DCACHE_PAR_LOOKUP lock. Date: Sat, 5 Sep 2026 07:48:15 +1000 Message-ID: <20260904215142.1060510-7-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 DCACHE_PAR_LOOKUP acts like a lock in that threads can block waiting for it to clear. As we plan to make changes to lock order for this lock, teach lockdep to monitor it so as to help detect bugs early. As NFS allocates an in-lookup dentry to unlink a silly-renamed file, and completes the lookup in a different thread, we need interfaces to release and the acquire ownership of the lock. This avoids lockdep complaining that a lock is still held on return to user-space. Signed-off-by: NeilBrown --- fs/dcache.c | 15 +++++++++++++++ fs/nfs/unlink.c | 3 +++ include/linux/dcache.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index cbd5738de168..83790c7a4dee 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1901,6 +1901,7 @@ EXPORT_SYMBOL(d_invalidate); =20 static struct dentry *__d_alloc(struct super_block *sb, const struct qstr = *name) { + static struct lock_class_key __lookup_key; struct dentry *dentry; char *dname; int err; @@ -1958,6 +1959,8 @@ static struct dentry *__d_alloc(struct super_block *s= b, const struct qstr *name) dentry->waiters =3D NULL; INIT_HLIST_NODE(&dentry->d_sib); =20 + lockdep_init_map(&dentry->lookup_map, "DCACHE_PAR_LOOKUP", &__lookup_key,= 0); + if (dentry->d_op && dentry->d_op->d_init) { err =3D dentry->d_op->d_init(dentry); if (err) { @@ -2037,6 +2040,7 @@ struct dentry *d_duplicate(struct dentry *dentry) return ERR_PTR(-ENOMEM); =20 new->d_flags |=3D DCACHE_PAR_LOOKUP; + lock_map_acquire_try(&new->lookup_map); spin_lock(&parent->d_lock); new->d_parent =3D dget_dlock(parent); hlist_add_head(&new->d_sib, &parent->d_children); @@ -2801,6 +2805,15 @@ static inline void end_dir_add(struct inode *dir, un= signed int n) static void d_wait_lookup(struct dentry *dentry) { if (likely(d_in_lookup(dentry))) { + /* + * Tell lockdep we will wait for the lookup lock, after + * dropping ->d_lock, but won't actually take it. + */ + spin_release(&dentry->d_lock.dep_map, _THIS_IP_); + lock_map_acquire(&dentry->lookup_map); + lock_map_release(&dentry->lookup_map); + spin_acquire(&dentry->d_lock.dep_map, 0, 1, _THIS_IP_); + dentry->d_flags |=3D DCACHE_LOOKUP_WAITERS; wait_var_event_spinlock(&dentry->d_flags, !d_in_lookup(dentry), @@ -2923,6 +2936,7 @@ struct dentry *__d_alloc_parallel(struct dentry *pare= nt, } hlist_bl_add_head(&new->d_in_lookup_hash, b); hlist_bl_unlock(b); + lock_map_acquire_try(&new->lookup_map); return new; mismatch: spin_unlock(&dentry->d_lock); @@ -3021,6 +3035,7 @@ static void __d_lookup_unhash(struct dentry *dentry) b =3D in_lookup_hash(dentry->d_parent, dentry->d_name.hash); hlist_bl_lock(b); dentry->d_flags &=3D ~DCACHE_PAR_LOOKUP; + lock_map_release(&dentry->lookup_map); __hlist_bl_del(&dentry->d_in_lookup_hash); hlist_bl_unlock(b); dentry->waiters =3D NULL; diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index b57cfaa4d516..c8d712204e64 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -67,6 +67,7 @@ static void nfs_async_unlink_release(void *calldata) struct super_block *sb =3D dentry->d_sb; =20 up_read_non_owner(&NFS_I(d_inode(dentry->d_parent))->rmdir_sem); + d_lookup_acquire(dentry); d_lookup_done(dentry); nfs_free_unlinkdata(data); dput(dentry); @@ -159,6 +160,8 @@ static int nfs_call_unlink(struct dentry *dentry, struc= t inode *inode, struct nf return ret; } data->dentry =3D alias; + d_lookup_release(alias); + nfs_do_call_unlink(inode, data); return 1; } diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 2b7d99ec9306..e7e3ef05313b 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -116,6 +116,8 @@ struct dentry { * possible! */ =20 + /* lockdep tracking of DCACHE_PAR_LOOKUP locks */ + struct lockdep_map lookup_map; struct list_head d_lru; /* LRU list */ struct hlist_node d_sib; /* child of parent list */ struct hlist_head d_children; /* our children */ @@ -554,6 +556,36 @@ static inline int simple_positive(const struct dentry = *dentry) =20 unsigned long vfs_pressure_ratio(unsigned long val); =20 +/** + * d_lookup_release - release ownership of DCACHE_PAR_LOOKUP lock + * @dentry: dentry that is locked + * + * If an in-lookup dentry is to be passed to another thread which + * will drop the in-lookup lock, then d_lookup_release() must be called + * to tell lockdep that this thread no lock holds the lock. The + * thread that receives the lock must call d_lookup_acquire() to + * acquire the lock. + */ +static inline void d_lookup_release(struct dentry *dentry) +{ + if (d_in_lookup(dentry)) + lock_map_release(&dentry->lookup_map); +} + +/** + * d_lookup_acquire - acquire ownership of DCACHE_PAR_LOOKUP lock + * @dentry: dentry that is locked + * + * If an in-lookup dentry was passed to this thread, the + * d_lookup_acquire() must be called to tell lockdep that this + * thread now owns the DCACHE_PAR_LOOKUP lock. + */ +static inline void d_lookup_acquire(struct dentry *dentry) +{ + if (d_in_lookup(dentry)) + lock_map_acquire_try(&dentry->lookup_map); +} + /** * d_inode - Get the actual inode of this dentry * @dentry: The dentry to query --=20 2.50.0.107.gf914562f5916.dirty From nobody Sat Sep 26 03:10:50 2026 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (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 8209642E429; Fri, 4 Sep 2026 21:53:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558839; cv=none; b=fHfNKn7IEBVIimODG8cNMbFr484COPeQCVM08z2fz7mmxyiC6Sew0TqNeCQLOM7/rjR0WYAzMfziABugxy1yOq8uHEaKFlaIzhOi0SHLpSYkYQO/w/0nvwVciC0N65P7VNCYXKGJbSo78j+YD7u0nGVMX6xIsxT7ONskxW+DFjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788558839; c=relaxed/simple; bh=aUs/PFLLTaGein3PyaTaOoqZxfDY7ORzzk9KelrvCqo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uwVkQ+xQmdyE9kEbHLiup1gQGXmJZdAt/oLdUhJp8aIgLZa3kVwObxpCXDC7wczv1kHqBW9tXhdJFYjzvVSwEAcSQ39CmcnrSChC+RssSCz/2RD8eFXgPmog1lzWY7mqkwfTJvuIfugnE8XiPOQlP6HY6/9Ape1mp7iNCw3RC5s= 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=COanBLnm; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=NvXfjivQ; arc=none smtp.client-ip=103.168.172.158 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="COanBLnm"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="NvXfjivQ" Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailfhigh.phl.internal (Postfix) with ESMTP id 5FC891400156; Fri, 4 Sep 2026 17:53:56 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-05.internal (MEProxy); Fri, 04 Sep 2026 17:53: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=fm1; t=1788558836; x=1788645236; bh=wj/MnL34RixKciPgZi/7laRXXNimZ5XfwnqNuzhacfk=; b= COanBLnmXJBIoT4hDX+ScO9r7qdGdcBWmGAgc7K6vQw37b7pCmWtNpTuSW//1Z3y itNxaevYlAt9zrW1t1ZdP+ttLh72ThRTdKNE6eEtzdRwMUq3K3frhlSaTXE3z2AZ YwBIlc9sCBnjm37cRpNgn7z2T9dWy6R79YijSJipS1FZkIBPfBqbZUmQ0NXLR77L YUJSj9IYPR9Jztln+bi3wqg5NPcenCh6n6NjrGYMx/fQXlBJTCwbDdPSnGEBAStW /Q+nsawOmJl9Y9UuD1h82EahTtiSQr2BkBAfrw5+MFULVMGcl7/f50nYpdiBJtP5 SHMoP1uQ9R0ZJ8orCyMatw== 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=1788558836; x=1788645236; bh=w j/MnL34RixKciPgZi/7laRXXNimZ5XfwnqNuzhacfk=; b=NvXfjivQbyX1+xS3v 7k91TGS0rsUcyjxGrgYuZbdnTwqU/Pdk8gweYzWYT/4+r6LsBUTshJOszLurUDLa mB7K1+GNLJVPHP/eYejpcCc8Oy/yXrcP8sJvjw8aTnb0uYIQr4sfT2PnSOReLWlY /cCuKrlwt9pjZV9ascA5M0xWm9yp2UzB3Jjso1NeImSrvVgEau95vBTJM1O7VNar bKcczJMCFusdHf93Z1veM/NOhk3/VdTqUnAIo29vlwhVr1kFeGXPAyeXIuaqylwK yQenLPb/17/Qtma27402ngz+8j8EXVHKNoif0EsFFMVt6fNNZ1YFUyJBd58iLuwH kifpw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTFiAOSj3LUvbMyTizwFG8S0Z77/oyH2J2g/uycK/oy+xjfWiF27uJMr9H7g3QAOe/ XYsAVApeSvodxh0nJXqm+2ih0Zs0UFQnZPCwAsQgYJh4bKlGJCxAFvJ28DiVFZcSJ1v4SN eyofj/RHn+C6wmmzYsHzdQWXaMLzQ5qjTmyCk6u6FNaJzHTyX3mRZJWbQlLecUBL+8R9uF oXPgTkabZ8M+0wwMRuzFqlmpEXjU77OKNTiGAEqZPKyJRGqwLIf4volXBc3DcquHRoaijA Ked+eKVy/8jzE5J4p8iliYop7ExvhRi8QZDkpUnJW3mwzA4SzmVm5+ia17mBgI6SpbQsJH CygeaM1INM6cV32x4VYKeOonKyzLfyPCrxqNtWdoN4AcYkpPdbaw5na1oFweMamG4+s97P E0+ufaUNxi9a44fopeY9q6mozrO6UECQTg0xSxcbPpFoZhjJpnGa+cuoVSucT00a/BRs64 W7U6CmfL+/CGBzf7/E0gB/+MpBctZkhHg/jFUjGxMVdgwm5Q7oVSsX3WUFxW4njTGEigaL /22TAynsvaT7AuFF1504Qwk1W9BWrrOfRuPAmEcjvGD9w9OZGFl4QFyrYTCw24DZfjTiAn gguwTOmjMjpBWkh29HetTdQscDxX1JaOgTVb+Nomk2WqV8cGnB8tUUh8+AkA X-ME-Proxy: Feedback-ID: i9d664b8f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 17:53:53 -0400 (EDT) From: NeilBrown To: Alexander Viro , Christian Brauner Cc: Jan Kara , linux-fsdevel@vger.kernel.org, Jeff Layton , Amir Goldstein , Miklos Szeredi , linux-kernel@vger.kernel.org Subject: [PATCH v4 7/7] VFS: reserve a d_flags bit for fs-specific usage Date: Sat, 5 Sep 2026 07:48:16 +1000 Message-ID: <20260904215142.1060510-8-neilb@ownmail.net> X-Mailer: git-send-email 2.50.0.107.gf914562f5916.dirty In-Reply-To: <20260904215142.1060510-1-neilb@ownmail.net> References: <20260904215142.1060510-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 DCACHE_PRIVATE may be used by any filesystem for its own purposes, much like d_fsdata and d_time. I plan to use this in a similar manner the way nfs stores NFS_FSDATA_BLOCKED in d_fsdata. Signed-off-by: NeilBrown --- include/linux/dcache.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/dcache.h b/include/linux/dcache.h index e7e3ef05313b..adf239f8205f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -238,7 +238,9 @@ enum dentry_flags { DCACHE_PAR_LOOKUP =3D BIT(24), /* being looked up (with parent locked sh= ared) */ DCACHE_DENTRY_CURSOR =3D BIT(25), DCACHE_NORCU =3D BIT(26), /* No RCU delay for freeing */ - DCACHE_PERSISTENT =3D BIT(27) + DCACHE_PERSISTENT =3D BIT(27), +/* 28, 29, 30 free */ + DCACHE_PRIVATE =3D BIT(31) /* fs-specific flag */ }; =20 #define DCACHE_MANAGED_DENTRY \ --=20 2.50.0.107.gf914562f5916.dirty