From nobody Thu Apr 2 17:18:50 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 4D9833A5E70; Fri, 27 Mar 2026 10:34:34 +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=1774607678; cv=none; b=XRVdGPiB3tYJo2PlFoS/ZhK6d5jit7kY1I52mHmsMrn39J3Dk0E1L4FbhaFL8JxWqQ/w7jkQCMzYSuNHPlDNgxgmYgYJT/IvmKiXlT7lAVcPEAdnR4ontzN3PBeihF8JRKXHNnD18bKohhM2nKZHTI0OhdnShWFDW0misFZ57VU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607678; c=relaxed/simple; bh=viFvCHynwN2QwKfgVv4CMz86s7mPdhW8AzLlTm4Rt7I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k/ki/vktIpdWPB3NDl2R5J2dKNcGreY/U5xwGi/qK9inkIW8JYIR1ETqPKJ8F7Uu5ftJz8p4IYRp8jku5zOCs6NjVxDora+h3fddbEuMi3chOvEn0SJQqcEEYt5zotVq4ptUzakQvL9UUTpXf1uMSyPp82W1C3fz/aDJPShptjs= 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.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4fhxnp1kCwzKHMRM; Fri, 27 Mar 2026 18:33:50 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id E23E740562; Fri, 27 Mar 2026 18:34:31 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S5; Fri, 27 Mar 2026 18:34:31 +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 v4 01/13] ext4: add did_zero output parameter to ext4_block_zero_page_range() Date: Fri, 27 Mar 2026 18:29:27 +0800 Message-ID: <20260327102939.1095257-2-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S5 X-Coremail-Antispam: 1UD129KBjvJXoWxCF17XryfAw18KF1rKw15Jwb_yoW5uw1xpr y5t345ur47u34q9F4xWF1jvr1Sk3Z3GFW8W3y3G3s0v3yIq3WxKF95K3WFvF4jg3y7Xay0 qF4Yy3y2gw1UArJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUm014x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0x vEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVj vjDU0xZFpf9x0JUfKs8UUUUU= 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 17:18:50 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 4AECD38551F; Fri, 27 Mar 2026 10:34:34 +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=1774607680; cv=none; b=EERfB+h2H1bSd4TE8JM8D4U1drDu5Uf//p6ds8h1AxJDOn2iiYLy+ZGbtFQjR5G8qydm7kQvWCkp1QYUx8qly65PL6u7/aOFbtFmeUXW7HgMisZ3eCjF1elrXiWNb/LWbqzVZVtegHssY5FvzYGYtCwGkC52+CLml7pmn3M6HCY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607680; c=relaxed/simple; bh=I4XHiujXs7qhKUx4JhAgRX0qgoLkJvpiinPfQkkp0yI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aocAe7/RTUaNQRtzaNSZRI4GDvME8pswPRPAYh/ZaLlJxcifS0WtyfDoGQ4EndGconRWD+PtHC7iZ2V3dTen8ZaqJfpzvVfBP3Q1+rhEbMUFfpBhwVY8gNYLPqsBFzUDvoIpe7DPxjzQLWnmiJarKifQCbQF5DsjJWlfoo04hvM= 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 4fhxpL33gczYQv2t; Fri, 27 Mar 2026 18:34:18 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 0926A40572; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S6; Fri, 27 Mar 2026 18:34:31 +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 v4 02/13] ext4: rename and extend ext4_block_truncate_page() Date: Fri, 27 Mar 2026 18:29:28 +0800 Message-ID: <20260327102939.1095257-3-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S6 X-Coremail-Antispam: 1UD129KBjvJXoW3XF18Ar1kWw1fCF48tw15XFb_yoW7uw15p3 43Aw15Cr1j9ryq9F4IgFsrZr4a93W8GF4UWrWfKryrZasrXF1xKF1DtF1FyFWjqrWxXa1j qFs8KrWjgw17J3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUm014x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0x vEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVj vjDU0xZFpf9x0JUADGOUUUUU= 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 17:18:50 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 4DA0A3A6EF9; Fri, 27 Mar 2026 10:34:34 +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=1774607677; cv=none; b=spASS1+/hRseiiTOzjCx7ulJzP163wns1EXxuhXHZuciu2TvudqEUS6ETTPpMOWeHUXBxbkUzUzLOnP+CBRGsKOC1rrrAk0oxXiYx6jjTn3AANLrl814c21/lt3PeXtPxSmJlEIv3KdXisLslxL4Lmc+B7vdL+uf8CZ7vK8xZ00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607677; c=relaxed/simple; bh=YXS8lHEC3Jdo2j5cSBN7EJ0ZzFqzocgiimSao+12Ztg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tDP3TZkoexFnSjILNbm77AkF0/9mtXqsp/7sXCSi887QtM/cBoPyHDiuNZ7c78jLoPbUJS+NdaEA59Wi/DsJouXKn8L/ja/RXqNN9wPOhG3BRvF3Th5psWPU1gLqb4l5TsH/ghNcyPi1tgUlJPB9YVf3q5EyGdtG8jB3kOANrTk= 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 4fhxnp2tq8zKHMVt; Fri, 27 Mar 2026 18:33:50 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 165AE40594; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S7; Fri, 27 Mar 2026 18:34:31 +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 v4 03/13] ext4: factor out journalled block zeroing range Date: Fri, 27 Mar 2026 18:29:29 +0800 Message-ID: <20260327102939.1095257-4-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S7 X-Coremail-Antispam: 1UD129KBjvJXoWxur18Jr4kCryrtryUJw4Utwb_yoW7JF13pr y3K3srZrW7WF9FgF4Sq3W7Xr1aka4rGrW8WFyxG3savayYqFn3KF1UK3WSvF45tr43G3W0 qF4Yy34j93WDtrDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmY14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JrWl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIev Ja73UjIFyTuYvjfUF3kuDUUUU 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 17:18:50 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 4D8F238CFFF; Fri, 27 Mar 2026 10:34:34 +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=1774607680; cv=none; b=Nlo3ZbrSQHprbWv/3skqZzhGjiFwlPRiiNAJnziJfkayVidtWfhEm7s1YvGVBPjwyBqGfD7BNZ1P8YJSiOr9wXyvbbp0nW/2Y7EV/bYcSgXtNOv7SARqKogQ2qMo0hqUtUuow6u3+BonWVaP3P6E/gMhz7teOz/UBSqH6pP13LQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607680; c=relaxed/simple; bh=fMVXrpHueNdqeZTWFLtA8gyGmQHMRbTNJ3pFGiLRrRc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m4KVKyUUuExSez7s5/x+BWNU6LrxG1l3JMbEk5/4uVbjH4FQu3t/eXgIjAoxCAJt86NJvoyFj8cte+g0ftdkKjWMDRf+kSsuv+IjFjgLHPbn1mbHZlau7PhcMZZ5DsuTo8j03/PoQ9GgwfW/RczFvoIQoQtz79CinejkPnc73rY= 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.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4fhxnp3jyyzKHMbd; Fri, 27 Mar 2026 18:33:50 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 3102840570; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S8; Fri, 27 Mar 2026 18:34:31 +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 v4 04/13] ext4: rename ext4_block_zero_page_range() to ext4_block_zero_range() Date: Fri, 27 Mar 2026 18:29:30 +0800 Message-ID: <20260327102939.1095257-5-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S8 X-Coremail-Antispam: 1UD129KBjvJXoWxAw1fCr1rWF4DKF18tr43Wrg_yoW5try5pr y3tw15ur47W34v9a1xWF17Xr1Ik3Z3GFW8Xry7WryFv39xX3WfKF95K3Z5XF4jg3yxAa40 qF4Yyry2gw17AFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnI WIevJa73UjIFyTuYvjfUriihUUUUU 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 | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1d6eb3ff437e..6e6bf693ef36 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4140,17 +4140,14 @@ static int ext4_block_journalled_zero_range(handle_= t *handle, } =20 /* - * ext4_block_zero_page_range() zeros out a mapping of length 'length' - * starting from file offset 'from'. The range to be zero'd must - * be contained with in one block. If the specified range exceeds - * the end of the block it will be shortened to end of the block - * that corresponds to 'from' + * Zeros out a mapping of length 'length' starting from file offset + * 'from'. The range to be zero'd must be contained with in one block. + * If the specified range exceeds 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 +4192,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 +4213,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 17:18:50 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 4ACB733CEB5; Fri, 27 Mar 2026 10:34:34 +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=1774607677; cv=none; b=s+A0ZQ0RpLV1fveYmMGsWCXqGDbQT3Gnist+PWpj8xrVdaNpJkafc5vN0IjJqQeLRgodo2bZFEu380DZpW9J9sy7v2MfPTteXwbxz0ybCjEFjkY9CFC23km9NQ33W26ohBh37bYaPh1OuH9J9zq4JZ0ltdqAigkV9mlAOxRwM/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607677; c=relaxed/simple; bh=2+y487ZeGEaDqVfaKs6EDyCqjzKjfMqCmiarNm/q0Gk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=px2dUKQDhpaB4Q6JPe59kcEtf9ChxMwZy51HeUjUh3nsyYcaKc6xC1QD+EOy/pQfvAyecGqSVleqbe49nyTGGPjLitB+q0+UjUwHs81u84J7BYKaTcbbclEsTclWgVw9rP50ISDtCrmWbTBcmafhtnpRqzsmnC0ADJdtv7bskbw= 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 4fhxpL53JFzYQv5R; Fri, 27 Mar 2026 18:34:18 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 4D0B94056D; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S9; Fri, 27 Mar 2026 18:34:32 +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 v4 05/13] ext4: move ordered data handling out of ext4_block_do_zero_range() Date: Fri, 27 Mar 2026 18:29:31 +0800 Message-ID: <20260327102939.1095257-6-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S9 X-Coremail-Antispam: 1UD129KBjvJXoW3JF1UCFy8ZrW5Cr1kAF1fZwb_yoW7KFy8pF y5K345Cr47WF9F9Fs7JF17XF1ak3WxGFW8WFWxGr9Yv3y2qwn7KFyUKryFvF4Yq3y3W3W0 qF45t34jg3W7AaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnI WIevJa73UjIFyTuYvjfUriihUUUUU 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 6e6bf693ef36..91e054407463 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, @@ -4146,7 +4141,8 @@ static int ext4_block_journalled_zero_range(handle_t = *handle, * shortened to end of the block 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)); @@ -4165,7 +4161,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 /* @@ -4181,6 +4178,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) @@ -4192,7 +4192,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, @@ -4214,13 +4228,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; } @@ -4228,7 +4242,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 @@ -4403,17 +4417,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 17:18:50 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 4AC373382C5; Fri, 27 Mar 2026 10:34:34 +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=1774607678; cv=none; b=B1oDXyc8IBwi2zOBgHUII9OpH5+JWcqSdbXVZ6C/mzc4isVWSMJbAu8alRQ4REaLr6MQnV1VTfFeuJebbZDRBEaBds12sjJ1MbvbvRl4zQW7EBMbddlxIxY7xluA/pURgjZynp5hA50UxpJuBrvWWFDg5w+Durl+MiNWce8jfIs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607678; c=relaxed/simple; bh=vQahYFkXfQ44db0EvgYheq86BcPHolTynlsacZ14p/Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rQFL2lUC/vdWbYSvzzeXJbPaHrAxWQcL9CwWlbGLCv+cUePGqOaCBM++3II4jb9i+LVljbuB0EOSjQAqTFRU/8rq4dgw3tLCTZ8IDPED9G6OpfMVmijOcBmOf9z+LdvYPKhNPaGNmGiF0YYEOePFNHn59fRsKi7dP5wYF978K4Y= 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 4fhxpL5wc0zYQv5R; Fri, 27 Mar 2026 18:34:18 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 679E940575; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S10; Fri, 27 Mar 2026 18:34:32 +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 v4 06/13] ext4: remove handle parameters from zero partial block functions Date: Fri, 27 Mar 2026 18:29:32 +0800 Message-ID: <20260327102939.1095257-7-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S10 X-Coremail-Antispam: 1UD129KBjvJXoW3Xw1rKw47Kr4DGw4rWw17KFg_yoWfuF1xp3 4UJw1UCr43uFyv9F4I9F47Zr1a93WxGF48WryfGryFvaykXwn7KF1DKF1FyF4jqr47Wa10 vF4Yy34jg3WUJ3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnI WIevJa73UjIFyTuYvjfUriihUUUUU 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 91e054407463..13655ea709fe 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 @@ -4140,7 +4149,7 @@ static int ext4_block_journalled_zero_range(handle_t = *handle, * If the specified range exceeds 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) { @@ -4158,8 +4167,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); @@ -4172,8 +4181,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; @@ -4192,7 +4200,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; @@ -4203,14 +4211,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; @@ -4227,21 +4244,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; } @@ -4437,7 +4452,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 @@ -4587,7 +4602,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 @@ -5964,8 +5979,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 17:18:50 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 4ADA1369999; Fri, 27 Mar 2026 10:34:34 +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=1774607679; cv=none; b=UjwrQEeaqphXyYPYk4X8TPqphtqNhu5oDSlRfTc2nfcyqSBxr57LsODoiO2CpsxC6kMp/cekAVxkA5bv5x3Zszz5aYsgIAkD1n9pzaaGP0UCqPSan2SniX07FClzCLl3HUXNJmHXqme9ORQXjebW1QR3ZpNg37GKK3qVF602L0E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607679; c=relaxed/simple; bh=XmFUjlxOZHR+uzDYaPjlfunzjAttkhEg3O4QZ+98J+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I7Tu2H9Fy1xfrrO/xigWbIw5r7/2mkS/yhWGCkGdOuz9B10otG2rM7gheWceocwIFrP+OxrNAFNIZfqbLl51eJ1NsNfGx9XTnvjK/+C6wAfwcjYU9gKwQt2CyEItvwROavALU8vDMpnnZDRde8U1CFVC3cwPTE5S3b9U1uoEFFk= 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 4fhxpL6XMRzYQv6K; Fri, 27 Mar 2026 18:34:18 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 7EB6240539; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S11; Fri, 27 Mar 2026 18:34:32 +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 v4 07/13] ext4: pass allocate range as loff_t to ext4_alloc_file_blocks() Date: Fri, 27 Mar 2026 18:29:33 +0800 Message-ID: <20260327102939.1095257-8-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S11 X-Coremail-Antispam: 1UD129KBjvJXoWxtrWfuF1kCryUKFyUZrW5Wrg_yoW7tFWrpF Z8Zr15GF4fWFyv9w40kwsrXr1fK3ZrKrWUXryagryFqa4DtF1xtan0yFW0gFySgrZ7Zrs0 vF4Ykry7Ga1UG3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU= 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 17:18:50 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 561073DA7DF; Fri, 27 Mar 2026 10:34:40 +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=1774607683; cv=none; b=MvXUeqFWEXiVX0t1AL7/5ATf3HggaESuGDdIfivEBI16vTOmX8M3C/tEP11ORpXnTY0tAh39M9A+qAaYXUZdQaLtBf04oMTJhmZWhleN0UDVgDYay+JiEWySTFULHKHFp1J7g0HBhKIuiZOvc6xt+jCKz5zAdc+KFzWXlLCRY/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607683; c=relaxed/simple; bh=QfbPo7seK4B0TDu2BB5BbSBr8hShQvihn/uS493D+9c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FdWpXFvZ4oXeaHLd06vAYeJqI/YeDr14rVgpNwp6cLlSRLoFLmVLramnhGQ7lf2Mphzx7QC39VQYQS0NC1T4BapwDF9cwDC9oAwbz0qDdulhN8yUNvA/KqfTCjchPaSuFZ2uQyCJsKm00OKT4IeAKcypHorB6N0NE4M2Yj9MMMk= 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 4fhxpM09n0zYQv6M; Fri, 27 Mar 2026 18:34:19 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 980DF40575; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S12; Fri, 27 Mar 2026 18:34:32 +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 v4 08/13] ext4: move zero partial block range functions out of active handle Date: Fri, 27 Mar 2026 18:29:34 +0800 Message-ID: <20260327102939.1095257-9-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S12 X-Coremail-Antispam: 1UD129KBjvJXoWxuFWfKF13GFWrAFyDGF15Jwb_yoWxXr4Up3 y3Aa4fGr1kuF9Y9F4Skr47ZF4ak3WxKr4UWry7Cr10qayDZw1fKF1ayFy0vFWjgrWUZr4Y vF4jkry7G3WUC3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU= 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 13655ea709fe..8aa4369e3150 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4441,8 +4441,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); @@ -4452,10 +4456,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; @@ -4587,6 +4587,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)) @@ -4600,10 +4605,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 @@ -5961,15 +5962,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 @@ -5978,9 +5970,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 17:18:50 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 5A29E3DB62F; Fri, 27 Mar 2026 10:34:40 +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=1774607685; cv=none; b=Yey7DGtDPXCk69FXzucDduG/6mShrK617Stmu9vAYdA+4X1alsnUiJsVTqRTfeBGXDmV2BOtNjwZsgPw8CHqBFeqErqBcTBAPPnVa+9wvWEajJkKl6Zz2m6W7JKVr4uYANhKgbpEceLHaC0qftnzAnCcGwJ2xBDOUr8ZZT5IkmQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607685; c=relaxed/simple; bh=j/97nXmTe8IHvO2fi5SBryB3oogNc2Q7CceNOoEudAE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ohfzne9O1GJxm4uN3coBeeNoAh2X8UXG9N2mGkCbgvn1EX/o4IHm0pGw1XfWiEe1djNMQ3lBXFwfCfL8MknARsAj1LdTTwD2uFbLyfaGjW9nPcVHuzob0sSOi2B0epAnm70oQ7IN6L+R6CP0MnlEY6aEN+AbH4EIhoK14d9VV9Y= 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 4fhxpM0zdjzYQv7N; Fri, 27 Mar 2026 18:34:19 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id B425A4057A; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S13; Fri, 27 Mar 2026 18:34:32 +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 v4 09/13] ext4: ensure zeroed partial blocks are persisted in SYNC mode Date: Fri, 27 Mar 2026 18:29:35 +0800 Message-ID: <20260327102939.1095257-10-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S13 X-Coremail-Antispam: 1UD129KBjvJXoWxJw1UKFyUXw4UKF17uFy5twb_yoWrtF18p3 43JFy3Gr4fW348ur4fKF4UZr1ay3Z3GF48Wry3Grn8Za97X34xtFyDKF1FvF1YgrW3C340 vF4Yy347Kr15CFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi In ext4_zero_range() and ext4_punch_hole(), when operating in SYNC mode and zeroing a partial block, only data=3Djournal modes guarantee that the zeroed data is synchronously persisted after the operation completes. For data=3Dordered/writeback mode and non-journal modes, this guarantee is missing. Introduce a partial_zero parameter to explicitly trigger writeback for all scenarios where a partial block is zeroed, ensuring the zeroed data is durably persisted. Signed-off-by: Zhang Yi --- fs/ext4/ext4.h | 2 +- fs/ext4/extents.c | 9 ++++++++- fs/ext4/inode.c | 19 ++++++++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 859ae05339ad..bfe86479a83c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3101,7 +3101,7 @@ extern int ext4_meta_trans_blocks(struct inode *inode= , int lblocks, int pextents); 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); + loff_t length, bool *did_zero); 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 002b1ec8cee2..16386f499138 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4673,6 +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); + bool partial_zeroed =3D false; int ret, flags; =20 trace_ext4_zero_range(inode, offset, len, mode); @@ -4728,9 +4729,15 @@ static long ext4_zero_range(struct file *file, loff_= t offset, return ret; =20 /* Zero out partial block at the edges of the range */ - ret =3D ext4_zero_partial_blocks(inode, offset, len); + ret =3D ext4_zero_partial_blocks(inode, offset, len, &partial_zeroed); if (ret) return ret; + if (((file->f_flags & O_SYNC) || IS_SYNC(inode)) && partial_zeroed) { + ret =3D filemap_write_and_wait_range(inode->i_mapping, offset, + end - 1); + if (ret) + return ret; + } =20 handle =3D ext4_journal_start(inode, EXT4_HT_MISC, 1); if (IS_ERR(handle)) { diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8aa4369e3150..b934ad86a96d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4227,7 +4227,8 @@ int ext4_block_zero_eof(struct inode *inode, loff_t f= rom, loff_t end) return 0; } =20 -int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t le= ngth) +int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t le= ngth, + bool *did_zero) { struct super_block *sb =3D inode->i_sb; unsigned partial_start, partial_end; @@ -4244,20 +4245,21 @@ int ext4_zero_partial_blocks(struct inode *inode, l= off_t lstart, loff_t length) /* 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(inode, lstart, length, NULL, NULL); + err =3D ext4_block_zero_range(inode, lstart, length, did_zero, + NULL); return err; } /* Handle partial zero out on the start of the range */ if (partial_start) { err =3D ext4_block_zero_range(inode, lstart, sb->s_blocksize, - NULL, NULL); + did_zero, 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(inode, byte_end - partial_end, - partial_end + 1, NULL, NULL); + partial_end + 1, did_zero, NULL); return err; } =20 @@ -4406,6 +4408,7 @@ int ext4_punch_hole(struct file *file, loff_t offset,= loff_t length) loff_t end =3D offset + length; handle_t *handle; unsigned int credits; + bool partial_zeroed =3D false; int ret; =20 trace_ext4_punch_hole(inode, offset, length, 0); @@ -4441,9 +4444,15 @@ 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); + ret =3D ext4_zero_partial_blocks(inode, offset, length, &partial_zeroed); if (ret) return ret; + if (((file->f_flags & O_SYNC) || IS_SYNC(inode)) && partial_zeroed) { + ret =3D filemap_write_and_wait_range(inode->i_mapping, offset, + end - 1); + if (ret) + return ret; + } =20 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) credits =3D ext4_chunk_trans_extent(inode, 0); --=20 2.52.0 From nobody Thu Apr 2 17:18:50 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 54BD53DA7CE; Fri, 27 Mar 2026 10:34:40 +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=1774607683; cv=none; b=WrpgtoGIOuuDcrPGLhxAZo35ex+SgAnWYIyANVo30zV2KvWu1SIWhZUmSf4BngloX5BBJX/SeGAYQz9as/uZz8WFOOPTGShnlCKiblnmeJ/AnykhPxTTTHRuyYpo0J5T4zLZh6jmbyWSAA88BZtvPT44KyuxBL4kvUSLYin+2Sk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607683; c=relaxed/simple; bh=SJjes3iGDrA6L1XeuCKnKGzpfXUkDoov3mS2gTY12Nk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GPdITwTA/PGRKKFqX1G8zTi1K0g30Ub/BW0GPaa1Qu55UlA+JExSuphzkHjBNAnj4snFiMPsEE54EWwx73jAgE79aUrsEEgD90V0cxh73pLE1VW8MstfVgHaZ4ERGp7bFsn0kThYNSaw69uSnHRGUY+ZgGeD6SFxz0oQ0mg5Of8= 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.177]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fhxpM1FY4zYQv70; Fri, 27 Mar 2026 18:34:19 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id BF9224058D; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S14; Fri, 27 Mar 2026 18:34:32 +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 v4 10/13] ext4: unify SYNC mode checks in fallocate paths Date: Fri, 27 Mar 2026 18:29:36 +0800 Message-ID: <20260327102939.1095257-11-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S14 X-Coremail-Antispam: 1UD129KBjvJXoW7uF17Ary5CF1xJrWDuw1kGrg_yoW8KF1kp3 yrGa48Kr10gFyjgrsagF4UZF12y3WkK3y8WrWkC34Fqa9Iqr1Fga4rt3WFkF47X3yruF4U XFWUK34UGa17C37anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU= X-CM-SenderInfo: d1lo6xhdqjqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Zhang Yi In the ext4 fallocate call chain, SYNC mode handling is inconsistent: some places check the inode state, while others check the open file descriptor state. Unify these checks by evaluating both conditions to ensure consistent behavior across all fallocate operations. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/extents.c | 9 +++++---- fs/ext4/inode.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 16386f499138..f4009544f762 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4753,7 +4753,7 @@ static long ext4_zero_range(struct file *file, loff_t= offset, goto out_handle; =20 ext4_update_inode_fsync_trans(handle, inode, 1); - if (file->f_flags & O_SYNC) + if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) ext4_handle_sync(handle); =20 out_handle: @@ -4791,7 +4791,8 @@ static long ext4_do_fallocate(struct file *file, loff= _t offset, if (ret) goto out; =20 - if (file->f_flags & O_SYNC && EXT4_SB(inode->i_sb)->s_journal) { + if (((file->f_flags & O_SYNC) || IS_SYNC(inode)) && + EXT4_SB(inode->i_sb)->s_journal) { ret =3D ext4_fc_commit(EXT4_SB(inode->i_sb)->s_journal, EXT4_I(inode)->i_sync_tid); } @@ -5564,7 +5565,7 @@ static int ext4_collapse_range(struct file *file, lof= f_t offset, loff_t len) goto out_handle; =20 ext4_update_inode_fsync_trans(handle, inode, 1); - if (IS_SYNC(inode)) + if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) ext4_handle_sync(handle); =20 out_handle: @@ -5688,7 +5689,7 @@ static int ext4_insert_range(struct file *file, loff_= t offset, loff_t len) goto out_handle; =20 ext4_update_inode_fsync_trans(handle, inode, 1); - if (IS_SYNC(inode)) + if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) ext4_handle_sync(handle); =20 out_handle: diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b934ad86a96d..3b150e643ef5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4501,7 +4501,7 @@ int ext4_punch_hole(struct file *file, loff_t offset,= loff_t length) goto out_handle; =20 ext4_update_inode_fsync_trans(handle, inode, 1); - if (IS_SYNC(inode)) + if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) ext4_handle_sync(handle); out_handle: ext4_journal_stop(handle); --=20 2.52.0 From nobody Thu Apr 2 17:18:50 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 621411C3F31; Fri, 27 Mar 2026 10:34:34 +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=1774607676; cv=none; b=jSgT6Ax5B4kHbeUVtJmpcWv+yD1fFtyF+k/Mhr2TKM/CafMdk6Y7kSxaWttG4C3K8FlKTdG03gghT7WFah4HdZMyI8mE0VWKy0FLqtnR9QD1aZlE+mPgFA8er2fmfsqM77Qe3PxBZ6v5v0u0/3rTg9vfdulxeo1GyOZM2jHLdHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607676; c=relaxed/simple; bh=Pr9zvjwOfGLX5Mr9kIHJP1iN6iabU2fPfM7KwF0Hr9k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=C1I2++Uspm2bsFN9k/sQczWmxjwhzdEeFHIMAmkVILCx3KgzWsxEhNjBB7aAa/y77BplAYSPTJ9x0WU7Hm4y5u2pq/FQDfN6Y9wvDS11v23ekapUCVt8b97dJoOJwpuIU7D6tic7C0qAkv9FAIYt0k2bZgbCAzt3orWaj0QzRsg= 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.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4fhxnq1FSkzKHMdw; Fri, 27 Mar 2026 18:33:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id D1B4740572; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S15; Fri, 27 Mar 2026 18:34:32 +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 v4 11/13] ext4: remove ctime/mtime update from ext4_alloc_file_blocks() Date: Fri, 27 Mar 2026 18:29:37 +0800 Message-ID: <20260327102939.1095257-12-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S15 X-Coremail-Antispam: 1UD129KBjvdXoWrtFyUCrW7Cr4rCw48ZFWfAFb_yoWkGrc_Wa y7JrW0yw43X3WSgF4DCw13JwsYvr18Gr15WFWftFWfZw1UKrWkJ3WDAr15urW5Ww45CrZ8 Ww4ktr4UtryIgjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJTRUUUbvAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k26cxKx2IYs7xG 6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAVCq3wA2048vs2 IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28E F7xvwVC0I7IYx2IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr 1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0D M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjx v20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1l F7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2 IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF 0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsG vfC2KfnxnUUI43ZEXa7VU1zpBDUUUUU== 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 Reviewed-by: Jan Kara --- 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 f4009544f762..7abe47f923c0 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 17:18:50 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 8A9803A9636; Fri, 27 Mar 2026 10:34:34 +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=1774607680; cv=none; b=IWxDWabzjbYG4sp61BxSaGvQ6cwDlmadZ4j/MuC4Mc+AMzC1wblQg5wb+wcI/HdfzolzL5Y0gL22k4fwt3lktB6hgMPx9Dq6PB02qjrkpOqOsQLiT/77TTg2fKELtb6khr1qLZwUu0I2f4030vwdyd1On8GDqMEfTa1K4XFOBgY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607680; c=relaxed/simple; bh=3KQAjTexdz03Het2sU0IPCHZadGHhf7+7gZl/XOiIFw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Gyh4/1WZIb+vvVaLoUE8HxTzfEHq1FBN4reWArg/J4M8ptS/6SZZhI5G7FWDJIp9OW3Xd+i2dGHihlY1gVG+XFOGE5LsOVoj5CtSaj+Fml+ygbN1KITmMLl+7UqYBqGcOMcBLSoXxB+i/T51rJ4EN9BHK6AXGTCZxrNKoi4gH7U= 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 4fhxnq1hlMzKHMds; Fri, 27 Mar 2026 18:33:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id E112A40596; Fri, 27 Mar 2026 18:34:32 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S16; Fri, 27 Mar 2026 18:34:32 +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 v4 12/13] ext4: move pagecache_isize_extended() out of active handle Date: Fri, 27 Mar 2026 18:29:38 +0800 Message-ID: <20260327102939.1095257-13-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S16 X-Coremail-Antispam: 1UD129KBjvJXoWxJFy3Xr1fKr1rAw15Gw18Grg_yoWrJFyfpr W3CF1FyF1FgFyv9rsayr4DZr4Yga48KrWUXr93Wr9Yv3ZxXw1fKryYyFyFvFW5trW8XF4Y qr4Dt345G3WUA3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU= 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 Reviewed-by: Jan Kara --- fs/ext4/extents.c | 62 +++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7abe47f923c0..f13f604b1f67 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4553,7 +4553,7 @@ static int ext4_alloc_file_blocks(struct file *file, = loff_t offset, loff_t len, ext4_lblk_t len_lblk; struct ext4_map_blocks map; unsigned int credits; - loff_t epos, old_size =3D i_size_read(inode); + loff_t epos =3D 0, old_size =3D i_size_read(inode); unsigned int blkbits =3D inode->i_blkbits; bool alloc_zero =3D false; =20 @@ -4618,44 +4618,60 @@ 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); - } - 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, + 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 (ret2) + if (ret) break; } =20 - map.m_lblk +=3D ret; - map.m_len =3D len_lblk =3D len_lblk - ret; + map.m_lblk +=3D map.m_len; + map.m_len =3D len_lblk =3D len_lblk - map.m_len; + epos =3D EXT4_LBLK_TO_B(inode, map.m_lblk); } + if (ret =3D=3D -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; =20 - return ret > 0 ? ret2 : ret; + if (!epos || !new_size) + return ret; + + /* + * Allocate blocks, update the file size to match the size of the + * already successfully allocated blocks. + */ + if (epos > new_size) + epos =3D new_size; + + handle =3D ext4_journal_start(inode, EXT4_HT_MISC, 1); + if (IS_ERR(handle)) + return ret ? ret : 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 (epos > old_size) + pagecache_isize_extended(inode, old_size, epos); + + 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 17:18:50 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 556C43DA7DD; Fri, 27 Mar 2026 10:34:40 +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=1774607683; cv=none; b=dGUjYtlPlSvG8bTIck16V7taoLA3fVCiBf9cbEU5GWjff38JHEDLbXXnEu4Ds5gHqvKTX6M1XNq/K+mLZ1CwDCDkzt0LrzeBkGR5IinCUrpbGsizINQdj5d5bMzl6IpMIwJV2o61QYsqBOKIs4dxD1s1VIWXDk8ozehtOqiXQ54= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774607683; c=relaxed/simple; bh=HWHjJwruyHq/Wbz4i5l0dAiCgRGI7Sfz7pY8baZw8Ns=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cDpCDvZOWib5BVHRLQqkVMmw2Wx9iQX39Oqs/4P5NIKZtR7G2jj5o0idb9zMkxyU6xOsKVh0mGbePsm2d52rL+YlJAqAAbBJu6VKTA6LUJicTX+8utTG7Jp/MoZ2jJceCQVadc5ZHp5aviQyIwfQ8BOERupbxwaXIkcaPoRJwHo= 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 4fhxpM2wlMzYQv8r; Fri, 27 Mar 2026 18:34:19 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 03C0E4056F; Fri, 27 Mar 2026 18:34:33 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.85.155]) by APP1 (Coremail) with SMTP id cCh0CgC3utouXcZp_T2cCQ--.28730S17; Fri, 27 Mar 2026 18:34:32 +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 v4 13/13] ext4: zero post-EOF partial block before appending write Date: Fri, 27 Mar 2026 18:29:39 +0800 Message-ID: <20260327102939.1095257-14-yi.zhang@huaweicloud.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260327102939.1095257-1-yi.zhang@huaweicloud.com> References: <20260327102939.1095257-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: cCh0CgC3utouXcZp_T2cCQ--.28730S17 X-Coremail-Antispam: 1UD129KBjvJXoWxGrW8WrWrtryxZr17Gr1Dtrb_yoWrWFW3pF ZIkF1fuwnFgr9rW3yxGFsrX34jka48JrW7GFyfKrWfZFnxJw18KF1Iq34UtFWrtrZrXa1F qF4qkFyUG3Wjy3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU= 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 3b150e643ef5..7afa5fbf067b 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