Received: by 2002:a05:7412:b995:b0:f9:9502:5bb8 with SMTP id it21csp15838rdb; Thu, 21 Dec 2023 01:07:44 -0800 (PST) X-Google-Smtp-Source: AGHT+IH7hNdpwREJWjK8CsHQ3HRhxl5qnTnS/L+u7r3jnpz6C7pipclR6xKL6u24UzD5wwAaOrfb X-Received: by 2002:ad4:5aa5:0:b0:67f:4a8d:1618 with SMTP id u5-20020ad45aa5000000b0067f4a8d1618mr7735084qvg.119.1703149664179; Thu, 21 Dec 2023 01:07:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703149664; cv=none; d=google.com; s=arc-20160816; b=JIV/0aQ8hGAOR5zRkH4dN2v38f8JsLKnQKzYb4BBNhDjqYgELvRskY6Bt+idQPRC+G Hw9GgiqVDUYWLKIWfqEKzA2jKHOpAI4vru7ralGw1LBmCr6Rpqzkv+KOisigvKZBRp5g fXGwInJ9l8TqZ49NyKZjV4WXXZmQ3wU5D3UsvYFAyoeT7mSER3so5nj1K0Z8xrlG3Nyw 4Jk8GB/UtDHwKZ0OmTLwCJJcmH0EG2dNezFWn0LmeGXwuNQJ36Mb5ObN40SlZbro0rgR K0MptObgGycFh1yuARwvYo/x0XC1CXjKiMunVZzvdTD5Uq4xQrzwCS2Xu3Pi/HZDh8q1 KChQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=kjWeW2ylVJBfyye8quSWl7OIVOQuOBMQ0Z1QS8iSO/4=; fh=ra0zcfFNH7JWn2tyKhchpyMoSpFA+1HuRrgbaLqrjLs=; b=H5qfBmR+qGXAlP4cKO2jWifvHeCbwcmsgktEHjcENXXF3qFcKH9pHiSrL5TCYyN6HL vwJeiWhx7CDlvWjWqfCsxiHypvJUI2GS44bETiWF8PCcm2SAc9pDvYHn1sn3QtuBGTp9 GCmnVVStXyu1W/1A/Zx4ej3HucCGuUNvJLRyZYS4ooWOVu9oEj3jaMvKMXCzHbVPv+Ix zsTLUZ8NVfCCWxKtofvqJWzufgFNjw6cqVSeK9qaWpylc3BcLYLqfyu+ifREws5osLG2 Kl9BWmQf0K8X1oV4jjJI6vycUvLZTKB05gl/VMf++axK14inOTWuXIyLi+jRpNshIEK+ bFvw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-ext4+bounces-527-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-ext4+bounces-527-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id o8-20020a0c8c48000000b0067f64f06cf5si1606458qvb.474.2023.12.21.01.07.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Dec 2023 01:07:44 -0800 (PST) Received-SPF: pass (google.com: domain of linux-ext4+bounces-527-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-ext4+bounces-527-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-ext4+bounces-527-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id D3E371C2320C for ; Thu, 21 Dec 2023 09:07:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4753E51C2A; Thu, 21 Dec 2023 09:00:57 +0000 (UTC) X-Original-To: linux-ext4@vger.kernel.org Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (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 2D77650260; Thu, 21 Dec 2023 09:00:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.93.142]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTP id 4SwktC0cvjz4f3kJs; Thu, 21 Dec 2023 17:00:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 6B3371A01B3; Thu, 21 Dec 2023 17:00:52 +0800 (CST) Received: from huaweicloud.com (unknown [10.175.104.67]) by APP1 (Coremail) with SMTP id cCh0CgCn9QvB_oNlLR7vEA--.33384S4; Thu, 21 Dec 2023 17:00:51 +0800 (CST) From: Yu Kuai To: axboe@kernel.dk, roger.pau@citrix.com, colyli@suse.de, kent.overstreet@gmail.com, joern@lazybastard.org, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, sth@linux.ibm.com, hoeppner@linux.ibm.com, hca@linux.ibm.com, gor@linux.ibm.com, agordeev@linux.ibm.com, jejb@linux.ibm.com, martin.petersen@oracle.com, clm@fb.com, josef@toxicpanda.com, dsterba@suse.com, viro@zeniv.linux.org.uk, brauner@kernel.org, nico@fluxnic.net, xiang@kernel.org, chao@kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.com, konishi.ryusuke@gmail.com, willy@infradead.org, akpm@linux-foundation.org, hare@suse.de, p.raghav@samsung.com Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, xen-devel@lists.xenproject.org, linux-bcache@vger.kernel.org, linux-mtd@lists.infradead.org, linux-s390@vger.kernel.org, linux-scsi@vger.kernel.org, linux-bcachefs@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-erofs@lists.ozlabs.org, linux-ext4@vger.kernel.org, linux-nilfs@vger.kernel.org, yukuai3@huawei.com, yukuai1@huaweicloud.com, yi.zhang@huawei.com, yangerkun@huawei.com Subject: [PATCH RFC v3 for-6.8/block 14/17] buffer: add a new helper to read sb block Date: Thu, 21 Dec 2023 16:58:53 +0800 Message-Id: <20231221085853.1770062-1-yukuai1@huaweicloud.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231221085712.1766333-1-yukuai1@huaweicloud.com> References: <20231221085712.1766333-1-yukuai1@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-ext4@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:cCh0CgCn9QvB_oNlLR7vEA--.33384S4 X-Coremail-Antispam: 1UD129KBjvJXoW3AFyUCF4kKryrJrW3trWrXwb_yoW7Ww13pr 98Kay3trWDKFyaqF1xtwn8Jr13t3Z2v3W8CayfJ3s3ArWUGrn3XF9rGr129FWFyr9rXry5 XFW5CrWfCr1UWFDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUv014x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4U JVW0owA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oV Cq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0 I7IYx2IY67AKxVWUAVWUtwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r 4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628v n2kIc2xKxwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F4 0E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Wrv_Gr1U MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I 0E14v26F4UJVW0owCI42IY6xAIw20EY4v20xvaj40_JFI_Gr1lIxAIcVC2z280aVAFwI0_ Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVWxJr0_GcJvcSsGvfC2KfnxnUUI43ZEXa7VUb ZNVDUUUUU== X-CM-SenderInfo: 51xn3trlr6x35dzhxuhorxvhhfrp/ From: Yu Kuai Unlike __bread_gfp(), ext4 has special handing while reading sb block: 1) __GFP_NOFAIL is not set, and memory allocation can fail; 2) If buffer write failed before, set buffer uptodate and don't read block from disk; 3) REQ_META is set for all IO, and REQ_PRIO is set for reading xattr; 4) If failed, return error ptr instead of NULL; This patch add a new helper __bread_gfp2() that will match above 2 and 3( 1 will be used, and 4 will still be encapsulated by ext4), and prepare to prevent calling mapping_gfp_constraint() directly on bd_inode->i_mapping in ext4. Signed-off-by: Yu Kuai --- fs/buffer.c | 68 ++++++++++++++++++++++++++----------- include/linux/buffer_head.h | 18 +++++++++- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 967f34b70aa8..188bd36c9fea 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1255,16 +1255,19 @@ void __bforget(struct buffer_head *bh) } EXPORT_SYMBOL(__bforget); -static struct buffer_head *__bread_slow(struct buffer_head *bh) +static struct buffer_head *__bread_slow(struct buffer_head *bh, + blk_opf_t op_flags, + bool check_write_error) { lock_buffer(bh); - if (buffer_uptodate(bh)) { + if (buffer_uptodate(bh) || + (check_write_error && buffer_uptodate_or_error(bh))) { unlock_buffer(bh); return bh; } else { get_bh(bh); bh->b_end_io = end_buffer_read_sync; - submit_bh(REQ_OP_READ, bh); + submit_bh(REQ_OP_READ | op_flags, bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) return bh; @@ -1445,6 +1448,31 @@ void __breadahead(struct block_device *bdev, sector_t block, unsigned size) } EXPORT_SYMBOL(__breadahead); +static struct buffer_head * +bread_gfp(struct block_device *bdev, sector_t block, unsigned int size, + blk_opf_t op_flags, gfp_t gfp, bool check_write_error) +{ + struct buffer_head *bh; + + gfp |= mapping_gfp_constraint(bdev->bd_inode->i_mapping, ~__GFP_FS); + + /* + * Prefer looping in the allocator rather than here, at least that + * code knows what it's doing. + */ + gfp |= __GFP_NOFAIL; + + bh = bdev_getblk(bdev, block, size, gfp); + if (unlikely(!bh)) + return NULL; + + if (buffer_uptodate(bh) || + (check_write_error && buffer_uptodate_or_error(bh))) + return bh; + + return __bread_slow(bh, op_flags, check_write_error); +} + /** * __bread_gfp() - reads a specified block and returns the bh * @bdev: the block_device to read from @@ -1458,27 +1486,27 @@ EXPORT_SYMBOL(__breadahead); * It returns NULL if the block was unreadable. */ struct buffer_head * -__bread_gfp(struct block_device *bdev, sector_t block, - unsigned size, gfp_t gfp) +__bread_gfp(struct block_device *bdev, sector_t block, unsigned int size, + gfp_t gfp) { - struct buffer_head *bh; - - gfp |= mapping_gfp_constraint(bdev->bd_inode->i_mapping, ~__GFP_FS); - - /* - * Prefer looping in the allocator rather than here, at least that - * code knows what it's doing. - */ - gfp |= __GFP_NOFAIL; - - bh = bdev_getblk(bdev, block, size, gfp); - - if (likely(bh) && !buffer_uptodate(bh)) - bh = __bread_slow(bh); - return bh; + return bread_gfp(bdev, block, size, 0, gfp, false); } EXPORT_SYMBOL(__bread_gfp); +/* + * This works like __bread_gfp() except: + * 1) If buffer write failed before, set buffer uptodate and don't read + * block from disk; + * 2) Caller can pass in additional op_flags like REQ_META; + */ +struct buffer_head * +__bread_gfp2(struct block_device *bdev, sector_t block, unsigned int size, + blk_opf_t op_flags, gfp_t gfp) +{ + return bread_gfp(bdev, block, size, op_flags, gfp, true); +} +EXPORT_SYMBOL(__bread_gfp2); + static void __invalidate_bh_lrus(struct bh_lru *b) { int i; diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 5f23ee599889..751b2744b4ae 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -171,6 +171,18 @@ static __always_inline int buffer_uptodate(const struct buffer_head *bh) return test_bit_acquire(BH_Uptodate, &bh->b_state); } +static __always_inline int buffer_uptodate_or_error(struct buffer_head *bh) +{ + /* + * If the buffer has the write error flag, data was failed to write + * out in the block. In this case, set buffer uptodate to prevent + * reading old data. + */ + if (buffer_write_io_error(bh)) + set_buffer_uptodate(bh); + return buffer_uptodate(bh); +} + static inline unsigned long bh_offset(const struct buffer_head *bh) { return (unsigned long)(bh)->b_data & (page_size(bh->b_page) - 1); @@ -231,7 +243,11 @@ void __brelse(struct buffer_head *); void __bforget(struct buffer_head *); void __breadahead(struct block_device *, sector_t block, unsigned int size); struct buffer_head *__bread_gfp(struct block_device *, - sector_t block, unsigned size, gfp_t gfp); + sector_t block, unsigned int size, gfp_t gfp); +struct buffer_head *__bread_gfp2(struct block_device *bdev, sector_t block, + unsigned int size, blk_opf_t op_flags, + gfp_t gfp); + struct buffer_head *alloc_buffer_head(gfp_t gfp_flags); void free_buffer_head(struct buffer_head * bh); void unlock_buffer(struct buffer_head *bh); -- 2.39.2