From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75576CCA490 for ; Tue, 7 Jun 2022 18:37:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353068AbiFGSgC (ORCPT ); Tue, 7 Jun 2022 14:36:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350386AbiFGSA4 (ORCPT ); Tue, 7 Jun 2022 14:00:56 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29C5B138B45; Tue, 7 Jun 2022 10:43:06 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A31676146F; Tue, 7 Jun 2022 17:43:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A96C3C385A5; Tue, 7 Jun 2022 17:43:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1654623786; bh=rNhPrWpWb5Rkbor0Yta50Ausbw27F01ediVZYvcfL64=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AuOT6hjBulq34d8XYtlZaz4eOcOQqOivd8w7w5gMQKaaix1YAIUJF1jcpoOb3Hscj EKaWVhCfte3C4dnDkjhaQcnxmTVzi3diZbSnB5r5Ot43Eokd8eKVTUSRi1gCIkBVFe qa1Ai3CbnKHueGwPciYicfDaz1xAIcrMygkIfn9A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Qu Wenruo , David Sterba Subject: [PATCH 5.15 040/667] btrfs: return correct error number for __extent_writepage_io() Date: Tue, 7 Jun 2022 18:55:05 +0200 Message-Id: <20220607164936.002584485@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220607164934.766888869@linuxfoundation.org> References: <20220607164934.766888869@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Qu Wenruo commit 44e5801fada6925d2bba1987c7b59cbcc9d0d592 upstream. [BUG] If we hit an error from submit_extent_page() inside __extent_writepage_io(), we could still return 0 to the caller, and even trigger the warning in btrfs_page_assert_not_dirty(). [CAUSE] In __extent_writepage_io(), if we hit an error from submit_extent_page(), we will just clean up the range and continue. This is completely fine for regular PAGE_SIZE == sectorsize, as we can only hit one sector in one page, thus after the error we're ensured to exit and @ret will be saved. But for subpage case, we may have other dirty subpage range in the page, and in the next loop, we may succeeded submitting the next range. In that case, @ret will be overwritten, and we return 0 to the caller, while we have hit some error. [FIX] Introduce @has_error and @saved_ret to record the first error we hit, so we will never forget what error we hit. CC: stable@vger.kernel.org # 5.15+ Signed-off-by: Qu Wenruo Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/extent_io.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3902,10 +3902,12 @@ static noinline_for_stack int __extent_w u64 extent_offset; u64 block_start; struct extent_map *em; + int saved_ret = 0; int ret = 0; int nr = 0; u32 opf = REQ_OP_WRITE; const unsigned int write_flags = wbc_to_write_flags(wbc); + bool has_error = false; bool compressed; ret = btrfs_writepage_cow_fixup(page); @@ -3956,6 +3958,9 @@ static noinline_for_stack int __extent_w if (IS_ERR_OR_NULL(em)) { btrfs_page_set_error(fs_info, page, cur, end - cur + 1); ret = PTR_ERR_OR_ZERO(em); + has_error = true; + if (!saved_ret) + saved_ret = ret; break; } @@ -4019,6 +4024,10 @@ static noinline_for_stack int __extent_w end_bio_extent_writepage, 0, 0, false); if (ret) { + has_error = true; + if (!saved_ret) + saved_ret = ret; + btrfs_page_set_error(fs_info, page, cur, iosize); if (PageWriteback(page)) btrfs_page_clear_writeback(fs_info, page, cur, @@ -4032,8 +4041,10 @@ static noinline_for_stack int __extent_w * If we finish without problem, we should not only clear page dirty, * but also empty subpage dirty bits */ - if (!ret) + if (!has_error) btrfs_page_assert_not_dirty(fs_info, page); + else + ret = saved_ret; *nr_ret = nr; return ret; }