public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Zhang Yi <yi.zhang@huaweicloud.com>
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 10/10] ext4: zero post-EOF partial block before appending write
Date: Tue, 10 Mar 2026 09:41:01 +0800	[thread overview]
Message-ID: <20260310014101.4140698-11-yi.zhang@huaweicloud.com> (raw)
In-Reply-To: <20260310014101.4140698-1-yi.zhang@huaweicloud.com>

From: Zhang Yi <yi.zhang@huawei.com>

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().

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
---
 fs/ext4/file.c  | 14 ++++++++++++++
 fs/ext4/inode.c | 21 +++++++--------------
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index f1dc5ce791a7..b2e44601ab6a 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,
 
 static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from)
 {
+	struct inode *inode = file_inode(iocb->ki_filp);
+	loff_t old_size = i_size_read(inode);
 	ssize_t ret, count;
 
 	count = ext4_generic_write_checks(iocb, from);
@@ -280,6 +282,18 @@ static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from)
 	ret = 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)) {
+		ret = ext4_block_zero_eof(inode, old_size, iocb->ki_pos);
+		if (ret < 0)
+			return ret;
+	}
+
 	return count;
 }
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5288d36b0f09..67a4d12fcb4d 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);
 
-	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 kiocb *iocb,
 	folio_unlock(folio);
 	folio_put(folio);
 
-	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);
-	}
 
 	if (size_changed) {
 		ret2 = ext4_mark_inode_dirty(handle, inode);
@@ -3196,7 +3193,7 @@ static int ext4_da_do_write_end(struct address_space *mapping,
 	struct inode *inode = mapping->host;
 	loff_t old_size = inode->i_size;
 	bool disksize_changed = false;
-	loff_t new_i_size, zero_len = 0;
+	loff_t new_i_size;
 	handle_t *handle;
 
 	if (unlikely(!folio_buffers(folio))) {
@@ -3240,19 +3237,15 @@ static int ext4_da_do_write_end(struct address_space *mapping,
 	folio_unlock(folio);
 	folio_put(folio);
 
-	if (pos > old_size) {
+	if (pos > old_size)
 		pagecache_isize_extended(inode, old_size, pos);
-		zero_len = pos - old_size;
-	}
 
-	if (!disksize_changed && !zero_len)
+	if (!disksize_changed)
 		return copied;
 
-	handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+	handle = 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);
 
-- 
2.52.0


  parent reply	other threads:[~2026-03-10  1:45 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-10  1:40 [PATCH 00/10] ext4: refactor partial block zero-out for iomap conversion Zhang Yi
2026-03-10  1:40 ` [PATCH 01/10] ext4: add did_zero output parameter to ext4_block_zero_page_range() Zhang Yi
2026-03-23 16:33   ` Jan Kara
2026-03-10  1:40 ` [PATCH 02/10] ext4: ext4_block_truncate_page() returns zeroed length on success Zhang Yi
2026-03-23 16:34   ` Jan Kara
2026-03-10  1:40 ` [PATCH 03/10] ext4: rename and extend ext4_block_truncate_page() Zhang Yi
2026-03-23 16:42   ` Jan Kara
2026-03-10  1:40 ` [PATCH 04/10] ext4: factor out journalled block zeroing range Zhang Yi
2026-03-23 16:48   ` Jan Kara
2026-03-24  3:16     ` Zhang Yi
2026-03-10  1:40 ` [PATCH 05/10] ext4: rename ext4_block_zero_page_range() to ext4_block_zero_range() Zhang Yi
2026-03-23 16:49   ` Jan Kara
2026-03-10  1:40 ` [PATCH 06/10] ext4: move ordered data handling out of ext4_block_do_zero_range() Zhang Yi
2026-03-23 16:59   ` Jan Kara
2026-03-24  3:17     ` Zhang Yi
2026-03-10  1:40 ` [PATCH 07/10] ext4: remove handle parameters from zero partial block functions Zhang Yi
2026-03-23 17:27   ` Jan Kara
2026-03-10  1:40 ` [PATCH 08/10] ext4: pass allocate range as loff_t to ext4_alloc_file_blocks() Zhang Yi
2026-03-23 17:06   ` Jan Kara
2026-03-10  1:41 ` [PATCH 09/10] ext4: move zero partial block range functions out of active handle Zhang Yi
2026-03-23 20:17   ` Jan Kara
2026-03-24  3:10     ` Zhang Yi
2026-03-24  3:14       ` Zhang Yi
2026-03-24 13:56       ` Jan Kara
2026-03-10  1:41 ` Zhang Yi [this message]
2026-03-23 20:31   ` [PATCH 10/10] ext4: zero post-EOF partial block before appending write Jan Kara
2026-03-24  3:29     ` Zhang Yi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260310014101.4140698-11-yi.zhang@huaweicloud.com \
    --to=yi.zhang@huaweicloud.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=jack@suse.cz \
    --cc=libaokun@linux.alibaba.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojaswin@linux.ibm.com \
    --cc=ritesh.list@gmail.com \
    --cc=tytso@mit.edu \
    --cc=yangerkun@huawei.com \
    --cc=yi.zhang@huawei.com \
    --cc=yizhang089@gmail.com \
    --cc=yukuai@fnnas.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox