From nobody Tue Sep 29 06:08:34 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 D77A1376475; Tue, 11 Aug 2026 18:15:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472111; cv=none; b=ZztcMZZD1bAGF+u4fkcTUUsJaLJmOC35PyLCq2Jl3MPeZupRX2YTbUxr/snQpYppbIm7mC3eTT4vZPOpGhABHJtfjwpPcl/JD5v3sPHoo1QoK8VHkGGcmghdVRnhg5gQgRpT+rOHCdIgmwwS6iaG0XmdHYm5uG3Oo9ZAkHwC8aU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472111; c=relaxed/simple; bh=KhWdPBELIeMvAxFJiDxL/iLcUriQg6T+juXokUgGOIc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k/hCfn8zQ5d4hjIlAFLdR4wglSDIT8pS8JT5jN+wrMdS6Ot+95onreLgC6aENz4LMcGSFUE8/2lyUEATdT0CpG7i2L1eOQiQ9SoL1ZYJKXb3jorp5//PBNkF/MhyfjIXArOnT6O/bXH0bN6whv9a+13T1QZM8dtgGpO9dTSbt94= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XFaH1ctx; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XFaH1ctx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE3741F00A3D; Tue, 11 Aug 2026 18:15:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786472109; bh=4qG9pt9qpja3I+dp/q+sfoAW6y+kjZng9ZLdIg42aFU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=XFaH1ctx+HWWXJR3teB4U21dwpMJ2z40YoZZJfsfEumK4TP8AdaNsPeiKGPzw0Fb4 TbSYsBhhBdi0hmmBvX6MEjEb7n7dR3qO6dp4CbyyRgfSxaWUXdjZkOzRxiVGLLDYbI zZX0+t73Cuol/sKR20NVKS8P87XSKd6Dm5Y5E+LPBfbAHnLOWYkovVTc2yxQQ8MQld uGuN2iomqpJiIJhH7wKjBbkwCAQ8DrDCbg2stc4ddR0pjSk5EvyR/EtU3044c2lbyP PpGOECbmnde5c+Y2wi0ZeLQmr75YXxaLW3swPCZC7DYoNUrYHfcfLyLmwHoCAGMTRf F3VrAD6XogTjQ== From: Jeff Layton Date: Tue, 11 Aug 2026 14:14:54 -0400 Subject: [PATCH v3 1/6] btrfs: use an on-stack path in btrfs_insert_orphan_item() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260811-btrfs-enomem-v3-1-46a993fc3fe5@kernel.org> References: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> In-Reply-To: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> To: Chris Mason , David Sterba Cc: Qu Wenruo , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1361; i=jlayton@kernel.org; h=from:subject:message-id; bh=KhWdPBELIeMvAxFJiDxL/iLcUriQg6T+juXokUgGOIc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqe2aq5VzvXCnHbz0BS+a+L/N0LekrR/Dn4JcL6 W48kzHi7QWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCantmqgAKCRAADmhBGVaC FQPyEACiEHA27+fVbcWI15K/oN6uUud1kO0Gg72G9folHw9yAapLhCRmlNuJyb65hvdwMBTfUJF qou66MIlRY6nETnDXA6e20NvaGIwKgM5TTEF/HNVaCq6C8L2aQ/BvzVMwGD/T83+gtb2Cnk8GFt jB6dZ0JfrtH2Ju+PkrWXpQ7TXas/ztwUgShOoa9kEVb0FdIfZxCbCEdON9WoRyDAFM/hLmY+aOo 4RzypREDvWdb+EjBZwNvie4nUEKzx83uDBMEq2/8KXXNurIvDSD6ywW5hJdJAlWIQnPzKQE6xaI 3qh1w+1i9c/BhMR/jDP7I08WoC0O457Puvb+ZCNMnJs46l/V79yO+usv4KfFSdwuqkdimnyniXA m4SDAcmtHf4vA96FuT+Zi9/wlL2XYcgYJg1hZnEGaPl4ePbdWRMxGO2VzABsFIfGM4JuPJo/E5V 2BKB71Lot458yhCU0rrp3q0hNnCalWBiOJFro632iu9R4lJhLi0k627twbRLv+zQ+j4ZUVlM+cQ vKqR/5swd6I9zP4u0VvaOgZAb2qalEZ6h2VutV9RH9g2D1dgQ+H6y0hc8K1WVdIKHeRvRK08zhZ dOSyBDFWt3f0K8ZkItnjTt+CHq/Dggh863FAjCxlJvE5d+iZBkQEr+PjJmTkT+mPl+HagrJQBgy 49YA0Wvcl3sK1wQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 btrfs_insert_orphan_item() allocated a btrfs_path with btrfs_alloc_path() which returns -ENOMEM on failure. It is called from btrfs_orphan_add(), so a path allocation failure there turns a recoverable error into a transaction abort. btrfs_path is only ~112 bytes, so allocate it on the stack instead. Assisted-by: LLM Suggested-by: Qu Wenruo Reviewed-by: Qu Wenruo Signed-off-by: Jeff Layton --- fs/btrfs/orphan.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c index 9f3ad124104f..72e1adec39d8 100644 --- a/fs/btrfs/orphan.c +++ b/fs/btrfs/orphan.c @@ -9,18 +9,17 @@ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 offset) { - BTRFS_PATH_AUTO_FREE(path); + struct btrfs_path path =3D { 0 }; struct btrfs_key key; + int ret; =20 key.objectid =3D BTRFS_ORPHAN_OBJECTID; key.type =3D BTRFS_ORPHAN_ITEM_KEY; key.offset =3D offset; =20 - path =3D btrfs_alloc_path(); - if (!path) - return -ENOMEM; - - return btrfs_insert_empty_item(trans, root, path, &key, 0); + ret =3D btrfs_insert_empty_item(trans, root, &path, &key, 0); + btrfs_release_path(&path); + return ret; } =20 int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, --=20 2.55.0 From nobody Tue Sep 29 06:08:34 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 6E692376A07; Tue, 11 Aug 2026 18:15:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472114; cv=none; b=meU1udXidzo8lTEPNAyX9zqswRlvnHR0fcfSV4fwf31RK2TK6t4HXArC7FTiwwx4Dxs7mTdQfpfVQMhunC4RVJhHZshkQDQZu6N7xXucpRFUE0cxHjC9aMYS0RNZJmtwE2C+T/2eX61K4qpnMqX8mO9p9EueMgZ7ruvBNRcSj2k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472114; c=relaxed/simple; bh=z8frzW3+GWYNL1Dql899xeHXBn+IosONCZIVli05JSk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TqDgk1O1ruZblOM8YbmKqi5+ewSHhFGRWXU0SobVnHv5P1wLSO759PkuK9Xi5Uo/+eS2/jaYFZSzc22Dda9WAF6iNw1xPhNUqUuBVlU7F4EYjf/DYyT0IREC6MCZQzKUUTSnegjS41Amm1LLcTAZnhquuxzJB9x1/yI57Mj5sns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XYyPntYS; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XYyPntYS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B07B21F00A3E; Tue, 11 Aug 2026 18:15:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786472110; bh=habuHpxE/FIf7mktmFmbUjmAGBxkdmZecj+7Q8PaLgM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=XYyPntYSlAdbCDQbNuBzwZNZPfMmgIs4JXvy3VVZ1ivMV4q/wm1nXb3QcKjhe36K4 ZmPtrRPMLQVbUEp40KtTqfxwc2ngIkbZwK8lB/YdHLz/OGyZy9l96ZEnpKP4XSEbNf 1IIkCiLhj5DMQYglAqkJNfAyOCM9K2NuSYQdWh+G8kiAZg3DYRg1+c1Rn3WS4Kzmbh Oe/PV3rbSybeHlVkCykgy4J0W9Gr4FYDi+P9X6j9j/qk9V+49Vri1UahzCjBaKAchc xA2aeXUnj/pk/y4vBut3z97tSZWimJY3hEraO7HoGYto1fh2pYPf5/VcfJALhF27lA /6urMLRA9+xMQ== From: Jeff Layton Date: Tue, 11 Aug 2026 14:14:55 -0400 Subject: [PATCH v3 2/6] btrfs: use an on-stack path in btrfs_del_orphan_item() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260811-btrfs-enomem-v3-2-46a993fc3fe5@kernel.org> References: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> In-Reply-To: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> To: Chris Mason , David Sterba Cc: Qu Wenruo , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1772; i=jlayton@kernel.org; h=from:subject:message-id; bh=z8frzW3+GWYNL1Dql899xeHXBn+IosONCZIVli05JSk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqe2aqT4grwQmMOHzzZ3+LmwXm+Vwjdm89NCwPo Ge6xyDjs46JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCantmqgAKCRAADmhBGVaC FU4HD/41ywTjbFqkHkAykTQ5S2MaSb69ZPlXodA6lRjNh5r7pEUK8DzPKARbFK8sSBU1V6Q2Put /Eypcq7tSKfFtFlgsc5T9lmbYv8LKyWEGCESrBRiXIjU/+jj1EGIKmmUuVjqzM9+waKrkAebnmk fWkQzLgNHuzOyHGU4adNi5Aiu2fexAKyexMNGgJ9VP4K/e1VTxC1iv3qupdJcRJPd66xKtqf2xn OTl1bD1IslSpi57nlnOgsAksW3kf+oo6YuPg/UbdPGgc1h3Ajk5w5HnYsv1g47h78aK0WwZsZRG kAntU9MZtt0Vdr3JsyoDUQxUR6tjBG/7Szom+8x26iq792p5Q6Wq1MQUXwb7ooEvO7r4rNFtfPm ojXIiCq2Uw5Pl4XpfnWMRSvCuTeur3WvTnkGAZfsUW14a/o/91obsk9n/p6yTi65Q03sRe73yay Ubx2gPEcvjqTurGrLbQhX7rutXzQOLPiqzEe2a2hBn4osYpfmNShDDgrWkACcI/dFsxksOld2UW eOztJS1aIjEzJIO+pCrtnn9QwCHxVTo+4o1IDrTfkdtqfRhV5A7J8CVfM2o9BCG1H0J0z7vqRTx KWThuHSVewxq+nzemLyTSmI0J/F8DL4F85VhTgtO+VFu8BTD3sdkmn0nvCe7cvumPHw5naVnyjo Puc90S28LVVY04A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 btrfs_del_orphan_item() allocated a btrfs_path with btrfs_alloc_path() which returns -ENOMEM on failure. It is called from btrfs_orphan_del(), and btrfs_link() turns any error from it into a transaction abort. So a path allocation failure there (reachable via linkat() on an O_TMPFILE under memory pressure) turns a recoverable error into an abort. btrfs_path is only ~112 bytes, so allocate it on the stack instead. Unlike the insert case there are multiple exit points after the search, so release the path via a common out: label. Assisted-by: LLM Signed-off-by: Jeff Layton Reviewed-by: Qu Wenruo --- fs/btrfs/orphan.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c index 72e1adec39d8..ae1685f26dec 100644 --- a/fs/btrfs/orphan.c +++ b/fs/btrfs/orphan.c @@ -25,23 +25,24 @@ int btrfs_insert_orphan_item(struct btrfs_trans_handle = *trans, int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 offset) { - BTRFS_PATH_AUTO_FREE(path); + struct btrfs_path path =3D { 0 }; struct btrfs_key key; - int ret =3D 0; + int ret; =20 key.objectid =3D BTRFS_ORPHAN_OBJECTID; key.type =3D BTRFS_ORPHAN_ITEM_KEY; key.offset =3D offset; =20 - path =3D btrfs_alloc_path(); - if (!path) - return -ENOMEM; - - ret =3D btrfs_search_slot(trans, root, &key, path, -1, 1); + ret =3D btrfs_search_slot(trans, root, &key, &path, -1, 1); if (ret < 0) - return ret; - if (ret) - return -ENOENT; - - return btrfs_del_item(trans, root, path); + goto out; + if (ret) { + ret =3D -ENOENT; + goto out; + } + + ret =3D btrfs_del_item(trans, root, &path); +out: + btrfs_release_path(&path); + return ret; } --=20 2.55.0 From nobody Tue Sep 29 06:08:34 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 6E5923769FD; Tue, 11 Aug 2026 18:15:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472114; cv=none; b=JyUaK/eiaRI++K7RJYAtZAG8gcPDNCyUYq4GWUps6qMv3dI97wUG0MSG3mU6IET+0rdXzYjlU10p1O/tXCAEL3wG6nccSA0jn/f1T/tMsmGWLTyD7LTAHxyB7PDFS5dwwNzUuC0jaTENaAB5Yid5ALXckvnpdJpdmDz0ncVCROk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472114; c=relaxed/simple; bh=2+jFO/P3BGcWQvUFK4ldginqeIuydNFf7qjazms8PEo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sMXkJznvdb8ca8jh5AWYg+1LcKwHdI50134aadaLRn458MMpqY4Pm56onqlKYj8+SEHRIkFmNZncklH34UfcJpMZKrFMzj1kIcFD8YJP/114AwVFPUaNEBgTJ8jiKMp/ZBFZnoTKH7RGSoCuP0dy+iol5bOYNhmO8xAKS9QjnZ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YsD78Tm3; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YsD78Tm3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71F891F00A3A; Tue, 11 Aug 2026 18:15:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786472111; bh=3mntvJAHhytu5viFQowYsbS7QVsCCWaixajcjCeZSQw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=YsD78Tm3z0ereiXLT1inad9VwQ7fMjV5BBw/at09DwA98ml7i0Hul9PQNk646CucK O3q5cxKVRslA3Ri7fce0OK4G5WxbN2aFj+GcjnE/HrnkTU6W6KUu+A0gQ/D+8SXZvD IRraPRHsYNvtw7oSYETL3n0/xGhV4en6lngL3BJlm81AmRytYfYHFjPxYj1eaQGJvo 6d5MMS7VBoMMybctD1DuA65GTvuYb2JYR9t2I3jzrousKi8JuMgN7po0OuGlhIAphp Eu4zdFMsHtXMqBr6ZNmOa3geWDEpxO2XNzEpYrl9zW435/ws8nZvlTzMl9aeTmxTQi BzUI5L1sQjObg== From: Jeff Layton Date: Tue, 11 Aug 2026 14:14:56 -0400 Subject: [PATCH v3 3/6] btrfs: split btrfs_insert_delayed_dir_index() into prealloc and commit phases Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260811-btrfs-enomem-v3-3-46a993fc3fe5@kernel.org> References: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> In-Reply-To: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> To: Chris Mason , David Sterba Cc: Qu Wenruo , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9478; i=jlayton@kernel.org; h=from:subject:message-id; bh=2+jFO/P3BGcWQvUFK4ldginqeIuydNFf7qjazms8PEo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqe2ar9IeY1+Sw7jXUCyPfuyCO6OIKzofdB5P08 OUZwikiPEOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCantmqwAKCRAADmhBGVaC FQDrD/9/kX/OsX+xqWWfp4kR7BwoOVvxZcC0so7xKogTb2cms1mvI1rjaCBPHXbjl3mlqAj6qjD +JEOnbcayIYSyGiI4R7/Mgb+Hlk33suf4zVNj3gIPLAL+pmtYP9pi89QZS7/IftGABm1e6daLHj SFizh71EGHNUUsia8C/v/U71kxysZbvRVI7rp+hAoKD9xL9XRn+BCgxxOZJ0f7u3Z0U1S+9Dq5r ARnayw9gV1kXT1LA4Y8yaSqH39DfhIpKR5VxR5AmG3JL5YUBxyUJNMw0x7qjJgw5hadmg0dVPlq v1iA4/5woVbf7lqRuhQFwTXOrlByPPeAxaE5t12hoYdvQC4rCOpgmUFVoNwHDsXsQMKROmEobEi SK4i/aLmf5GFXLuQFOSr+81Ua+EYh/sBwBKb3+zMrF7FqTDMeC+M/hfiGGmyy7BpjUmJ3BSX/hG bDhFWdbrhk266c3sxypzPu8mMVuZgS+A5N7rSqWMti8Mc+H6ptt/bj6DIeBRfcqbqI8mJFzzVv+ YA+vNcNJtc3eNrAki+qV8dCmtwr4YJ9HIw0p0UF+2wdCWgQorv5ubqae3V9jai3GudJahiE1955 cS/1++69ZETC1dS5OOVLx88VGomZ4M5WsFZs/pX961dLDaeXJU+0iizGDkjteFz3lbQ6/WqTH/R 5SLmHN84UjqSUzw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Split btrfs_insert_delayed_dir_index() into three functions using a new btrfs_dir_index_prealloc struct to bundle the pre-allocated resources: - btrfs_prealloc_delayed_dir_index(): allocates the struct and performs the two GFP_NOFS allocations (delayed node + delayed item) that can fail with -ENOMEM. Returns the struct, or ERR_PTR on failure. - btrfs_insert_delayed_dir_index_prealloc(): populates the item data, inserts into the rb-tree, and reserves metadata space. Cannot fail with -ENOMEM since all allocations were done in the prealloc step. - btrfs_free_delayed_dir_index_prealloc(): frees pre-allocated resources when the caller's btree insertion fails. Tolerates NULL. The prealloc is returned as a pointer rather than filled into a caller-provided struct, so that a plain NULL means "no prealloc" and callers do not need a separate flag to track whether one exists. It is consumed (and freed) by either the commit or the free helper, so ownership is unambiguous. The original btrfs_insert_delayed_dir_index() is refactored into a thin wrapper that calls the prealloc and commit functions. This split allows callers to move the fallible memory allocations before the point of no return (the DIR_ITEM btree insertion), so that -ENOMEM can be returned cleanly without aborting the transaction. Assisted-by: LLM Reviewed-by: Qu Wenruo Signed-off-by: Jeff Layton --- fs/btrfs/delayed-inode.c | 128 ++++++++++++++++++++++++++++++++++++++-----= ---- fs/btrfs/delayed-inode.h | 17 +++++++ 2 files changed, 121 insertions(+), 24 deletions(-) diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index db2ffab0941a..af5e6dbf60d3 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -6,6 +6,7 @@ =20 #include #include +#include #include "ctree.h" #include "fs.h" #include "messages.h" @@ -1469,35 +1470,93 @@ static void btrfs_release_dir_index_item_space(stru= ct btrfs_trans_handle *trans) trans->bytes_reserved -=3D bytes; } =20 -/* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected).= */ -int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, - const char *name, int name_len, - struct btrfs_inode *dir, - const struct btrfs_disk_key *disk_key, u8 flags, - u64 index) +/* + * Pre-allocate a delayed node and delayed item for a dir index insertion = and + * copy the name into the item. Call this before modifying the btree so th= at + * ENOMEM can be returned before any on-disk state has changed. + * + * The returned prealloc is consumed by either + * btrfs_insert_delayed_dir_index_prealloc() or + * btrfs_free_delayed_dir_index_prealloc(); it must not be used afterwards. + * + * Returns a prealloc on success, ERR_PTR on allocation failure. + */ +struct btrfs_dir_index_prealloc *btrfs_prealloc_delayed_dir_index(struct b= trfs_inode *dir, + const char *name, + int name_len) +{ + struct btrfs_dir_index_prealloc *prealloc; + struct btrfs_delayed_node *node; + struct btrfs_delayed_item *item; + + prealloc =3D kzalloc_obj(*prealloc, GFP_NOFS); + if (!prealloc) + return ERR_PTR(-ENOMEM); + + node =3D btrfs_get_or_create_delayed_node(dir, &prealloc->tracker); + if (IS_ERR(node)) { + kfree(prealloc); + return ERR_CAST(node); + } + + item =3D btrfs_alloc_delayed_item(sizeof(struct btrfs_dir_item) + name_le= n, + node, BTRFS_DELAYED_INSERTION_ITEM); + if (!item) { + btrfs_release_delayed_node(node, &prealloc->tracker); + kfree(prealloc); + return ERR_PTR(-ENOMEM); + } + + memcpy(item->data + sizeof(struct btrfs_dir_item), name, name_len); + + prealloc->node =3D node; + prealloc->item =3D item; + return prealloc; +} +ALLOW_ERROR_INJECTION(btrfs_prealloc_delayed_dir_index, ERRNO); + +/* + * Free resources from btrfs_prealloc_delayed_dir_index() when the btree + * insertion failed and we will not commit the delayed dir index. Does not= hing + * if @prealloc is NULL. + */ +void btrfs_free_delayed_dir_index_prealloc(struct btrfs_trans_handle *tran= s, + struct btrfs_dir_index_prealloc *prealloc) { + if (!prealloc) + return; + + btrfs_release_delayed_item(prealloc->item); + btrfs_release_dir_index_item_space(trans); + btrfs_release_delayed_node(prealloc->node, &prealloc->tracker); + kfree(prealloc); +} + +/* + * Commit a pre-allocated delayed dir index item. @prealloc must have been + * returned by btrfs_prealloc_delayed_dir_index(). This populates the item, + * adds it to the delayed node's rb-tree, and reserves metadata space. It + * cannot fail with ENOMEM. @prealloc is freed here in all cases. + * + * Will return 0 or -EEXIST (index number collision, unexpected). + */ +int btrfs_insert_delayed_dir_index_prealloc(struct btrfs_trans_handle *tra= ns, + struct btrfs_inode *dir, + struct btrfs_dir_index_prealloc *prealloc, + const struct btrfs_disk_key *disk_key, + u8 flags, u64 index) +{ + struct btrfs_delayed_node *delayed_node =3D prealloc->node; + struct btrfs_ref_tracker *tracker =3D &prealloc->tracker; + struct btrfs_delayed_item *delayed_item =3D prealloc->item; struct btrfs_fs_info *fs_info =3D trans->fs_info; const unsigned int leaf_data_size =3D BTRFS_LEAF_DATA_SIZE(fs_info); - struct btrfs_delayed_node *delayed_node; - struct btrfs_ref_tracker delayed_node_tracker; - struct btrfs_delayed_item *delayed_item; + const int name_len =3D delayed_item->data_len - sizeof(struct btrfs_dir_i= tem); struct btrfs_dir_item *dir_item; bool reserve_leaf_space; u32 data_len; int ret; =20 - delayed_node =3D btrfs_get_or_create_delayed_node(dir, &delayed_node_trac= ker); - if (IS_ERR(delayed_node)) - return PTR_ERR(delayed_node); - - delayed_item =3D btrfs_alloc_delayed_item(sizeof(*dir_item) + name_len, - delayed_node, - BTRFS_DELAYED_INSERTION_ITEM); - if (!delayed_item) { - ret =3D -ENOMEM; - goto release_node; - } - delayed_item->index =3D index; =20 dir_item =3D (struct btrfs_dir_item *)delayed_item->data; @@ -1506,7 +1565,7 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans= _handle *trans, btrfs_set_stack_dir_data_len(dir_item, 0); btrfs_set_stack_dir_name_len(dir_item, name_len); btrfs_set_stack_dir_flags(dir_item, flags); - memcpy((char *)(dir_item + 1), name, name_len); + /* Name was already copied by btrfs_prealloc_delayed_dir_index(). */ =20 data_len =3D delayed_item->data_len + sizeof(struct btrfs_item); =20 @@ -1524,7 +1583,9 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans= _handle *trans, if (unlikely(ret)) { btrfs_err(trans->fs_info, "error adding delayed dir index item, name: %.*s, index: %llu, root: %llu,= dir: %llu, dir->index_cnt: %llu, delayed_node->index_cnt: %llu, error: %pe= ", - name_len, name, index, btrfs_root_id(delayed_node->root), + name_len, + (const char *)(dir_item + 1), + index, btrfs_root_id(delayed_node->root), delayed_node->inode_id, dir->index_cnt, delayed_node->index_cnt, ERR_PTR(ret)); btrfs_release_delayed_item(delayed_item); @@ -1562,10 +1623,29 @@ int btrfs_insert_delayed_dir_index(struct btrfs_tra= ns_handle *trans, mutex_unlock(&delayed_node->mutex); =20 release_node: - btrfs_release_delayed_node(delayed_node, &delayed_node_tracker); + /* Must release the node before freeing @tracker's containing struct. */ + btrfs_release_delayed_node(delayed_node, tracker); + kfree(prealloc); return ret; } =20 +/* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected).= */ +int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, + const char *name, int name_len, + struct btrfs_inode *dir, + const struct btrfs_disk_key *disk_key, u8 flags, + u64 index) +{ + struct btrfs_dir_index_prealloc *prealloc; + + prealloc =3D btrfs_prealloc_delayed_dir_index(dir, name, name_len); + if (IS_ERR(prealloc)) + return PTR_ERR(prealloc); + + return btrfs_insert_delayed_dir_index_prealloc(trans, dir, prealloc, + disk_key, flags, index); +} + static bool btrfs_delete_delayed_insertion_item(struct btrfs_delayed_node = *node, u64 index) { diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h index fc752863f89b..6d12a145489f 100644 --- a/fs/btrfs/delayed-inode.h +++ b/fs/btrfs/delayed-inode.h @@ -121,6 +121,23 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_= handle *trans, const struct btrfs_disk_key *disk_key, u8 flags, u64 index); =20 +struct btrfs_dir_index_prealloc { + struct btrfs_delayed_node *node; + struct btrfs_ref_tracker tracker; + struct btrfs_delayed_item *item; +}; + +struct btrfs_dir_index_prealloc *btrfs_prealloc_delayed_dir_index(struct b= trfs_inode *dir, + const char *name, + int name_len); +void btrfs_free_delayed_dir_index_prealloc(struct btrfs_trans_handle *tran= s, + struct btrfs_dir_index_prealloc *prealloc); +int btrfs_insert_delayed_dir_index_prealloc(struct btrfs_trans_handle *tra= ns, + struct btrfs_inode *dir, + struct btrfs_dir_index_prealloc *prealloc, + const struct btrfs_disk_key *disk_key, + u8 flags, u64 index); + int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, struct btrfs_inode *dir, u64 index); =20 --=20 2.55.0 From nobody Tue Sep 29 06:08:34 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 CDDEE369D61; Tue, 11 Aug 2026 18:15:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472116; cv=none; b=KSLfre/fUJ+rrWBhJ7oMPu24isi4rCeI5hJ6ceXTDW5VgVZe4ggh+7DMLZDtOAACxnsEWp6H+lrVKW8wbiEWabS0vHxMCvFjO4r7ELRnNyzb19FNK9fFCVRmlJ2nr+RhVoHyTJ+67DitvOGgjNPSEdeM2GUqR9ttoFzJNkz8mlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472116; c=relaxed/simple; bh=SuoQyOL5OoixGIQjHqn4nzB0MprTrfikfwtDwZ15904=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Vt1GrNA6XIqwYfh2Hamwuy+pyb9UWxtwifz6nBf1WUxduxOzfTUekG9lk/6oBrjBwBJ0fjRL3+5WB8xvshmVn+/3rw2tlEkzFy7QQM0F8hwsg+GONOacQuYW5QrGBO+LTHCdmaRHPvavw3idOTRhU3DhrnjYJpsvKGKUlHq9QwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dSHgrNAA; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dSHgrNAA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3477C1F00AC4; Tue, 11 Aug 2026 18:15:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786472111; bh=b9PWBl+4Ny6MgSuhtKT5CkWx640e44bnpWLCqG0SP9A=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=dSHgrNAANwln0fa6wt4gxIU+IcrLIpz7dOZGI762DQPG2QluDdE3ZRU01O8nJ/JZV B1ICjInBvNzS4iHm20wB2EQnUz0XynTWebnToZg5fC3nxicL8t9sIz1q3DlKZ3b6qO +bwklAnIFt6t9mAbrfBeKWoQLsltix6S3dBOxCm89cjNoTV2dAxw4dk+GWa1FVaG39 DVleHQHVxdrRaBFJpzSeqdexP3V0FZLYx2lrKOgPaDbF4gM+vOkPhpiscNClegfZsI dxo8Tbxj32eWiOyKipi0zB9bnQRuGxJcRnkzgkAiNpuoaQDJFfJZQgNsFPq6cCAEtL DND4O17syWubw== From: Jeff Layton Date: Tue, 11 Aug 2026 14:14:57 -0400 Subject: [PATCH v3 4/6] btrfs: pre-allocate delayed dir index before btree modification Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260811-btrfs-enomem-v3-4-46a993fc3fe5@kernel.org> References: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> In-Reply-To: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> To: Chris Mason , David Sterba Cc: Qu Wenruo , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=8619; i=jlayton@kernel.org; h=from:subject:message-id; bh=SuoQyOL5OoixGIQjHqn4nzB0MprTrfikfwtDwZ15904=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqe2arElK+AtgGFhdzSFxNQTC78GqJrQf5v+quO fQ3MywFU5uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCantmqwAKCRAADmhBGVaC FcwJD/4kCGof62j78o0aI5ZutvjfZ8gi0BK+8Z60tKstE8K+Ejj4W+z1E+rHZh7/6srlxJvHFpI VAxRvfWROPlork/hedshRf9NpszSpOKwYDPWLvrE7b8HybsjO4zZRmM+IsnQ6NbEpu36DYeIo5W DdDS4AcaiN44OOONpSRlP6pr4/HLjmguTJ/crT723oObRXkulTZxVU4lDHMLW7OjTh3Z3Yq0XEi jAm0ac0Y9mOMnlImV+RgWq9WFXo1NN2qCHnmUF1caJK2Mn2DT2dPKA2EphXOgEMpQhS3V9J07/S rIC/l+pqpP/XYXj6shg0soE0zb0kiR1ekOqDkIbi4EhxGrvj4xlfWLpo59bak639660Z1pyjsZY YZ4GbuWVZlvZXehOkyklwgINxuUsw/UZfbQThSkIOjMgIqhI97NwOEmSUZ8TgX4PbNZuVxqJuYp 1ENsX5wLdEcaf560Aro8TgerP0W2JasDwwXi5MUbMKOsz/USsQKLfMyqVhkVtVdqiPXwfR8vRFp G0jFGugedkqworUWdKXDyH9JXrt0pnTggmnw8k4QoodOLjyECRzba3xkegFyswhkcFfqg//23A1 btmNLprIItLVmUvigLtXlYLBFVUrHy0fogvvKhyTZ6pWv2mMDfAAMzeDfWJy03j+UILUH8kktNr 6LuvQjd368lV5bg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Move the delayed dir index allocation in btrfs_insert_dir_item() before the insert_with_overflow() call that modifies the btree. Previously, the allocations happened after the DIR_ITEM was already inserted, meaning an ENOMEM failure left the btree in a partially-modified state that could only be resolved by aborting the transaction. Add an optional caller-provided btrfs_dir_index_prealloc parameter to btrfs_insert_dir_item(). When non-NULL, ownership of the prealloc transfers to btrfs_insert_dir_item(). When NULL, it allocates internally. All existing callers pass NULL to preserve the current behavior. Since ownership transfers, btrfs_insert_dir_item() must free the prealloc on every path that does not commit it. Route all such exits (including the early path allocation failure) through a common out_free_prealloc label, rather than keying cleanup on need_delayed_index. Remove the btrfs_insert_delayed_dir_index() wrapper, as there are no more callers. Assisted-by: LLM Suggested-by: Qu Wenruo Signed-off-by: Jeff Layton Reviewed-by: Qu Wenruo --- fs/btrfs/delayed-inode.c | 21 ++------------------- fs/btrfs/delayed-inode.h | 5 ----- fs/btrfs/dir-item.c | 42 ++++++++++++++++++++++++++++-------------- fs/btrfs/dir-item.h | 5 +++-- fs/btrfs/inode.c | 2 +- fs/btrfs/transaction.c | 2 +- 6 files changed, 35 insertions(+), 42 deletions(-) diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index af5e6dbf60d3..bd603525c133 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -687,7 +687,7 @@ static int btrfs_insert_delayed_item(struct btrfs_trans= _handle *trans, /* * For delayed items to insert, we track reserved metadata bytes based * on the number of leaves that we will use. - * See btrfs_insert_delayed_dir_index() and + * See btrfs_insert_delayed_dir_index_prealloc() and * btrfs_delayed_item_reserve_metadata()). */ ASSERT(first_item->bytes_reserved =3D=3D 0); @@ -1629,23 +1629,6 @@ int btrfs_insert_delayed_dir_index_prealloc(struct b= trfs_trans_handle *trans, return ret; } =20 -/* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected).= */ -int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, - const char *name, int name_len, - struct btrfs_inode *dir, - const struct btrfs_disk_key *disk_key, u8 flags, - u64 index) -{ - struct btrfs_dir_index_prealloc *prealloc; - - prealloc =3D btrfs_prealloc_delayed_dir_index(dir, name, name_len); - if (IS_ERR(prealloc)) - return PTR_ERR(prealloc); - - return btrfs_insert_delayed_dir_index_prealloc(trans, dir, prealloc, - disk_key, flags, index); -} - static bool btrfs_delete_delayed_insertion_item(struct btrfs_delayed_node = *node, u64 index) { @@ -1661,7 +1644,7 @@ static bool btrfs_delete_delayed_insertion_item(struc= t btrfs_delayed_node *node, /* * For delayed items to insert, we track reserved metadata bytes based * on the number of leaves that we will use. - * See btrfs_insert_delayed_dir_index() and + * See btrfs_insert_delayed_dir_index_prealloc() and * btrfs_delayed_item_reserve_metadata()). */ ASSERT(item->bytes_reserved =3D=3D 0); diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h index 6d12a145489f..57ba96cfaf9c 100644 --- a/fs/btrfs/delayed-inode.h +++ b/fs/btrfs/delayed-inode.h @@ -115,11 +115,6 @@ struct btrfs_delayed_item { }; =20 void btrfs_init_delayed_root(struct btrfs_delayed_root *delayed_root); -int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, - const char *name, int name_len, - struct btrfs_inode *dir, - const struct btrfs_disk_key *disk_key, u8 flags, - u64 index); =20 struct btrfs_dir_index_prealloc { struct btrfs_delayed_node *node; diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 84f1c64423d3..30ddafaf8d3d 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -106,8 +106,11 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle = *trans, * Will return 0 or -ENOMEM */ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, - const struct fscrypt_str *name, struct btrfs_inode *dir, - const struct btrfs_key *location, u8 type, u64 index) + const struct fscrypt_str *name, + struct btrfs_inode *dir, + const struct btrfs_key *location, u8 type, + u64 index, + struct btrfs_dir_index_prealloc *prealloc) { int ret =3D 0; int ret2 =3D 0; @@ -119,17 +122,28 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *= trans, struct btrfs_key key; struct btrfs_disk_key disk_key; u32 data_size; + const bool need_delayed_index =3D (root !=3D root->fs_info->tree_root); =20 key.objectid =3D btrfs_ino(dir); key.type =3D BTRFS_DIR_ITEM_KEY; key.offset =3D btrfs_name_hash(name->name, name->len); =20 path =3D btrfs_alloc_path(); - if (!path) - return -ENOMEM; + if (!path) { + ret =3D -ENOMEM; + goto out_free_prealloc; + } =20 btrfs_cpu_key_to_disk(&disk_key, location); =20 + /* Pre-allocate the delayed dir index before modifying the btree. */ + if (need_delayed_index && !prealloc) { + prealloc =3D btrfs_prealloc_delayed_dir_index(dir, name->name, + name->len); + if (IS_ERR(prealloc)) + return PTR_ERR(prealloc); + } + data_size =3D sizeof(*dir_item) + name->len; dir_item =3D insert_with_overflow(trans, root, path, &key, data_size, name->name, name->len); @@ -137,7 +151,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *tr= ans, ret =3D PTR_ERR(dir_item); if (ret =3D=3D -EEXIST) goto second_insert; - goto out_free; + goto out_free_prealloc; } =20 if (IS_ENCRYPTED(&dir->vfs_inode)) @@ -154,21 +168,21 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *= trans, write_extent_buffer(leaf, name->name, name_ptr, name->len); =20 second_insert: - /* FIXME, use some real flag for selecting the extra index */ - if (root =3D=3D root->fs_info->tree_root) { + if (!need_delayed_index) { ret =3D 0; - goto out_free; + goto out_free_prealloc; } btrfs_release_path(path); =20 - ret2 =3D btrfs_insert_delayed_dir_index(trans, name->name, name->len, dir, - &disk_key, type, index); -out_free: + ret2 =3D btrfs_insert_delayed_dir_index_prealloc(trans, dir, prealloc, + &disk_key, type, index); if (ret) return ret; - if (ret2) - return ret2; - return 0; + return ret2; + +out_free_prealloc: + btrfs_free_delayed_dir_index_prealloc(trans, prealloc); + return ret; } =20 static struct btrfs_dir_item *btrfs_lookup_match_dir( diff --git a/fs/btrfs/dir-item.h b/fs/btrfs/dir-item.h index e52174a8baf9..d7a7d0b66f37 100644 --- a/fs/btrfs/dir-item.h +++ b/fs/btrfs/dir-item.h @@ -16,9 +16,11 @@ struct btrfs_trans_handle; =20 int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir_ino, const struct fscrypt_str *name); +struct btrfs_dir_index_prealloc; int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const struct fscrypt_str *name, struct btrfs_inode *dir, - const struct btrfs_key *location, u8 type, u64 index); + const struct btrfs_key *location, u8 type, u64 index, + struct btrfs_dir_index_prealloc *prealloc); struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *tr= ans, struct btrfs_root *root, struct btrfs_path *path, u64 dir, @@ -53,5 +55,4 @@ static inline u64 btrfs_name_hash(const char *name, int l= en) { return crc32c((u32)~1, name, len); } - #endif diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3c10a0ef0002..3a2dca093c7d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6924,7 +6924,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, return ret; =20 ret =3D btrfs_insert_dir_item(trans, name, parent_inode, &key, - btrfs_inode_type(inode), index); + btrfs_inode_type(inode), index, NULL); if (ret =3D=3D -EEXIST || ret =3D=3D -EOVERFLOW) goto fail_dir_item; else if (unlikely(ret)) { diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c641099d66e2..6fdfea5d35af 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1882,7 +1882,7 @@ static noinline int create_pending_snapshot(struct bt= rfs_trans_handle *trans, =20 ret =3D btrfs_insert_dir_item(trans, &fname.disk_name, parent_inode, &key, BTRFS_FT_DIR, - index); + index, NULL); if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); goto fail; --=20 2.55.0 From nobody Tue Sep 29 06:08:34 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 CDF2736D9FE; Tue, 11 Aug 2026 18:15:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472117; cv=none; b=AA/+llYLL7Xx7BdTZ3DDx4YVffU1L3pTAA+3sTS1B5uRm8mIS/tz0ZE8bM2jFYz769mx4xy5CRSFNoP6muPQF6DRPdKFfC2nOesba1kSEIPBrslJbodr9AwopGth8Yjpqgvx/CCgHaoT/VpcVKUuSQmvB/Ug63AB0WUyd1iVOso= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472117; c=relaxed/simple; bh=i8QCxSVOV0LcFs+6/Mjy+uu1WcgS6N7H0r4iR2hOgvk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h4/htJN4Ah6oq/heXnmnw54bs4XwiurozXHFpTAEw2N7G4I4D9rnEeUlJL+3VamJBq9axj+OuC9+JI7bf3sc71TBD1NGnL83LNHby+yt8xIsLStKOFyxXMWzGUdY3zvmTDxN8s7R1OcHfm2oKjJ+iRlE4UTAui8SSlYXyxWnzts= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FGhjd9yi; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FGhjd9yi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EA9F31F00A3D; Tue, 11 Aug 2026 18:15:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786472112; bh=0KxVljklGd97b9rZMT8e3dxgS3KH3MdjoX7XMkwh6Ws=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=FGhjd9yipJAsE8MOIVP3Fr/Y/r3xaRD18wkeAJTOKzMtDVwiyvPpihEyfjitJ9iQc IjpYNcEpF/9eqxO/lRmsaUgQtDDeeTq3B7p0LkUXX0zLgXhJtF46zyK8oaAZXFxNrX tPusbteXZk6RL2/G0zkpMtruVwmaCKtUv9Zq5HGxO4lB9XhL11kZMR82Q1Rm16PmJ5 5kB+JCOXE4dGED+X6/Wf1rSg2Oo+oFCUQP35p5IH/AOqoCZZPm4SBhgUhaaaCVncC1 8UpCg7+kttVy4Hrgdm50aQ+fKyPf68MEp6f5kO3vKGVkQwDY7LkwOqfdSGF8icIYw7 etdXG/6N+mInA== From: Jeff Layton Date: Tue, 11 Aug 2026 14:14:58 -0400 Subject: [PATCH v3 5/6] btrfs: handle ENOMEM from btrfs_insert_dir_item() without aborting Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260811-btrfs-enomem-v3-5-46a993fc3fe5@kernel.org> References: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> In-Reply-To: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> To: Chris Mason , David Sterba Cc: Qu Wenruo , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2667; i=jlayton@kernel.org; h=from:subject:message-id; bh=i8QCxSVOV0LcFs+6/Mjy+uu1WcgS6N7H0r4iR2hOgvk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqe2arMWMeCVirASuceWVZYx/Ga8+ycl7V71gix cqbv9EQlOyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCantmqwAKCRAADmhBGVaC FSsAD/9EMnv2Pf2XjvvyBgU8P6Kmd6x/0sOKXWolE6REbF6AmlOc8FS3xbpUn0uIOXh8KqBnr4S zzBl6/ZcuFWV0tyJhqCl88F6AfRvOC2fCr0Yl+P+RvbhjXdREXwmNtPYg12EFEOIpnzaG4MFE8x EwgdRRJEEpg0BW3ZN65Y6BrUpqDesqcj3yyk+q72m6lTgDHOKpEONcMufQ6A+nWKpyS7FRWbmCM 4Jqlnk3wVo4s4eG2WhFi2sFBoxHdCnmdHwJvG+v5olVTTtm5c0f5qRaGwe3sQs/Hw016BpD3Kpa WmW94LaUVnQL8Fj+hm/sgAGk1WYCvQe90pgA9ILGpTV2AgRo/evH5b0XI/Weak22jLt9KbHCeiZ axqb1+MMmD+ZwrRI+dDaZ7yUxrkQ9BJNSLDE/k/DKHMCnsP5ILfT7qXL4B9vB3EwhHO5MTICW2E ss+kOo8MHyRNSmC0LK/RAMCMU/YSpZVS7fQzwWhv/2Bj6CJrDmJLnxdgQCPjNvulNUkjDhtmgQi J6slD32+ZSdjDwBNNDYNO1TyiGZ80fe3bIlgkw6bpfZX+Q6Ci7OGSJG+/e4LB3sBvuT5oxKOSVH Lp8HogG2LznHxcieDalC9VqkZ2DVAVGpR4SmXxhKkQWgVDa2bBU5ImEVTRH5+OJVykb6GH3RXN2 abtzhAcxNvJn1KA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Now that btrfs_insert_dir_item() returns -ENOMEM before modifying the btree (thanks to delayed dir index pre-allocation), callers can handle ENOMEM gracefully instead of aborting the transaction. - btrfs_add_link(): add -ENOMEM to the recoverable errors alongside -EEXIST and -EOVERFLOW. - btrfs_create_new_inode(): on -ENOMEM from btrfs_add_link(), orphan the newly-created inode instead of aborting. The inode item was already written with nlink 1, and discard_new_inode() marks it bad so eviction won't delete it. So clear_nlink() alone is not enough: persist nlink 0 via btrfs_update_inode(), otherwise orphan cleanup would see nlink > 0, drop the orphan item, and leak the inode. Fall back to aborting only if that update also fails. This turns a filesystem-killing abort into a graceful -ENOMEM return for create(), mkdir(), mknod(), symlink(), and link() under memory pressure. Assisted-by: LLM Signed-off-by: Jeff Layton Reviewed-by: Qu Wenruo --- fs/btrfs/inode.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3a2dca093c7d..5b79910d72f5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6863,7 +6863,27 @@ int btrfs_create_new_inode(struct btrfs_trans_handle= *trans, } else { ret =3D btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name, false, BTRFS_I(inode)->dir_index); - if (unlikely(ret)) { + if (ret =3D=3D -ENOMEM) { + /* + * Orphan the new inode instead of aborting. The inode + * item was already written with nlink 1, and discard's + * eviction won't delete a bad inode, so nlink 0 must be + * persisted here or orphan cleanup would see nlink > 0, + * drop the orphan item, and leak the inode. + */ + clear_nlink(inode); + /* btrfs_orphan_add() aborts the transaction on failure. */ + ret =3D btrfs_orphan_add(trans, BTRFS_I(inode)); + if (ret) + goto discard; + ret =3D btrfs_update_inode(trans, BTRFS_I(inode)); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto discard; + } + ret =3D -ENOMEM; + goto discard; + } else if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); goto discard; } @@ -6925,7 +6945,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, =20 ret =3D btrfs_insert_dir_item(trans, name, parent_inode, &key, btrfs_inode_type(inode), index, NULL); - if (ret =3D=3D -EEXIST || ret =3D=3D -EOVERFLOW) + if (ret =3D=3D -EEXIST || ret =3D=3D -EOVERFLOW || ret =3D=3D -ENOMEM) goto fail_dir_item; else if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); --=20 2.55.0 From nobody Tue Sep 29 06:08:34 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 2BA73353A8E; Tue, 11 Aug 2026 18:15:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472119; cv=none; b=r7YwWwA/xogyxDO1bkAfgNfykYwAFa/3EWbgEEyqy5od3EbJgDu5NtIM/6fGXBmtNn33tntNWSb3RRvRY2Kw43gbWpEfkaVm6VBjsrvUJoYeamx255kDw1U3jbOhEHxwVK3MBp4LveCY7nwZ3r+UXXuAQBAF6dIzp4joqo91+wE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786472119; c=relaxed/simple; bh=v8a82oH3QarP6I8CBddMNieJTg8G5gwPz33bnEBPH1I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N2AXgjRyyLmCUPUw2MUGtK2BuwsSepqCp8jDd08I9yDiLKPnXQ8EuXfRPK6QnUT9pUzut+NgqqK2/3F9F0ChlkO1xpmOsKIzKN3Zb+vfj5rfF4zp62ccnzRv7rQR96dbABwg2O7LkkfzyJvEOT70smU6xFvyuw6KMihtw1ajRJ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=clno6O/Z; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="clno6O/Z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC7B61F00A3F; Tue, 11 Aug 2026 18:15:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786472113; bh=OXnftdUGJlC4cntuhv3BMGFqzvt2LM1k7YzvH1mHMHQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=clno6O/Z+k4l5ZF/Ksp86hxQf+9C5YOITr0V0kjfjiY1W+MQfFxB+dKzLGpYxQrXR 0/3xbBwQsCuzaVBjpIQnBjK6aCwiEcqLjmloZ2omYN25GiP35wEdCRJNRQBEX2rxAn CIG//bl8sJjwnEujClkW+Znhx0DX0qiI2jNpbiPzIieN46FjTHxHUH3m5ISPZmvxhG hG7Wq2musWv9d9WPF8fBDTRPElb/NlxJSGhjPRIohTZA6bnJBmY8e+775OLrfjDeBB wHQPbRH7vYwixT7pofifTEolgjqmHic1YSg2KS7sNsYPjh5dUwPmbxiqCtinFH17QF VocWZpwrJCN2w== From: Jeff Layton Date: Tue, 11 Aug 2026 14:14:59 -0400 Subject: [PATCH v3 6/6] btrfs: pre-allocate delayed dir index for non-overwrite rename Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260811-btrfs-enomem-v3-6-46a993fc3fe5@kernel.org> References: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> In-Reply-To: <20260811-btrfs-enomem-v3-0-46a993fc3fe5@kernel.org> To: Chris Mason , David Sterba Cc: Qu Wenruo , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7243; i=jlayton@kernel.org; h=from:subject:message-id; bh=v8a82oH3QarP6I8CBddMNieJTg8G5gwPz33bnEBPH1I=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqe2arc2/r4Mvv0cPl8IiNahyaae65akZfL2ij1 aRlodrXNWeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCantmqwAKCRAADmhBGVaC FQSJEADPqKwCteozx2yXw6skrgyxhq0OYVPRNSqsMwqDWopohroiFNAMKCOZflZVKjW2N6rq2+l +OkOIcOGqHWv8mb3L6aBh4/TIEzdZ4LPCD2dcn1xMhLDVrxMTJ+RMIf5gKxvBZFKOH5ovlBOr4c Ogl6RnpWzq+atJUb2Oh36nARK0gIlLzj7KgLDpbbvy6vI5tHtb38WLgPEvCcwpnSqcMLz7Yb0kr hF0nycQcD7pJ6kj7ZNLQ2jsY/Svb5RguAI2pySRSrUez9Gk35iiwcR4s1mNEuHY9RB9FoKwiffz 3mYs5fs38u/gNbv5o3I01B5xDflr0MsMXoZ4SnbwOm1HscO3EvsaEjVaHuNRIk6HCMypXo/eK49 nK6mpDtPE3vRuIVMvYZP+chygR3coPF5Q41/7AvUF6uDl6qejmGXByLs6/KJmwgxE2xxsKS3gSP qBznQ9jAxLy5hkCU/HmiP2fH7A3vFwmhybsTM1FXFZS3k7LcnqxWW+GZe2ZdTVejQRNOFBDdIQM gq55srO8tyzBQ7fOdSSpJKr91XWKAOz3n0Jcyq5YZtgPHx75itpqlDGJCKnAfHyPyMmCcQsBFXq oqYA2CEeemxavAC9ucnmJ9bwPTyxCXtqV4wKK6RucKHR2usPCl1SLuAje6OPwxEtY+6oEHQLAF4 2ob8xtdgyIIZNwQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 For rename() without an overwrite target, pre-allocate the delayed dir index before any btree modifications so that ENOMEM can be returned before the source is unlinked from the old directory. Add a prealloc parameter to btrfs_add_link() that allows callers to pass pre-allocated delayed dir index resources. When provided, btrfs_add_link() takes ownership: it either passes the prealloc to btrfs_insert_dir_item() (which commits or frees it), or frees it on early error. All existing callers pass NULL to preserve the current behavior. In btrfs_rename(), when new_inode is NULL (no overwrite), call btrfs_prealloc_delayed_dir_index() before the first btree modification and pass the result through to btrfs_add_link(). If the prealloc fails, -ENOMEM is returned before any btree state has changed. The local prealloc pointer is cleared once ownership passes to btrfs_add_link(), so the out_fail path only frees one we still own. For overwrite rename (new_inode !=3D NULL), the transaction still aborts on ENOMEM since earlier unlink operations have already made irreversible btree modifications. Assisted-by: LLM Signed-off-by: Jeff Layton Reviewed-by: Qu Wenruo --- fs/btrfs/btrfs_inode.h | 4 +++- fs/btrfs/inode.c | 40 ++++++++++++++++++++++++++++++++-------- fs/btrfs/tree-log.c | 4 ++-- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 1082fa92c145..d4280f152027 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -525,9 +525,11 @@ int btrfs_set_inode_index(struct btrfs_inode *dir, u64= *index); int btrfs_unlink_inode(struct btrfs_trans_handle *trans, struct btrfs_inode *dir, struct btrfs_inode *inode, const struct fscrypt_str *name); +struct btrfs_dir_index_prealloc; int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_inode *parent_inode, struct btrfs_inode *inode, - const struct fscrypt_str *name, bool add_backref, u64 index); + const struct fscrypt_str *name, bool add_backref, u64 index, + struct btrfs_dir_index_prealloc *prealloc); int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry); int btrfs_truncate_block(struct btrfs_inode *inode, u64 offset, u64 start,= u64 end); =20 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5b79910d72f5..fd6d481f4d12 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6862,7 +6862,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle = *trans, } } else { ret =3D btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name, - false, BTRFS_I(inode)->dir_index); + false, BTRFS_I(inode)->dir_index, NULL); if (ret =3D=3D -ENOMEM) { /* * Orphan the new inode instead of aborting. The inode @@ -6914,7 +6914,8 @@ int btrfs_create_new_inode(struct btrfs_trans_handle = *trans, */ int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_inode *parent_inode, struct btrfs_inode *inode, - const struct fscrypt_str *name, bool add_backref, u64 index) + const struct fscrypt_str *name, bool add_backref, u64 index, + struct btrfs_dir_index_prealloc *prealloc) { int ret =3D 0; struct btrfs_key key; @@ -6940,11 +6941,13 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, } =20 /* Nothing to clean up yet */ - if (ret) + if (ret) { + btrfs_free_delayed_dir_index_prealloc(trans, prealloc); return ret; + } =20 ret =3D btrfs_insert_dir_item(trans, name, parent_inode, &key, - btrfs_inode_type(inode), index, NULL); + btrfs_inode_type(inode), index, prealloc); if (ret =3D=3D -EEXIST || ret =3D=3D -EOVERFLOW || ret =3D=3D -ENOMEM) goto fail_dir_item; else if (unlikely(ret)) { @@ -7098,7 +7101,7 @@ static int btrfs_link(struct dentry *old_dentry, stru= ct inode *dir, inode_set_ctime_current(inode); =20 ret =3D btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), - &fname.disk_name, true, index); + &fname.disk_name, true, index, NULL); if (ret) goto fail; =20 @@ -8512,14 +8515,14 @@ static int btrfs_rename_exchange(struct inode *old_= dir, } =20 ret =3D btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode), - new_name, false, old_idx); + new_name, false, old_idx, NULL); if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); goto out_fail; } =20 ret =3D btrfs_add_link(trans, BTRFS_I(old_dir), BTRFS_I(new_inode), - old_name, false, new_idx); + old_name, false, new_idx, NULL); if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); goto out_fail; @@ -8592,6 +8595,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, struct inode *new_inode =3D d_inode(new_dentry); struct inode *old_inode =3D d_inode(old_dentry); struct btrfs_rename_ctx rename_ctx; + struct btrfs_dir_index_prealloc *prealloc =3D NULL; u64 index =3D 0; int ret; int ret2; @@ -8715,6 +8719,24 @@ static int btrfs_rename(struct mnt_idmap *idmap, if (ret) goto out_fail; =20 + /* + * When not overwriting an existing entry, pre-allocate the delayed + * dir index now so that ENOMEM is returned before any btree + * modifications. For the overwrite case, too many btree changes + * have already happened by the time btrfs_add_link() is called. + */ + if (!new_inode) { + prealloc =3D btrfs_prealloc_delayed_dir_index( + BTRFS_I(new_dir), + new_fname.disk_name.name, + new_fname.disk_name.len); + if (IS_ERR(prealloc)) { + ret =3D PTR_ERR(prealloc); + prealloc =3D NULL; + goto out_fail; + } + } + BTRFS_I(old_inode)->dir_index =3D 0ULL; if (unlikely(old_ino =3D=3D BTRFS_FIRST_FREE_OBJECTID)) { /* force full log commit if subvolume involved. */ @@ -8810,7 +8832,8 @@ static int btrfs_rename(struct mnt_idmap *idmap, } =20 ret =3D btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode), - &new_fname.disk_name, false, index); + &new_fname.disk_name, false, index, prealloc); + prealloc =3D NULL; if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); goto out_fail; @@ -8835,6 +8858,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, } } out_fail: + btrfs_free_delayed_dir_index_prealloc(trans, prealloc); if (logs_pinned) { btrfs_end_log_trans(root); btrfs_end_log_trans(dest); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 7ba7b6098aa5..a043611f82e1 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1683,7 +1683,7 @@ static noinline int add_inode_ref(struct walk_control= *wc) } =20 /* insert our name */ - ret =3D btrfs_add_link(trans, dir, inode, &name, false, ref_index); + ret =3D btrfs_add_link(trans, dir, inode, &name, false, ref_index, NULL= ); if (ret) { btrfs_abort_log_replay(wc, ret, "failed to add link for inode %llu in dir %llu ref_index %llu name %.*s ro= ot %llu", @@ -2031,7 +2031,7 @@ static noinline int insert_one_name(struct btrfs_tran= s_handle *trans, return PTR_ERR(dir); } =20 - ret =3D btrfs_add_link(trans, dir, inode, name, true, index); + ret =3D btrfs_add_link(trans, dir, inode, name, true, index, NULL); =20 /* FIXME, put inode into FIXUP list */ =20 --=20 2.55.0