From nobody Thu Apr 2 22:13:14 2026 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 AE5713793DB; Thu, 26 Mar 2026 11:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523755; cv=none; b=idu/sHZCABHJyPd7r2cZZoQ3zIoZeglPJPDZiZATi2ovuokG9sBH5ILEMLQrzXBpIOVA4CRGXeSxYzuYnS5Hl6RQwhOxY/rrG1HGo/aCWvomLSXDvxiCk/BIfnQ9Kb/hXDpeHvW9hf2GBGAprwBC/n7KgxxKc2L7Q8Vqu4cdRMU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523755; c=relaxed/simple; bh=viFvCHynwN2QwKfgVv4CMz86s7mPdhW8AzLlTm4Rt7I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=afgoLmF5hfrXErfoL2JEsPJImF1KTKMmvU3pzI2YpZKnuZa7HAULhuTI/rApgeugWh7xw3KcTbuPfxI60hAUGz28uab+DKFSn3F/2dZysaFeXyJP/Ex0m10sptOV1+X6S3SulB8WBRKHRlbvZNLcBdeFjGFJDUO5WsZU3bvYB30= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmT590ZzYQv2F; Thu, 26 Mar 2026 19:15:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id A5A2540574; Thu, 26 Mar 2026 19:15:49 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S5; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 01/11] ext4: add did_zero output parameter to ext4_block_zero_page_range() Date: Thu, 26 Mar 2026 19:10:44 +0800 Message-ID: <20260326111054.907252-2-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S5 X-Coremail-Antispam: 1UD129KBjvJXoWxCF17XryfAw18KF1rKw15Jwb_yoW5uw1xpr y5t345ur47u34q9F4xWF1jvr1Sk3Z3GFW8W3y3G3s0v3yIq3WxKF95K3WFvF4jg3y7Xay0 qF4Yy3y2gw1UArJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUm014x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0x vEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVj vjDU0xZFpf9x0JU4OJ5UUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Add a bool *did_zero output parameter to ext4_block_zero_page_range() and __ext4_block_zero_page_range(). The parameter reports whether a partial block was zeroed out, which is needed for the upcoming iomap buffered I/O conversion. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/inode.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index af6d1759c8de..1c9474d5d11d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4003,7 +4003,8 @@ void ext4_set_aops(struct inode *inode) * racing writeback can come later and flush the stale pagecache to disk. */ static int __ext4_block_zero_page_range(handle_t *handle, - struct address_space *mapping, loff_t from, loff_t length) + struct address_space *mapping, loff_t from, loff_t length, + bool *did_zero) { unsigned int offset, blocksize, pos; ext4_lblk_t iblock; @@ -4091,6 +4092,8 @@ static int __ext4_block_zero_page_range(handle_t *han= dle, err =3D ext4_jbd2_inode_add_write(handle, inode, from, length); } + if (!err && did_zero) + *did_zero =3D true; =20 unlock: folio_unlock(folio); @@ -4106,7 +4109,8 @@ static int __ext4_block_zero_page_range(handle_t *han= dle, * that corresponds to 'from' */ static int ext4_block_zero_page_range(handle_t *handle, - struct address_space *mapping, loff_t from, loff_t length) + struct address_space *mapping, loff_t from, loff_t length, + bool *did_zero) { struct inode *inode =3D mapping->host; unsigned blocksize =3D inode->i_sb->s_blocksize; @@ -4120,10 +4124,11 @@ static int ext4_block_zero_page_range(handle_t *han= dle, length =3D max; =20 if (IS_DAX(inode)) { - return dax_zero_range(inode, from, length, NULL, + return dax_zero_range(inode, from, length, did_zero, &ext4_iomap_ops); } - return __ext4_block_zero_page_range(handle, mapping, from, length); + return __ext4_block_zero_page_range(handle, mapping, from, length, + did_zero); } =20 /* @@ -4146,7 +4151,7 @@ static int ext4_block_truncate_page(handle_t *handle, blocksize =3D i_blocksize(inode); length =3D blocksize - (from & (blocksize - 1)); =20 - return ext4_block_zero_page_range(handle, mapping, from, length); + return ext4_block_zero_page_range(handle, mapping, from, length, NULL); } =20 int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, @@ -4169,13 +4174,13 @@ int ext4_zero_partial_blocks(handle_t *handle, stru= ct inode *inode, if (start =3D=3D end && (partial_start || (partial_end !=3D sb->s_blocksize - 1))) { err =3D ext4_block_zero_page_range(handle, mapping, - lstart, length); + lstart, length, NULL); return err; } /* Handle partial zero out on the start of the range */ if (partial_start) { - err =3D ext4_block_zero_page_range(handle, mapping, - lstart, sb->s_blocksize); + err =3D ext4_block_zero_page_range(handle, mapping, lstart, + sb->s_blocksize, NULL); if (err) return err; } @@ -4183,7 +4188,7 @@ int ext4_zero_partial_blocks(handle_t *handle, struct= inode *inode, if (partial_end !=3D sb->s_blocksize - 1) err =3D ext4_block_zero_page_range(handle, mapping, byte_end - partial_end, - partial_end + 1); + partial_end + 1, NULL); return err; } =20 --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 AE65C37B3F1; Thu, 26 Mar 2026 11:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523755; cv=none; b=MFqP7bF+bAz/U2KGVJRvjB3h4uZ4FhPhrwj3ZJWJ4mxlrYgDOSBmKYovNUJsFzf0nPvX9D/FzM4t7rOQbwHLok+8dHYvMWiSCTAHlEg6JTKsOPNO8+RNo7X2/26fOTSQwQ8f28sxYkK1vF1v6c6l9HC2hYaIP8D+Q6xsjjV2PN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523755; c=relaxed/simple; bh=I4XHiujXs7qhKUx4JhAgRX0qgoLkJvpiinPfQkkp0yI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=a35m6ZHIN5Tq20KZlcr79qxdHYgslEtz4jiVCguQTQROsQTOz8Rvh+2u2235IM+UBB19r1Oz6iwJgWugof5K6qRr6urKRrwuxc88InrvnVguxSgXpmkta3rRWi2CkmvlYx7WdwGRg6xTGDt+Pqs3Ihn0+3SFHQtYS5pVEDamnxI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=none smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 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.163.170]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmT5cJdzYQv6h; Thu, 26 Mar 2026 19:15:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id B4D7340572; Thu, 26 Mar 2026 19:15:49 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S6; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 02/11] ext4: rename and extend ext4_block_truncate_page() Date: Thu, 26 Mar 2026 19:10:45 +0800 Message-ID: <20260326111054.907252-3-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S6 X-Coremail-Antispam: 1UD129KBjvJXoW3XF18Ar1kWw1fCF48tw15XFb_yoW7uw15p3 43Aw15Cr1j9ryq9F4IgFsrZr4a93W8GF4UWrWfKryrZasrXF1xKF1DtF1FyFWjqrWxXa1j qFs8KrWjgw17J3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmY14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIev Ja73UjIFyTuYvjfUOdgAUUUUU X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Rename ext4_block_truncate_page() to ext4_block_zero_eof() and extend its signature to accept an explicit 'end' offset instead of calculating the block boundary. This helper function now can replace all cases requiring zeroing of the partial EOF block, including the append buffered write paths in ext4_*_write_end(). Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/ext4.h | 2 ++ fs/ext4/extents.c | 4 ++-- fs/ext4/inode.c | 43 ++++++++++++++++++++++++------------------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 293f698b7042..c62459ef9796 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3099,6 +3099,8 @@ extern int ext4_chunk_trans_blocks(struct inode *, in= t nrblocks); extern int ext4_chunk_trans_extent(struct inode *inode, int nrblocks); extern int ext4_meta_trans_blocks(struct inode *inode, int lblocks, int pextents); +extern int ext4_block_zero_eof(handle_t *handle, struct inode *inode, + loff_t from, loff_t end); extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t lend); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ae3804f36535..a265070c1b79 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4625,8 +4625,8 @@ static int ext4_alloc_file_blocks(struct file *file, = ext4_lblk_t offset, inode_get_ctime(inode)); if (epos > old_size) { pagecache_isize_extended(inode, old_size, epos); - ext4_zero_partial_blocks(handle, inode, - old_size, epos - old_size); + ext4_block_zero_eof(handle, inode, old_size, + epos); } } ret2 =3D ext4_mark_inode_dirty(handle, inode); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1c9474d5d11d..5b601b8a4453 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1458,7 +1458,7 @@ static int ext4_write_end(const struct kiocb *iocb, =20 if (old_size < pos && !verity) { pagecache_isize_extended(inode, old_size, pos); - ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size); + ext4_block_zero_eof(handle, inode, old_size, pos); } /* * Don't mark the inode dirty under folio lock. First, it unnecessarily @@ -1576,7 +1576,7 @@ static int ext4_journalled_write_end(const struct kio= cb *iocb, =20 if (old_size < pos && !verity) { pagecache_isize_extended(inode, old_size, pos); - ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size); + ext4_block_zero_eof(handle, inode, old_size, pos); } =20 if (size_changed) { @@ -3252,7 +3252,7 @@ static int ext4_da_do_write_end(struct address_space = *mapping, if (IS_ERR(handle)) return PTR_ERR(handle); if (zero_len) - ext4_zero_partial_blocks(handle, inode, old_size, zero_len); + ext4_block_zero_eof(handle, inode, old_size, pos); ext4_mark_inode_dirty(handle, inode); ext4_journal_stop(handle); =20 @@ -4132,26 +4132,31 @@ static int ext4_block_zero_page_range(handle_t *han= dle, } =20 /* - * ext4_block_truncate_page() zeroes out a mapping from file offset `from' - * up to the end of the block which corresponds to `from'. - * This required during truncate. We need to physically zero the tail end - * of that block so it doesn't yield old data if the file is later grown. + * Zero out a mapping from file offset 'from' up to the end of the block + * which corresponds to 'from' or to the given 'end' inside this block. + * This required during truncate up and performing append writes. We need + * to physically zero the tail end of that block so it doesn't yield old + * data if the file is grown. */ -static int ext4_block_truncate_page(handle_t *handle, - struct address_space *mapping, loff_t from) +int ext4_block_zero_eof(handle_t *handle, struct inode *inode, + loff_t from, loff_t end) { - unsigned length; - unsigned blocksize; - struct inode *inode =3D mapping->host; + unsigned int blocksize =3D i_blocksize(inode); + unsigned int offset; + loff_t length =3D end - from; =20 + offset =3D from & (blocksize - 1); + if (!offset || from >=3D end) + return 0; /* If we are processing an encrypted inode during orphan list handling */ if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode)) return 0; =20 - blocksize =3D i_blocksize(inode); - length =3D blocksize - (from & (blocksize - 1)); + if (length > blocksize - offset) + length =3D blocksize - offset; =20 - return ext4_block_zero_page_range(handle, mapping, from, length, NULL); + return ext4_block_zero_page_range(handle, inode->i_mapping, from, + length, NULL); } =20 int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, @@ -4500,7 +4505,6 @@ int ext4_truncate(struct inode *inode) unsigned int credits; int err =3D 0, err2; handle_t *handle; - struct address_space *mapping =3D inode->i_mapping; =20 /* * There is a possibility that we're either freeing the inode @@ -4543,8 +4547,9 @@ int ext4_truncate(struct inode *inode) goto out_trace; } =20 + /* Zero to the end of the block containing i_size */ if (inode->i_size & (inode->i_sb->s_blocksize - 1)) - ext4_block_truncate_page(handle, mapping, inode->i_size); + ext4_block_zero_eof(handle, inode, inode->i_size, LLONG_MAX); =20 /* * We add the inode to the orphan list, so that if this @@ -5921,8 +5926,8 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dent= ry *dentry, inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); if (oldsize & (inode->i_sb->s_blocksize - 1)) - ext4_block_truncate_page(handle, - inode->i_mapping, oldsize); + ext4_block_zero_eof(handle, inode, + oldsize, LLONG_MAX); } =20 if (shrink) --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 AE74F37C91E; Thu, 26 Mar 2026 11:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523754; cv=none; b=GT4zBaZAJZw0Qf/EKOFVIhxiFDD9ec1sner9VtqKMTBob7pyh5IbinqEOc4PnsoXXCImcmGiU92aDCWKNFs33RW9PiXcWt6flpyDFIu4p7h233LA7MhCk3RP+c/RIqrRDnT0ceQN4bBBREz9f1W8Lh4pIyPfn8EBV0KWRnAVkdQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523754; c=relaxed/simple; bh=YXS8lHEC3Jdo2j5cSBN7EJ0ZzFqzocgiimSao+12Ztg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KCdl04ikEeaDev1Zo73du6fvi60XHsUeyl9liuDk5OAdXszE905RNS6yeBodQmybz7DOtpz7HawclKq3gQhSO6VnEtb+Gck/Gw/wVOWi12r7HhTiQBlFEf7zeRMagepRsRkCL+H/8ULpDQlPPa65aIb1nefO87nJntyvYf/4Aqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=none smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 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.163.170]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmT6MCjzYQv3Z; Thu, 26 Mar 2026 19:15:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id CFF904056F; Thu, 26 Mar 2026 19:15:49 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S7; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 03/11] ext4: factor out journalled block zeroing range Date: Thu, 26 Mar 2026 19:10:46 +0800 Message-ID: <20260326111054.907252-4-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S7 X-Coremail-Antispam: 1UD129KBjvJXoWxur18Jr4kCryrtryUJw4Utwb_yoW7JF13pr y3K3srZrW7WF9FgF4Sq3W7Xr1aka4rGrW8WFyxG3savayYqFn3KF1UK3WSvF45tr43G3W0 qF4Yy34j93WDtrDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmY14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JrWl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIev Ja73UjIFyTuYvjfUO_MaUUUUU X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Refactor __ext4_block_zero_page_range() by separating the block zeroing operations for ordered data mode and journal data mode into two distinct functions: - ext4_block_do_zero_range(): handles non-journal data mode with ordered data support - ext4_block_journalled_zero_range(): handles journal data mode Also extract a common helper, ext4_load_tail_bh(), to handle buffer head and folio retrieval, along with the associated error handling. This prepares for converting the partial block zero range to the iomap infrastructure. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/inode.c | 98 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5b601b8a4453..1d6eb3ff437e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4002,13 +4002,11 @@ void ext4_set_aops(struct inode *inode) * ext4_punch_hole, etc) which needs to be properly zeroed out. Otherwise a * racing writeback can come later and flush the stale pagecache to disk. */ -static int __ext4_block_zero_page_range(handle_t *handle, - struct address_space *mapping, loff_t from, loff_t length, - bool *did_zero) +static struct buffer_head *ext4_load_tail_bh(struct inode *inode, loff_t f= rom) { unsigned int offset, blocksize, pos; ext4_lblk_t iblock; - struct inode *inode =3D mapping->host; + struct address_space *mapping =3D inode->i_mapping; struct buffer_head *bh; struct folio *folio; int err =3D 0; @@ -4017,7 +4015,7 @@ static int __ext4_block_zero_page_range(handle_t *han= dle, FGP_LOCK | FGP_ACCESSED | FGP_CREAT, mapping_gfp_constraint(mapping, ~__GFP_FS)); if (IS_ERR(folio)) - return PTR_ERR(folio); + return ERR_CAST(folio); =20 blocksize =3D inode->i_sb->s_blocksize; =20 @@ -4069,33 +4067,73 @@ static int __ext4_block_zero_page_range(handle_t *h= andle, } } } - if (ext4_should_journal_data(inode)) { - BUFFER_TRACE(bh, "get write access"); - err =3D ext4_journal_get_write_access(handle, inode->i_sb, bh, - EXT4_JTR_NONE); - if (err) - goto unlock; - } - folio_zero_range(folio, offset, length); + return bh; + +unlock: + folio_unlock(folio); + folio_put(folio); + return err ? ERR_PTR(err) : NULL; +} + +static int ext4_block_do_zero_range(handle_t *handle, struct inode *inode, + loff_t from, loff_t length, bool *did_zero) +{ + struct buffer_head *bh; + struct folio *folio; + int err =3D 0; + + bh =3D ext4_load_tail_bh(inode, from); + if (IS_ERR_OR_NULL(bh)) + return PTR_ERR_OR_ZERO(bh); + + folio =3D bh->b_folio; + folio_zero_range(folio, offset_in_folio(folio, from), length); BUFFER_TRACE(bh, "zeroed end of block"); =20 - if (ext4_should_journal_data(inode)) { - err =3D ext4_dirty_journalled_data(handle, bh); - } else { - mark_buffer_dirty(bh); - /* - * Only the written block requires ordered data to prevent - * exposing stale data. - */ - if (!buffer_unwritten(bh) && !buffer_delay(bh) && - ext4_should_order_data(inode)) - err =3D ext4_jbd2_inode_add_write(handle, inode, from, - length); - } + mark_buffer_dirty(bh); + /* + * Only the written block requires ordered data to prevent exposing + * stale data. + */ + if (ext4_should_order_data(inode) && + !buffer_unwritten(bh) && !buffer_delay(bh)) + err =3D ext4_jbd2_inode_add_write(handle, inode, from, length); if (!err && did_zero) *did_zero =3D true; =20 -unlock: + folio_unlock(folio); + folio_put(folio); + return err; +} + +static int ext4_block_journalled_zero_range(handle_t *handle, + struct inode *inode, loff_t from, loff_t length, bool *did_zero) +{ + struct buffer_head *bh; + struct folio *folio; + int err; + + bh =3D ext4_load_tail_bh(inode, from); + if (IS_ERR_OR_NULL(bh)) + return PTR_ERR_OR_ZERO(bh); + folio =3D bh->b_folio; + + BUFFER_TRACE(bh, "get write access"); + err =3D ext4_journal_get_write_access(handle, inode->i_sb, bh, + EXT4_JTR_NONE); + if (err) + goto out; + + folio_zero_range(folio, offset_in_folio(folio, from), length); + BUFFER_TRACE(bh, "zeroed end of block"); + + err =3D ext4_dirty_journalled_data(handle, bh); + if (err) + goto out; + + if (did_zero) + *did_zero =3D true; +out: folio_unlock(folio); folio_put(folio); return err; @@ -4126,9 +4164,11 @@ static int ext4_block_zero_page_range(handle_t *hand= le, if (IS_DAX(inode)) { return dax_zero_range(inode, from, length, did_zero, &ext4_iomap_ops); + } else if (ext4_should_journal_data(inode)) { + return ext4_block_journalled_zero_range(handle, inode, from, + length, did_zero); } - return __ext4_block_zero_page_range(handle, mapping, from, length, - did_zero); + return ext4_block_do_zero_range(handle, inode, from, length, did_zero); } =20 /* --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 ADFDB36D4F3; Thu, 26 Mar 2026 11:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523757; cv=none; b=je4Wfg3U6KYW6SvVSmK4mbJ2/6DN0RoWnCaGH1oA8B/tR9FOq4sZnILyQ4dUyB83Rxyu2LdaDb8a8mmXXn97jJ1yycRUAEyTM0yruDkX+iZ1ldC9OREiBS8lIiCqnkYkMrIxPEMHmj/zQ6REBsPXabYqMvMVKutFlVzPTVhIUio= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523757; c=relaxed/simple; bh=Vglqg+ydcyhGixaPRDhh554/99k9qa8m4O96LGyBQU4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lEupvXAltmCUZKaFdLRSyBFbLjOdw11ChUjE7jZCnJDL/o9ZOi1P9jakW/7ZLco0Z6okvvfembk005nFOYP4hCbl3uLZFL/tK3/s5Yk1cFFVFibWa0SbXOUSEdsyZeENtHawvo4tMzi2VHhvpixnGBXcn5X5kNu3briSCrSGTVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmT6zvZzYQv6x; Thu, 26 Mar 2026 19:15:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id E1EF140573; Thu, 26 Mar 2026 19:15:49 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S8; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 04/11] ext4: rename ext4_block_zero_page_range() to ext4_block_zero_range() Date: Thu, 26 Mar 2026 19:10:47 +0800 Message-ID: <20260326111054.907252-5-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S8 X-Coremail-Antispam: 1UD129KBjvJXoWxAw1fAr4kZFyfZr4kGw15Jwb_yoW5Aryrpr y3tw15Cr47W34v93WxWF17Xr1Ik3Z3GFWkXrW7G3sYv3y7Xas3tF98K3Z5XF4j93yxXa40 qF4Yyry2gw17AaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnI WIevJa73UjIFyTuYvjfUOyIUUUUUU X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Rename ext4_block_zero_page_range() to ext4_block_zero_range() since the "page" naming is no longer appropriate for current context. Also change its signature to take an inode pointer instead of an address_space. This aligns with the caller ext4_block_zero_eof() and ext4_zero_partial_blocks(). Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/inode.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1d6eb3ff437e..543f7e4a60fa 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4146,11 +4146,9 @@ static int ext4_block_journalled_zero_range(handle_t= *handle, * the end of the block it will be shortened to end of the block * that corresponds to 'from' */ -static int ext4_block_zero_page_range(handle_t *handle, - struct address_space *mapping, loff_t from, loff_t length, - bool *did_zero) +static int ext4_block_zero_range(handle_t *handle, struct inode *inode, + loff_t from, loff_t length, bool *did_zero) { - struct inode *inode =3D mapping->host; unsigned blocksize =3D inode->i_sb->s_blocksize; unsigned int max =3D blocksize - (from & (blocksize - 1)); =20 @@ -4195,15 +4193,13 @@ int ext4_block_zero_eof(handle_t *handle, struct in= ode *inode, if (length > blocksize - offset) length =3D blocksize - offset; =20 - return ext4_block_zero_page_range(handle, inode->i_mapping, from, - length, NULL); + return ext4_block_zero_range(handle, inode, from, length, NULL); } =20 int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t length) { struct super_block *sb =3D inode->i_sb; - struct address_space *mapping =3D inode->i_mapping; unsigned partial_start, partial_end; ext4_fsblk_t start, end; loff_t byte_end =3D (lstart + length - 1); @@ -4218,22 +4214,22 @@ int ext4_zero_partial_blocks(handle_t *handle, stru= ct inode *inode, /* Handle partial zero within the single block */ if (start =3D=3D end && (partial_start || (partial_end !=3D sb->s_blocksize - 1))) { - err =3D ext4_block_zero_page_range(handle, mapping, - lstart, length, NULL); + err =3D ext4_block_zero_range(handle, inode, lstart, + length, NULL); return err; } /* Handle partial zero out on the start of the range */ if (partial_start) { - err =3D ext4_block_zero_page_range(handle, mapping, lstart, - sb->s_blocksize, NULL); + err =3D ext4_block_zero_range(handle, inode, lstart, + sb->s_blocksize, NULL); if (err) return err; } /* Handle partial zero out on the end of the range */ if (partial_end !=3D sb->s_blocksize - 1) - err =3D ext4_block_zero_page_range(handle, mapping, - byte_end - partial_end, - partial_end + 1, NULL); + err =3D ext4_block_zero_range(handle, inode, + byte_end - partial_end, + partial_end + 1, NULL); return err; } =20 --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 AE0CA3750CF; Thu, 26 Mar 2026 11:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523758; cv=none; b=I4YNuzkFDfeX18MrOGWOvvLOXEQ4TLL3+lqQ2S5PlEjJS6/KYEQuzXn9EhPwYud5d2wDYjmx6VbcNptKdKjtayH2a/c60hGC2kqDoPp1I6xcBVgjYp9kaUfCf9Y/wmdOTw6cib/XaB/XJgOrXk4mPs6TMgvPprkgYYwdD2sDvu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523758; c=relaxed/simple; bh=Fy/wrAn7UeduL9im/mFNfm4g1WOZfxbR7ZFljLh3Psw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QYMXapPd+icpsVqcbEplGad2uB4RBJYPUzOGun2t6tYifMx9mCFDFoO/6l0bLBVyTPG5vyZ2Fjefz2/AxjaZk2yTltRIBNtRWN2iKq5DXHJy6MTXglTjfEEw/+OPiDlkb0gCnZXjWpG2wwP7e0Blj94966RrpV5L3Gg3D14tjLg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmV0BDYzYQv75; Thu, 26 Mar 2026 19:15:38 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id F07B74056F; Thu, 26 Mar 2026 19:15:49 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S9; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 05/11] ext4: move ordered data handling out of ext4_block_do_zero_range() Date: Thu, 26 Mar 2026 19:10:48 +0800 Message-ID: <20260326111054.907252-6-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S9 X-Coremail-Antispam: 1UD129KBjvJXoW3JF1UCFy8ZrW5Cr1kuFWxWFg_yoW7KrW3pF y5K345Cr47WF9F9Fs7JF17XF1ak3WfGFW8WrWxGr9Yv3y2qwn7KFyUKryFvF4Yq3y3W3W0 qF45t34jg3W7AaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUma14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsG vfC2KfnxnUUI43ZEXa7VUbPC7UUUUUU== X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Remove the handle parameter from ext4_block_do_zero_range() and move the ordered data handling to ext4_block_zero_eof(). This is necessary for truncate up and append writes across a range extending beyond EOF. The ordered data must be committed before updating i_disksize to prevent exposing stale on-disk data from concurrent post-EOF mmap writes during previous folio writeback or in case of system crash during append writes. This is unnecessary for partial block hole punching because the entire punch operation does not provide atomicity guarantees and can already expose intermediate results in case of crash. Hole punching can only ever expose data that was there before the punch but missed zeroing during append / truncate could expose data that was not visible in the file before the operation. Since ordered data handling is no longer performed inside ext4_zero_partial_blocks(), ext4_punch_hole() no longer needs to attach jinode. This is prepared for the conversion to the iomap infrastructure, which does not use ordered data mode while zeroing post-EOF partial blocks. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/inode.c | 61 ++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 543f7e4a60fa..a480676193f4 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4075,12 +4075,12 @@ static struct buffer_head *ext4_load_tail_bh(struct= inode *inode, loff_t from) return err ? ERR_PTR(err) : NULL; } =20 -static int ext4_block_do_zero_range(handle_t *handle, struct inode *inode, - loff_t from, loff_t length, bool *did_zero) +static int ext4_block_do_zero_range(struct inode *inode, loff_t from, + loff_t length, bool *did_zero, + bool *zero_written) { struct buffer_head *bh; struct folio *folio; - int err =3D 0; =20 bh =3D ext4_load_tail_bh(inode, from); if (IS_ERR_OR_NULL(bh)) @@ -4091,19 +4091,14 @@ static int ext4_block_do_zero_range(handle_t *handl= e, struct inode *inode, BUFFER_TRACE(bh, "zeroed end of block"); =20 mark_buffer_dirty(bh); - /* - * Only the written block requires ordered data to prevent exposing - * stale data. - */ - if (ext4_should_order_data(inode) && - !buffer_unwritten(bh) && !buffer_delay(bh)) - err =3D ext4_jbd2_inode_add_write(handle, inode, from, length); - if (!err && did_zero) + if (did_zero) *did_zero =3D true; + if (zero_written && !buffer_unwritten(bh) && !buffer_delay(bh)) + *zero_written =3D true; =20 folio_unlock(folio); folio_put(folio); - return err; + return 0; } =20 static int ext4_block_journalled_zero_range(handle_t *handle, @@ -4147,7 +4142,8 @@ static int ext4_block_journalled_zero_range(handle_t = *handle, * that corresponds to 'from' */ static int ext4_block_zero_range(handle_t *handle, struct inode *inode, - loff_t from, loff_t length, bool *did_zero) + loff_t from, loff_t length, bool *did_zero, + bool *zero_written) { unsigned blocksize =3D inode->i_sb->s_blocksize; unsigned int max =3D blocksize - (from & (blocksize - 1)); @@ -4166,7 +4162,8 @@ static int ext4_block_zero_range(handle_t *handle, st= ruct inode *inode, return ext4_block_journalled_zero_range(handle, inode, from, length, did_zero); } - return ext4_block_do_zero_range(handle, inode, from, length, did_zero); + return ext4_block_do_zero_range(inode, from, length, did_zero, + zero_written); } =20 /* @@ -4182,6 +4179,9 @@ int ext4_block_zero_eof(handle_t *handle, struct inod= e *inode, unsigned int blocksize =3D i_blocksize(inode); unsigned int offset; loff_t length =3D end - from; + bool did_zero =3D false; + bool zero_written =3D false; + int err; =20 offset =3D from & (blocksize - 1); if (!offset || from >=3D end) @@ -4193,7 +4193,21 @@ int ext4_block_zero_eof(handle_t *handle, struct ino= de *inode, if (length > blocksize - offset) length =3D blocksize - offset; =20 - return ext4_block_zero_range(handle, inode, from, length, NULL); + err =3D ext4_block_zero_range(handle, inode, from, length, + &did_zero, &zero_written); + if (err) + return err; + /* + * It's necessary to order zeroed data before update i_disksize when + * truncating up or performing an append write, because there might be + * exposing stale on-disk data which may caused by concurrent post-EOF + * mmap write during folio writeback. + */ + if (ext4_should_order_data(inode) && + did_zero && zero_written && !IS_DAX(inode)) + err =3D ext4_jbd2_inode_add_write(handle, inode, from, length); + + return err; } =20 int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, @@ -4215,13 +4229,13 @@ int ext4_zero_partial_blocks(handle_t *handle, stru= ct inode *inode, if (start =3D=3D end && (partial_start || (partial_end !=3D sb->s_blocksize - 1))) { err =3D ext4_block_zero_range(handle, inode, lstart, - length, NULL); + length, NULL, NULL); return err; } /* Handle partial zero out on the start of the range */ if (partial_start) { err =3D ext4_block_zero_range(handle, inode, lstart, - sb->s_blocksize, NULL); + sb->s_blocksize, NULL, NULL); if (err) return err; } @@ -4229,7 +4243,7 @@ int ext4_zero_partial_blocks(handle_t *handle, struct= inode *inode, if (partial_end !=3D sb->s_blocksize - 1) err =3D ext4_block_zero_range(handle, inode, byte_end - partial_end, - partial_end + 1, NULL); + partial_end + 1, NULL, NULL); return err; } =20 @@ -4404,17 +4418,6 @@ int ext4_punch_hole(struct file *file, loff_t offset= , loff_t length) end =3D max_end; length =3D end - offset; =20 - /* - * Attach jinode to inode for jbd2 if we do any zeroing of partial - * block. - */ - if (!IS_ALIGNED(offset | end, sb->s_blocksize)) { - ret =3D ext4_inode_attach_jinode(inode); - if (ret < 0) - return ret; - } - - ret =3D ext4_update_disksize_before_punch(inode, offset, length); if (ret) return ret; --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (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 CB1F038239B; Thu, 26 Mar 2026 11:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523755; cv=none; b=cBOEuko+i5i/XBr26KfF0eA6tzGVsisCLt1No0FFCTUh18jQBICHS3dKwRazWmzi8c/WFNmK3etKUt/7lQumRgvRPclV5Wf7/SfGKVVdXL1QAHUzxMju7tFdSTPfxUoCCsveDwy2zrEMYcKMKt4bipFALUtvucuSwS/QNaRHAOo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523755; c=relaxed/simple; bh=9g2x6Qbjyhqkv1VxjCVvNgCfVDAo7IdAPNC9y4TjOd8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IY7axBaHrxXTqNMSZ+8cGT13xVsKBNJQH2bc2GoWUNC/shxgKqjy3cT1HBtXRsH3HCaz+Pa5hH4f1qjPFmWROeucmq7Zw3FgVEffImvvNXhC7izDfeOAD4a16GF1Q9ZR7ATkV2eZnCdc4iiEiCZEvZ2bMbbBnA41FA2SJXsmyic= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4fhLlx6KMWzKHMlj; Thu, 26 Mar 2026 19:15:09 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 0D7704058D; Thu, 26 Mar 2026 19:15:50 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S10; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 06/11] ext4: remove handle parameters from zero partial block functions Date: Thu, 26 Mar 2026 19:10:49 +0800 Message-ID: <20260326111054.907252-7-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S10 X-Coremail-Antispam: 1UD129KBjvJXoW3Xw1rKw47Kr4DGw4rWw17KFg_yoWfur4Dp3 4UJw1UCr43uryv9F4IgF47Zr1a93WxGF48WryfGryFvaykX3Z7KF1DKF1FyF4jqr47Wa10 vF4Yy34jg3WUJ3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUQFxUUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Only journal data mode requires an active journal handle when zeroing partial blocks. Stop passing handle_t *handle to ext4_zero_partial_blocks() and related functions, and make ext4_block_journalled_zero_range() start a handle independently. This change has no practical impact now because all callers invoke these functions within the context of an active handle. It prepares for moving ext4_block_zero_eof() out of an active handle in the next patch, which is a prerequisite for converting block zero range operations to iomap infrastructure. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/ext4.h | 7 ++--- fs/ext4/extents.c | 5 ++-- fs/ext4/inode.c | 71 ++++++++++++++++++++++++++++------------------- 3 files changed, 48 insertions(+), 35 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index c62459ef9796..859ae05339ad 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3099,10 +3099,9 @@ extern int ext4_chunk_trans_blocks(struct inode *, i= nt nrblocks); extern int ext4_chunk_trans_extent(struct inode *inode, int nrblocks); extern int ext4_meta_trans_blocks(struct inode *inode, int lblocks, int pextents); -extern int ext4_block_zero_eof(handle_t *handle, struct inode *inode, - loff_t from, loff_t end); -extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, - loff_t lstart, loff_t lend); +extern int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t en= d); +extern int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, + loff_t length); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index a265070c1b79..753a0f3418a4 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4625,8 +4625,7 @@ static int ext4_alloc_file_blocks(struct file *file, = ext4_lblk_t offset, inode_get_ctime(inode)); if (epos > old_size) { pagecache_isize_extended(inode, old_size, epos); - ext4_block_zero_eof(handle, inode, old_size, - epos); + ext4_block_zero_eof(inode, old_size, epos); } } ret2 =3D ext4_mark_inode_dirty(handle, inode); @@ -4744,7 +4743,7 @@ static long ext4_zero_range(struct file *file, loff_t= offset, } =20 /* Zero out partial block at the edges of the range */ - ret =3D ext4_zero_partial_blocks(handle, inode, offset, len); + ret =3D ext4_zero_partial_blocks(inode, offset, len); if (ret) goto out_handle; =20 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a480676193f4..94c8e8c3984f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1458,7 +1458,7 @@ static int ext4_write_end(const struct kiocb *iocb, =20 if (old_size < pos && !verity) { pagecache_isize_extended(inode, old_size, pos); - ext4_block_zero_eof(handle, inode, old_size, pos); + ext4_block_zero_eof(inode, old_size, pos); } /* * Don't mark the inode dirty under folio lock. First, it unnecessarily @@ -1576,7 +1576,7 @@ static int ext4_journalled_write_end(const struct kio= cb *iocb, =20 if (old_size < pos && !verity) { pagecache_isize_extended(inode, old_size, pos); - ext4_block_zero_eof(handle, inode, old_size, pos); + ext4_block_zero_eof(inode, old_size, pos); } =20 if (size_changed) { @@ -3252,7 +3252,7 @@ static int ext4_da_do_write_end(struct address_space = *mapping, if (IS_ERR(handle)) return PTR_ERR(handle); if (zero_len) - ext4_block_zero_eof(handle, inode, old_size, pos); + ext4_block_zero_eof(inode, old_size, pos); ext4_mark_inode_dirty(handle, inode); ext4_journal_stop(handle); =20 @@ -4101,16 +4101,23 @@ static int ext4_block_do_zero_range(struct inode *i= node, loff_t from, return 0; } =20 -static int ext4_block_journalled_zero_range(handle_t *handle, - struct inode *inode, loff_t from, loff_t length, bool *did_zero) +static int ext4_block_journalled_zero_range(struct inode *inode, loff_t fr= om, + loff_t length, bool *did_zero) { struct buffer_head *bh; struct folio *folio; + handle_t *handle; int err; =20 + handle =3D ext4_journal_start(inode, EXT4_HT_MISC, 1); + if (IS_ERR(handle)) + return PTR_ERR(handle); + bh =3D ext4_load_tail_bh(inode, from); - if (IS_ERR_OR_NULL(bh)) - return PTR_ERR_OR_ZERO(bh); + if (IS_ERR_OR_NULL(bh)) { + err =3D PTR_ERR_OR_ZERO(bh); + goto out_handle; + } folio =3D bh->b_folio; =20 BUFFER_TRACE(bh, "get write access"); @@ -4131,6 +4138,8 @@ static int ext4_block_journalled_zero_range(handle_t = *handle, out: folio_unlock(folio); folio_put(folio); +out_handle: + ext4_journal_stop(handle); return err; } =20 @@ -4141,7 +4150,7 @@ static int ext4_block_journalled_zero_range(handle_t = *handle, * the end of the block it will be shortened to end of the block * that corresponds to 'from' */ -static int ext4_block_zero_range(handle_t *handle, struct inode *inode, +static int ext4_block_zero_range(struct inode *inode, loff_t from, loff_t length, bool *did_zero, bool *zero_written) { @@ -4159,8 +4168,8 @@ static int ext4_block_zero_range(handle_t *handle, st= ruct inode *inode, return dax_zero_range(inode, from, length, did_zero, &ext4_iomap_ops); } else if (ext4_should_journal_data(inode)) { - return ext4_block_journalled_zero_range(handle, inode, from, - length, did_zero); + return ext4_block_journalled_zero_range(inode, from, length, + did_zero); } return ext4_block_do_zero_range(inode, from, length, did_zero, zero_written); @@ -4173,8 +4182,7 @@ static int ext4_block_zero_range(handle_t *handle, st= ruct inode *inode, * to physically zero the tail end of that block so it doesn't yield old * data if the file is grown. */ -int ext4_block_zero_eof(handle_t *handle, struct inode *inode, - loff_t from, loff_t end) +int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end) { unsigned int blocksize =3D i_blocksize(inode); unsigned int offset; @@ -4193,7 +4201,7 @@ int ext4_block_zero_eof(handle_t *handle, struct inod= e *inode, if (length > blocksize - offset) length =3D blocksize - offset; =20 - err =3D ext4_block_zero_range(handle, inode, from, length, + err =3D ext4_block_zero_range(inode, from, length, &did_zero, &zero_written); if (err) return err; @@ -4204,14 +4212,23 @@ int ext4_block_zero_eof(handle_t *handle, struct in= ode *inode, * mmap write during folio writeback. */ if (ext4_should_order_data(inode) && - did_zero && zero_written && !IS_DAX(inode)) - err =3D ext4_jbd2_inode_add_write(handle, inode, from, length); + did_zero && zero_written && !IS_DAX(inode)) { + handle_t *handle; =20 - return err; + handle =3D ext4_journal_start(inode, EXT4_HT_MISC, 1); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + err =3D ext4_jbd2_inode_add_write(handle, inode, from, length); + ext4_journal_stop(handle); + if (err) + return err; + } + + return 0; } =20 -int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, - loff_t lstart, loff_t length) +int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t le= ngth) { struct super_block *sb =3D inode->i_sb; unsigned partial_start, partial_end; @@ -4228,21 +4245,19 @@ int ext4_zero_partial_blocks(handle_t *handle, stru= ct inode *inode, /* Handle partial zero within the single block */ if (start =3D=3D end && (partial_start || (partial_end !=3D sb->s_blocksize - 1))) { - err =3D ext4_block_zero_range(handle, inode, lstart, - length, NULL, NULL); + err =3D ext4_block_zero_range(inode, lstart, length, NULL, NULL); return err; } /* Handle partial zero out on the start of the range */ if (partial_start) { - err =3D ext4_block_zero_range(handle, inode, lstart, - sb->s_blocksize, NULL, NULL); + err =3D ext4_block_zero_range(inode, lstart, sb->s_blocksize, + NULL, NULL); if (err) return err; } /* Handle partial zero out on the end of the range */ if (partial_end !=3D sb->s_blocksize - 1) - err =3D ext4_block_zero_range(handle, inode, - byte_end - partial_end, + err =3D ext4_block_zero_range(inode, byte_end - partial_end, partial_end + 1, NULL, NULL); return err; } @@ -4438,7 +4453,7 @@ int ext4_punch_hole(struct file *file, loff_t offset,= loff_t length) return ret; } =20 - ret =3D ext4_zero_partial_blocks(handle, inode, offset, length); + ret =3D ext4_zero_partial_blocks(inode, offset, length); if (ret) goto out_handle; =20 @@ -4588,7 +4603,7 @@ int ext4_truncate(struct inode *inode) =20 /* Zero to the end of the block containing i_size */ if (inode->i_size & (inode->i_sb->s_blocksize - 1)) - ext4_block_zero_eof(handle, inode, inode->i_size, LLONG_MAX); + ext4_block_zero_eof(inode, inode->i_size, LLONG_MAX); =20 /* * We add the inode to the orphan list, so that if this @@ -5965,8 +5980,8 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dent= ry *dentry, inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); if (oldsize & (inode->i_sb->s_blocksize - 1)) - ext4_block_zero_eof(handle, inode, - oldsize, LLONG_MAX); + ext4_block_zero_eof(inode, oldsize, + LLONG_MAX); } =20 if (shrink) --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 91B912773E4; Thu, 26 Mar 2026 11:15:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523759; cv=none; b=cTvXeBuUjIh/bJb52BrazUMVRqGWUFPXk4G0yS0VcVL1CL2lIDFTS5DDULXqqerstiDJWYITg9xImB1JyU0Ue22gY/CnBnecpHyBE8J1op4yZRe86L3kj6LfzsM8Lj2I/oYzeNahMvkmuEUJu45D/BSxGQY2jYeAnEJ7CGl6iWw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523759; c=relaxed/simple; bh=XmFUjlxOZHR+uzDYaPjlfunzjAttkhEg3O4QZ+98J+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZhLQ6AaOrcn0db6IDbBw3bbba4xo5erVEsljFZY4fVegjVefLw9WQt1TOCzIuT/ehhQAVJ9u/W1EJ6fBypajqD84Nk75LCMhk4Zl2VPnVZXXIaDF399EWVVX5fAsO8W/2dHCDCUde/duxQC1zKEBU6EZJw60PM5uW99NNH/FqR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmV1Z3kzYQv7N; Thu, 26 Mar 2026 19:15:38 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 276BD4056E; Thu, 26 Mar 2026 19:15:50 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S11; Thu, 26 Mar 2026 19:15:49 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 07/11] ext4: pass allocate range as loff_t to ext4_alloc_file_blocks() Date: Thu, 26 Mar 2026 19:10:50 +0800 Message-ID: <20260326111054.907252-8-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S11 X-Coremail-Antispam: 1UD129KBjvJXoWxtrWfuF1kCryUKFyUZrW5Wrg_yoW7tFWrpF Z8Zr15GF4fWFyv9w40kwsrXr1fK3ZrKrWUXryagryFqa4DtF1xtan0yFW0gFySgrZ7Zrs0 vF4Ykry7Ga1UG3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUQFxUUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Change ext4_alloc_file_blocks() to accept offset and len in byte granularity instead of block granularity. This allows callers to pass byte offsets and lengths directly, and this prepares for moving the ext4_zero_partial_blocks() call from the while(len) loop for unaligned append writes, where it only needs to be invoked once before doing block allocation. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/extents.c | 53 ++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 753a0f3418a4..57a686b600d9 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4542,15 +4542,15 @@ int ext4_ext_truncate(handle_t *handle, struct inod= e *inode) return err; } =20 -static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, - ext4_lblk_t len, loff_t new_size, - int flags) +static int ext4_alloc_file_blocks(struct file *file, loff_t offset, loff_t= len, + loff_t new_size, int flags) { struct inode *inode =3D file_inode(file); handle_t *handle; int ret =3D 0, ret2 =3D 0, ret3 =3D 0; int retries =3D 0; int depth =3D 0; + ext4_lblk_t len_lblk; struct ext4_map_blocks map; unsigned int credits; loff_t epos, old_size =3D i_size_read(inode); @@ -4558,14 +4558,14 @@ static int ext4_alloc_file_blocks(struct file *file= , ext4_lblk_t offset, bool alloc_zero =3D false; =20 BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)); - map.m_lblk =3D offset; - map.m_len =3D len; + map.m_lblk =3D offset >> blkbits; + map.m_len =3D len_lblk =3D EXT4_MAX_BLOCKS(len, offset, blkbits); /* * Don't normalize the request if it can fit in one extent so * that it doesn't get unnecessarily split into multiple * extents. */ - if (len <=3D EXT_UNWRITTEN_MAX_LEN) + if (len_lblk <=3D EXT_UNWRITTEN_MAX_LEN) flags |=3D EXT4_GET_BLOCKS_NO_NORMALIZE; =20 /* @@ -4582,16 +4582,16 @@ static int ext4_alloc_file_blocks(struct file *file= , ext4_lblk_t offset, /* * credits to insert 1 extent into extent tree */ - credits =3D ext4_chunk_trans_blocks(inode, len); + credits =3D ext4_chunk_trans_blocks(inode, len_lblk); depth =3D ext_depth(inode); =20 retry: - while (len) { + while (len_lblk) { /* * Recalculate credits when extent tree depth changes. */ if (depth !=3D ext_depth(inode)) { - credits =3D ext4_chunk_trans_blocks(inode, len); + credits =3D ext4_chunk_trans_blocks(inode, len_lblk); depth =3D ext_depth(inode); } =20 @@ -4648,7 +4648,7 @@ static int ext4_alloc_file_blocks(struct file *file, = ext4_lblk_t offset, } =20 map.m_lblk +=3D ret; - map.m_len =3D len =3D len - ret; + map.m_len =3D len_lblk =3D len_lblk - ret; } if (ret =3D=3D -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; @@ -4665,11 +4665,9 @@ static long ext4_zero_range(struct file *file, loff_= t offset, { struct inode *inode =3D file_inode(file); handle_t *handle =3D NULL; - loff_t new_size =3D 0; + loff_t align_start, align_end, new_size =3D 0; loff_t end =3D offset + len; - ext4_lblk_t start_lblk, end_lblk; unsigned int blocksize =3D i_blocksize(inode); - unsigned int blkbits =3D inode->i_blkbits; int ret, flags, credits; =20 trace_ext4_zero_range(inode, offset, len, mode); @@ -4690,11 +4688,8 @@ static long ext4_zero_range(struct file *file, loff_= t offset, flags =3D EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT; /* Preallocate the range including the unaligned edges */ if (!IS_ALIGNED(offset | end, blocksize)) { - ext4_lblk_t alloc_lblk =3D offset >> blkbits; - ext4_lblk_t len_lblk =3D EXT4_MAX_BLOCKS(len, offset, blkbits); - - ret =3D ext4_alloc_file_blocks(file, alloc_lblk, len_lblk, - new_size, flags); + ret =3D ext4_alloc_file_blocks(file, offset, len, new_size, + flags); if (ret) return ret; } @@ -4709,18 +4704,17 @@ static long ext4_zero_range(struct file *file, loff= _t offset, return ret; =20 /* Zero range excluding the unaligned edges */ - start_lblk =3D EXT4_B_TO_LBLK(inode, offset); - end_lblk =3D end >> blkbits; - if (end_lblk > start_lblk) { - ext4_lblk_t zero_blks =3D end_lblk - start_lblk; - + align_start =3D round_up(offset, blocksize); + align_end =3D round_down(end, blocksize); + if (align_end > align_start) { if (mode & FALLOC_FL_WRITE_ZEROES) flags =3D EXT4_GET_BLOCKS_CREATE_ZERO | EXT4_EX_NOCACHE; else flags |=3D (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN | EXT4_EX_NOCACHE); - ret =3D ext4_alloc_file_blocks(file, start_lblk, zero_blks, - new_size, flags); + ret =3D ext4_alloc_file_blocks(file, align_start, + align_end - align_start, new_size, + flags); if (ret) return ret; } @@ -4768,15 +4762,11 @@ static long ext4_do_fallocate(struct file *file, lo= ff_t offset, struct inode *inode =3D file_inode(file); loff_t end =3D offset + len; loff_t new_size =3D 0; - ext4_lblk_t start_lblk, len_lblk; int ret; =20 trace_ext4_fallocate_enter(inode, offset, len, mode); WARN_ON_ONCE(!inode_is_locked(inode)); =20 - start_lblk =3D offset >> inode->i_blkbits; - len_lblk =3D EXT4_MAX_BLOCKS(len, offset, inode->i_blkbits); - /* We only support preallocation for extent-based files only. */ if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { ret =3D -EOPNOTSUPP; @@ -4791,7 +4781,7 @@ static long ext4_do_fallocate(struct file *file, loff= _t offset, goto out; } =20 - ret =3D ext4_alloc_file_blocks(file, start_lblk, len_lblk, new_size, + ret =3D ext4_alloc_file_blocks(file, offset, len, new_size, EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT); if (ret) goto out; @@ -4801,7 +4791,8 @@ static long ext4_do_fallocate(struct file *file, loff= _t offset, EXT4_I(inode)->i_sync_tid); } out: - trace_ext4_fallocate_exit(inode, offset, len_lblk, ret); + trace_ext4_fallocate_exit(inode, offset, + EXT4_MAX_BLOCKS(len, offset, inode->i_blkbits), ret); return ret; } =20 --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 662523CB2D4; Thu, 26 Mar 2026 11:15:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523758; cv=none; b=iOQyHYF3futVRWcjshllPFe43sThl/5qUjrg2jbxtTN4aVFzGiKMGvRCd3xfhTbOTHHHZvC8H+P0U+nB0ewfG9dSPdIFaPBvHGRFd8sJhL2T4xr7avYC9qXgipGrz+V6zyfpfLuyu1UL2AixpGD68Ld8rIbvmLwAz33f18w3RJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523758; c=relaxed/simple; bh=F/MPwLsFqMq4htfeDZGuti0YLKYlyyFoh1AuELOfYwM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QUsU+6+OTcOKWtKqrHyH/PLdrf9lfJ6OLqBY4hlF3Y5FnAQvANh6ST5XUJe6EwrGTIPhWdp25OCOLDBZZ+ucs8SQ5DpvwyZQ4bWIXRoWzc0tIXi4DN9bC9an3eBoFYFh/2pHLgoa/nHnu6rRJlQ70bmr9mPiwnGvin9Ic/XjGF4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmV23J3zYQv7N; Thu, 26 Mar 2026 19:15:38 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 3E75C40592; Thu, 26 Mar 2026 19:15:50 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S12; Thu, 26 Mar 2026 19:15:50 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 08/11] ext4: move zero partial block range functions out of active handle Date: Thu, 26 Mar 2026 19:10:51 +0800 Message-ID: <20260326111054.907252-9-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S12 X-Coremail-Antispam: 1UD129KBjvJXoWxuFWfKF13GFWrAFyDGF15Jwb_yoWxXr4Up3 y3Aa4fGr1kWF9I9F4Skr47ZF4Yk3WxKr4UWry7Cr10qayDZw1SkF1ayFy0qFWUKrWUZr4Y vF4UCryUGw1UC3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUQFxUUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi Move ext4_block_zero_eof() and ext4_zero_partial_blocks() calls out of the active handle context, making them independent operations, and also add return value checks. This is safe because it still ensures data is updated before metadata for data=3Dordered mode and data=3Djournal mode because we still zero data and ordering data before modifying the metadata. This change is required for iomap infrastructure conversion because the iomap buffered I/O path does not use the same journal infrastructure for partial block zeroing. The lock ordering of folio lock and starting transactions is "folio lock -> transaction start", which is opposite of the current path. Therefore, zeroing partial blocks cannot be performed under the active handle. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/extents.c | 32 +++++++++++++++----------------- fs/ext4/inode.c | 47 ++++++++++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 57a686b600d9..002b1ec8cee2 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4585,6 +4585,13 @@ static int ext4_alloc_file_blocks(struct file *file,= loff_t offset, loff_t len, credits =3D ext4_chunk_trans_blocks(inode, len_lblk); depth =3D ext_depth(inode); =20 + /* Zero to the end of the block containing i_size */ + if (new_size > old_size) { + ret =3D ext4_block_zero_eof(inode, old_size, LLONG_MAX); + if (ret) + return ret; + } + retry: while (len_lblk) { /* @@ -4623,10 +4630,8 @@ static int ext4_alloc_file_blocks(struct file *file,= loff_t offset, loff_t len, if (ext4_update_inode_size(inode, epos) & 0x1) inode_set_mtime_to_ts(inode, inode_get_ctime(inode)); - if (epos > old_size) { + if (epos > old_size) pagecache_isize_extended(inode, old_size, epos); - ext4_block_zero_eof(inode, old_size, epos); - } } ret2 =3D ext4_mark_inode_dirty(handle, inode); ext4_update_inode_fsync_trans(handle, inode, 1); @@ -4668,7 +4673,7 @@ static long ext4_zero_range(struct file *file, loff_t= offset, loff_t align_start, align_end, new_size =3D 0; loff_t end =3D offset + len; unsigned int blocksize =3D i_blocksize(inode); - int ret, flags, credits; + int ret, flags; =20 trace_ext4_zero_range(inode, offset, len, mode); WARN_ON_ONCE(!inode_is_locked(inode)); @@ -4722,25 +4727,18 @@ static long ext4_zero_range(struct file *file, loff= _t offset, if (IS_ALIGNED(offset | end, blocksize)) return ret; =20 - /* - * In worst case we have to writeout two nonadjacent unwritten - * blocks and update the inode - */ - credits =3D (2 * ext4_ext_index_trans_blocks(inode, 2)) + 1; - if (ext4_should_journal_data(inode)) - credits +=3D 2; - handle =3D ext4_journal_start(inode, EXT4_HT_MISC, credits); + /* Zero out partial block at the edges of the range */ + ret =3D ext4_zero_partial_blocks(inode, offset, len); + if (ret) + return ret; + + handle =3D ext4_journal_start(inode, EXT4_HT_MISC, 1); if (IS_ERR(handle)) { ret =3D PTR_ERR(handle); ext4_std_error(inode->i_sb, ret); return ret; } =20 - /* Zero out partial block at the edges of the range */ - ret =3D ext4_zero_partial_blocks(inode, offset, len); - if (ret) - goto out_handle; - if (new_size) ext4_update_inode_size(inode, new_size); ret =3D ext4_mark_inode_dirty(handle, inode); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 94c8e8c3984f..5c54d5c6fdfe 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4442,8 +4442,12 @@ int ext4_punch_hole(struct file *file, loff_t offset= , loff_t length) if (ret) return ret; =20 + ret =3D ext4_zero_partial_blocks(inode, offset, length); + if (ret) + return ret; + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) - credits =3D ext4_chunk_trans_extent(inode, 2); + credits =3D ext4_chunk_trans_extent(inode, 0); else credits =3D ext4_blocks_for_truncate(inode); handle =3D ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); @@ -4453,10 +4457,6 @@ int ext4_punch_hole(struct file *file, loff_t offset= , loff_t length) return ret; } =20 - ret =3D ext4_zero_partial_blocks(inode, offset, length); - if (ret) - goto out_handle; - /* If there are blocks to remove, do it */ start_lblk =3D EXT4_B_TO_LBLK(inode, offset); end_lblk =3D end >> inode->i_blkbits; @@ -4588,6 +4588,11 @@ int ext4_truncate(struct inode *inode) err =3D ext4_inode_attach_jinode(inode); if (err) goto out_trace; + + /* Zero to the end of the block containing i_size */ + err =3D ext4_block_zero_eof(inode, inode->i_size, LLONG_MAX); + if (err) + goto out_trace; } =20 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) @@ -4601,10 +4606,6 @@ int ext4_truncate(struct inode *inode) goto out_trace; } =20 - /* Zero to the end of the block containing i_size */ - if (inode->i_size & (inode->i_sb->s_blocksize - 1)) - ext4_block_zero_eof(inode, inode->i_size, LLONG_MAX); - /* * We add the inode to the orphan list, so that if this * truncate spans multiple transactions, and we crash, we will @@ -5962,15 +5963,6 @@ int ext4_setattr(struct mnt_idmap *idmap, struct den= try *dentry, goto out_mmap_sem; } =20 - handle =3D ext4_journal_start(inode, EXT4_HT_INODE, 3); - if (IS_ERR(handle)) { - error =3D PTR_ERR(handle); - goto out_mmap_sem; - } - if (ext4_handle_valid(handle) && shrink) { - error =3D ext4_orphan_add(handle, inode); - orphan =3D 1; - } /* * Update c/mtime and tail zero the EOF folio on * truncate up. ext4_truncate() handles the shrink case @@ -5979,9 +5971,22 @@ int ext4_setattr(struct mnt_idmap *idmap, struct den= try *dentry, if (!shrink) { inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); - if (oldsize & (inode->i_sb->s_blocksize - 1)) - ext4_block_zero_eof(inode, oldsize, - LLONG_MAX); + if (oldsize & (inode->i_sb->s_blocksize - 1)) { + error =3D ext4_block_zero_eof(inode, + oldsize, LLONG_MAX); + if (error) + goto out_mmap_sem; + } + } + + handle =3D ext4_journal_start(inode, EXT4_HT_INODE, 3); + if (IS_ERR(handle)) { + error =3D PTR_ERR(handle); + goto out_mmap_sem; + } + if (ext4_handle_valid(handle) && shrink) { + error =3D ext4_orphan_add(handle, inode); + orphan =3D 1; } =20 if (shrink) --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 4F1733DD517; Thu, 26 Mar 2026 11:15:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523759; cv=none; b=r1WoldhE3bOJcbkE015KjOHH5XMI3vDr6fO5tOKATPOm803kk+emv8MXIz2NTuMiXhY8IVs+C8mUIat+DOpwcgl3ydT8IFAzAH+0WNDyLjuSKA5nb3UiRiluftZ5+dseuVmzMgFdahxDtYJ7MnSwsam/R4PYaDNgSnMx+tqgW0E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523759; c=relaxed/simple; bh=eKoxAEuiPgiB7q78piU7nUjLlmqnlLLXLI6YAYLmoBM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K3rETDPdn2+5BNwfIGV/x5ax1DKriywgJGSwfipUKNoXIKTpI9fWnVyCKZjiuc4WYQGgS39chinK4Il9eSDHTDlYoNzxava6PuCT7T5OLqrLFczPg1xDduc6+c5uE4K1ffmabGZoF8Zf+aHNYZkhiVlvpaIQ7k/kbqE6fZ3hSZw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmV2TjPzYQv7h; Thu, 26 Mar 2026 19:15:38 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 4BAE640594; Thu, 26 Mar 2026 19:15:50 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S13; Thu, 26 Mar 2026 19:15:50 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 09/11] ext4: remove ctime/mtime update from ext4_alloc_file_blocks() Date: Thu, 26 Mar 2026 19:10:52 +0800 Message-ID: <20260326111054.907252-10-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S13 X-Coremail-Antispam: 1UD129KBjvdXoWrtFyUCrW7Cr4rCw48ZFWfAFb_yoWkGrc_Wa y7trW0yw43X3WSgF4DCw13JrsYvr18Gr15WFWftF4fZw1UKrWkJ3WDJr15urW5Ww45CrZ8 Ww4ktr4jyryIgjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJTRUUUbvAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k26cxKx2IYs7xG 6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAVCq3wA2048vs2 IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28E F7xvwVC0I7IYx2IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr 1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0D M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjx v20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1l F7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2 IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF 0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsG vfC2KfnxnUUI43ZEXa7VUbPC7UUUUUU== X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi The ctime and mtime update is already handled by file_modified() in ext4_fallocate(), the caller of ext4_alloc_file_blocks(). So remove the redundant calls to inode_set_ctime_current() and inode_set_mtime_to_ts() in ext4_alloc_file_blocks(). Signed-off-by: Zhang Yi --- fs/ext4/extents.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 002b1ec8cee2..4155a2e37070 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4623,13 +4623,10 @@ static int ext4_alloc_file_blocks(struct file *file= , loff_t offset, loff_t len, */ retries =3D 0; epos =3D EXT4_LBLK_TO_B(inode, map.m_lblk + ret); - inode_set_ctime_current(inode); if (new_size) { if (epos > new_size) epos =3D new_size; - if (ext4_update_inode_size(inode, epos) & 0x1) - inode_set_mtime_to_ts(inode, - inode_get_ctime(inode)); + ext4_update_inode_size(inode, epos); if (epos > old_size) pagecache_isize_extended(inode, old_size, epos); } --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (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 235113859EC; Thu, 26 Mar 2026 11:15:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523756; cv=none; b=Lsz5v2Fc2dYStt6047KoS5EgK/8799oWxIAzShIaMWYmCF+X4FwZ+gSXGpZF4JFtofQ64TmmNC295t5yhLGmRwGfqLspHc52s7VsIteQIvjndQ4+nrSdsQtr0A+44MvWLCSJmv96QxrdfdfDfF4QQnMbu3pqJgLRlzIiGffBfVw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523756; c=relaxed/simple; bh=O3/imx8V6zIXOmaZ3jq7idWbuIt/Pkm26283YKmlLb4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Cn5fcCpYNa1J6LSkEjTW+TXONRD9zQYwGvrpd98XZnAXwS2X07bfOjRNmWxu9FiTVfIG63ERR8Qmy9ySrkRQ44hShUYUlFUIcR+nfEZzlj7Ncj1ckrlRxdFSsirUOQIrhkR0xAh7v26Tno8OaqNyaxaj7LdVX7rGwxlWfq3nnMM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4fhLly1lBhzKHMm3; Thu, 26 Mar 2026 19:15:10 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 6444740592; Thu, 26 Mar 2026 19:15:50 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S14; Thu, 26 Mar 2026 19:15:50 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 10/11] ext4: move pagecache_isize_extended() out of active handle Date: Thu, 26 Mar 2026 19:10:53 +0800 Message-ID: <20260326111054.907252-11-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S14 X-Coremail-Antispam: 1UD129KBjvJXoWxJFy3Xr1fKr1rCr1UXrykGrg_yoW5try3pr W3CF1rtF1FgFyq9r4ftr4DZr4Yga48KrWUZr93Wr9Yv3ZxXr1rKr1YyFyFvFW5trW8XF4Y qrs0yw15G3WUZ3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUQFxUUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi In ext4_alloc_file_blocks(), pagecache_isize_extended() is called under an active handle and may also hold folio lock if the block size is smaller than the folio size. This also breaks the "folio lock -> transaction start" lock ordering for the upcoming iomap buffered I/O path. Therefore, move pagecache_isize_extended() outside of an active handle. Additionally, it is unnecessary to update the file length during each iteration of the allocation loop. Instead, update the file length only to the position where the allocation is successful. Postpone updating the inode size until after the allocation loop completes or is interrupted due to an error. Signed-off-by: Zhang Yi --- fs/ext4/extents.c | 69 +++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 4155a2e37070..19fc1ef7b2c3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4618,44 +4618,61 @@ static int ext4_alloc_file_blocks(struct file *file= , loff_t offset, loff_t len, ext4_journal_stop(handle); break; } + ext4_update_inode_fsync_trans(handle, inode, 1); + ret =3D ext4_journal_stop(handle); + if (unlikely(ret)) + break; + /* * allow a full retry cycle for any remaining allocations */ retries =3D 0; - epos =3D EXT4_LBLK_TO_B(inode, map.m_lblk + ret); - if (new_size) { - if (epos > new_size) - epos =3D new_size; - ext4_update_inode_size(inode, epos); - if (epos > old_size) - pagecache_isize_extended(inode, old_size, epos); + + if (alloc_zero && + (map.m_flags & (EXT4_MAP_MAPPED | EXT4_MAP_UNWRITTEN))) { + ret =3D ext4_issue_zeroout(inode, map.m_lblk, map.m_pblk, + map.m_len); + if (likely(!ret)) + ret =3D ext4_convert_unwritten_extents(NULL, + inode, (loff_t)map.m_lblk << blkbits, + (loff_t)map.m_len << blkbits); + if (ret) + break; } + + map.m_lblk +=3D map.m_len; + map.m_len =3D len_lblk =3D len_lblk - map.m_len; + } + + if (ret =3D=3D -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + + if (!new_size) + return ret; + + /* + * Update the file size to match the size of the already successfully + * allocated blocks. + */ + epos =3D EXT4_LBLK_TO_B(inode, map.m_lblk); + if (epos > new_size) + epos =3D new_size; + if (epos > old_size) { + handle =3D ext4_journal_start(inode, EXT4_HT_MISC, 1); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + ext4_update_inode_size(inode, epos); + ret2 =3D ext4_mark_inode_dirty(handle, inode); ext4_update_inode_fsync_trans(handle, inode, 1); ret3 =3D ext4_journal_stop(handle); ret2 =3D ret3 ? ret3 : ret2; - if (unlikely(ret2)) - break; =20 - if (alloc_zero && - (map.m_flags & (EXT4_MAP_MAPPED | EXT4_MAP_UNWRITTEN))) { - ret2 =3D ext4_issue_zeroout(inode, map.m_lblk, map.m_pblk, - map.m_len); - if (likely(!ret2)) - ret2 =3D ext4_convert_unwritten_extents(NULL, - inode, (loff_t)map.m_lblk << blkbits, - (loff_t)map.m_len << blkbits); - if (ret2) - break; - } - - map.m_lblk +=3D ret; - map.m_len =3D len_lblk =3D len_lblk - ret; + pagecache_isize_extended(inode, old_size, epos); } - if (ret =3D=3D -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry; =20 - return ret > 0 ? ret2 : ret; + return ret ? ret : ret2; } =20 static int ext4_collapse_range(struct file *file, loff_t offset, loff_t le= n); --=20 2.52.0 From nobody Thu Apr 2 22:13:14 2026 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 55D8B3DD51C; Thu, 26 Mar 2026 11:15:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523761; cv=none; b=HfoGjGkFKVGM2EpC4OEqT6SPJfuvN7ycdTttrVgwDGuUSjdWKV1++uWHUtDO+Z+BgqFsxW+wAqp55ZPUFUVuKcdGk1fhffpokVwhpv1ezrXjOO5nkft3JCTGOfKeqJU9Zw0vj8QGqt3JeYYdizDQrxiXSjPIc4R5swahOm2Bny8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774523761; c=relaxed/simple; bh=PV1n1q++orzKmCP/4t60hYR9COeJK/6LFBf/ldOzWFE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jZSXeJTWXQy/WE4YHtLu0ROrXBuEgfJrCTmluDvQvOEFgdEXtubREg9LERwk6W1flt6T6HkedE/9tNtaLTJC5aDnhcFY+SJp8MHDdJWSaVaWOjMQsvxDSQ1w8Ye+wmJix5BAhvQBSr8RlO9WkYBwGTYC4aENqxzQq+z6DNvOodw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=none smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 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.163.170]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhLmV3n4MzYQv7p; Thu, 26 Mar 2026 19:15:38 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 7655D40571; Thu, 26 Mar 2026 19:15:50 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgD3+NhWFcVprDInCQ--.2580S15; Thu, 26 Mar 2026 19:15:50 +0800 (CST) From: Zhang Yi To: linux-ext4@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com, libaokun@linux.alibaba.com, yi.zhang@huawei.com, yi.zhang@huaweicloud.com, yizhang089@gmail.com, yangerkun@huawei.com, yukuai@fnnas.com Subject: [PATCH v3 11/11] ext4: zero post-EOF partial block before appending write Date: Thu, 26 Mar 2026 19:10:54 +0800 Message-ID: <20260326111054.907252-12-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260326111054.907252-1-yi.zhang@huaweicloud.com> References: <20260326111054.907252-1-yi.zhang@huaweicloud.com> 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 X-CM-TRANSID: cCh0CgD3+NhWFcVprDInCQ--.2580S15 X-Coremail-Antispam: 1UD129KBjvJXoWxGrW8WrWrtryxZr17Gr1Dtrb_yoWrWFW3pF ZIkF1fWwnFgr9rW3yxKFsrX34jka48JrW7GFyfKrWfZFnxAw18KF12q34UtFWrtrZrXa1F qF4q9FyUG3Wjy3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUQFxUUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi In cases of appending write beyond EOF, ext4_zero_partial_blocks() is called within ext4_*_write_end() to zero out the partial block beyond EOF. This prevents exposing stale data that might be written through mmap. However, supporting only the regular buffered write path is insufficient. It is also necessary to support the DAX path as well as the upcoming iomap buffered write path. Therefore, move this operation to ext4_write_checks(). In addition, this may introduce a race window in which a post-EOF buffered write can race with an mmap write after the old EOF block has been zeroed. As a result, the data in this block written by the buffer-write and the data written by the mmap-write may be mixed. However, this is safe because users should not rely on the result of the race condition. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/file.c | 17 +++++++++++++++++ fs/ext4/inode.c | 21 +++++++-------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index f1dc5ce791a7..ec0d81bea07a 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -271,6 +271,8 @@ static ssize_t ext4_generic_write_checks(struct kiocb *= iocb, =20 static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from) { + struct inode *inode =3D file_inode(iocb->ki_filp); + loff_t old_size =3D i_size_read(inode); ssize_t ret, count; =20 count =3D ext4_generic_write_checks(iocb, from); @@ -280,6 +282,21 @@ static ssize_t ext4_write_checks(struct kiocb *iocb, s= truct iov_iter *from) ret =3D file_modified(iocb->ki_filp); if (ret) return ret; + + /* + * If the position is beyond the EOF, it is necessary to zero out the + * partial block that beyond the existing EOF, as it may contains + * stale data written through mmap. + */ + if (iocb->ki_pos > old_size && !ext4_verity_in_progress(inode)) { + if (iocb->ki_flags & IOCB_NOWAIT) + return -EAGAIN; + + ret =3D ext4_block_zero_eof(inode, old_size, iocb->ki_pos); + if (ret) + return ret; + } + return count; } =20 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5c54d5c6fdfe..d52cffdea635 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1456,10 +1456,9 @@ static int ext4_write_end(const struct kiocb *iocb, folio_unlock(folio); folio_put(folio); =20 - if (old_size < pos && !verity) { + if (old_size < pos && !verity) pagecache_isize_extended(inode, old_size, pos); - ext4_block_zero_eof(inode, old_size, pos); - } + /* * Don't mark the inode dirty under folio lock. First, it unnecessarily * makes the holding time of folio lock longer. Second, it forces lock @@ -1574,10 +1573,8 @@ static int ext4_journalled_write_end(const struct ki= ocb *iocb, folio_unlock(folio); folio_put(folio); =20 - if (old_size < pos && !verity) { + if (old_size < pos && !verity) pagecache_isize_extended(inode, old_size, pos); - ext4_block_zero_eof(inode, old_size, pos); - } =20 if (size_changed) { ret2 =3D ext4_mark_inode_dirty(handle, inode); @@ -3196,7 +3193,7 @@ static int ext4_da_do_write_end(struct address_space = *mapping, struct inode *inode =3D mapping->host; loff_t old_size =3D inode->i_size; bool disksize_changed =3D false; - loff_t new_i_size, zero_len =3D 0; + loff_t new_i_size; handle_t *handle; =20 if (unlikely(!folio_buffers(folio))) { @@ -3240,19 +3237,15 @@ static int ext4_da_do_write_end(struct address_spac= e *mapping, folio_unlock(folio); folio_put(folio); =20 - if (pos > old_size) { + if (pos > old_size) pagecache_isize_extended(inode, old_size, pos); - zero_len =3D pos - old_size; - } =20 - if (!disksize_changed && !zero_len) + if (!disksize_changed) return copied; =20 - handle =3D ext4_journal_start(inode, EXT4_HT_INODE, 2); + handle =3D ext4_journal_start(inode, EXT4_HT_INODE, 1); if (IS_ERR(handle)) return PTR_ERR(handle); - if (zero_len) - ext4_block_zero_eof(inode, old_size, pos); ext4_mark_inode_dirty(handle, inode); ext4_journal_stop(handle); =20 --=20 2.52.0