From nobody Wed Dec 17 00:15:54 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 019FEC7618E for ; Mon, 24 Apr 2023 03:40:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230403AbjDXDkK (ORCPT ); Sun, 23 Apr 2023 23:40:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230398AbjDXDjp (ORCPT ); Sun, 23 Apr 2023 23:39:45 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A7A02136; Sun, 23 Apr 2023 20:39:44 -0700 (PDT) Received: from dggpeml500021.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Q4W4S6KqSznf6p; Mon, 24 Apr 2023 11:35:52 +0800 (CST) Received: from huawei.com (10.175.127.227) by dggpeml500021.china.huawei.com (7.185.36.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Mon, 24 Apr 2023 11:39:42 +0800 From: Baokun Li To: CC: , , , , , , , , Subject: [PATCH v4 06/12] ext4: using nofail preallocation in ext4_es_remove_extent() Date: Mon, 24 Apr 2023 11:38:40 +0800 Message-ID: <20230424033846.4732-7-libaokun1@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230424033846.4732-1-libaokun1@huawei.com> References: <20230424033846.4732-1-libaokun1@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To dggpeml500021.china.huawei.com (7.185.36.21) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" If __es_remove_extent() returns an error it means that when splitting extent, allocating an extent that must be kept failed, where returning an error directly would cause the extent tree to be inconsistent. So we use GFP_NOFAIL to pre-allocate an extent_status and pass it to __es_remove_extent() to avoid this problem. In addition, since the allocated memory is outside the i_es_lock, the extent_status tree may change and the pre-allocated extent_status is no longer needed, so we release the pre-allocated extent_status when es->es_len is not initialized. Suggested-by: Jan Kara Signed-off-by: Baokun Li Reviewed-by: Jan Kara --- fs/ext4/extents_status.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 7219116e0d68..f4d50cd501fc 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -1458,6 +1458,7 @@ int ext4_es_remove_extent(struct inode *inode, ext4_l= blk_t lblk, ext4_lblk_t end; int err =3D 0; int reserved =3D 0; + struct extent_status *es =3D NULL; =20 if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) return 0; @@ -1472,17 +1473,25 @@ int ext4_es_remove_extent(struct inode *inode, ext4= _lblk_t lblk, end =3D lblk + len - 1; BUG_ON(end < lblk); =20 +retry: + if (err && !es) + es =3D __es_alloc_extent(true); /* * ext4_clear_inode() depends on us taking i_es_lock unconditionally * so that we are sure __es_shrink() is done with the inode before it * is reclaimed. */ write_lock(&EXT4_I(inode)->i_es_lock); - err =3D __es_remove_extent(inode, lblk, end, &reserved, NULL); + err =3D __es_remove_extent(inode, lblk, end, &reserved, es); + if (es && !es->es_len) + __es_free_extent(es); write_unlock(&EXT4_I(inode)->i_es_lock); + if (err) + goto retry; + ext4_es_print_tree(inode); ext4_da_release_space(inode, reserved); - return err; + return 0; } =20 static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, --=20 2.31.1