{"id":2226023,"url":"http://patchwork.ozlabs.org/api/patches/2226023/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-ext4/patch/20260422021042.4157510-22-yi.zhang@huaweicloud.com/","project":{"id":8,"url":"http://patchwork.ozlabs.org/api/projects/8/?format=json","name":"Linux ext4 filesystem development","link_name":"linux-ext4","list_id":"linux-ext4.vger.kernel.org","list_email":"linux-ext4@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260422021042.4157510-22-yi.zhang@huaweicloud.com>","list_archive_url":null,"date":"2026-04-22T02:10:41","name":"[v3,21/22] ext4: update i_disksize to i_size on ordered I/O completion","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"902d412d0056fc7f999a428c91039f03d21574eb","submitter":{"id":85428,"url":"http://patchwork.ozlabs.org/api/people/85428/?format=json","name":"Zhang Yi","email":"yi.zhang@huaweicloud.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-ext4/patch/20260422021042.4157510-22-yi.zhang@huaweicloud.com/mbox/","series":[{"id":500911,"url":"http://patchwork.ozlabs.org/api/series/500911/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-ext4/list/?series=500911","date":"2026-04-22T02:10:23","name":"ext4: use iomap for regular file's buffered I/O path","version":3,"mbox":"http://patchwork.ozlabs.org/series/500911/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2226023/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2226023/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <SRS0=RLJq=CV=vger.kernel.org=linux-ext4+bounces-15986-patchwork-incoming=ozlabs.org@ozlabs.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-ext4@vger.kernel.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","patchwork-incoming@ozlabs.org"],"Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=ozlabs.org\n (client-ip=150.107.74.76; helo=mail.ozlabs.org;\n envelope-from=srs0=rljq=cv=vger.kernel.org=linux-ext4+bounces-15986-patchwork-incoming=ozlabs.org@ozlabs.org;\n receiver=patchwork.ozlabs.org)","gandalf.ozlabs.org;\n arc=pass smtp.remote-ip=\"2600:3c04:e001:36c::12fc:5321\"\n arc.chain=subspace.kernel.org","gandalf.ozlabs.org;\n dmarc=none (p=none dis=none) header.from=huaweicloud.com","gandalf.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-ext4+bounces-15986-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org)","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=45.249.212.56","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=huaweicloud.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=huaweicloud.com"],"Received":["from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0jjB4K4Gz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 12:24:30 +1000 (AEST)","from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\tby gandalf.ozlabs.org (Postfix) with ESMTP id 4g0jjB3rBZz4wCQ\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 12:24:30 +1000 (AEST)","by gandalf.ozlabs.org (Postfix)\n\tid 4g0jjB3jpgz4wCX; Wed, 22 Apr 2026 12:24:30 +1000 (AEST)","from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby gandalf.ozlabs.org (Postfix) with ESMTPS id 4g0jj66Vgbz4wCQ\n\tfor <patchwork-incoming@ozlabs.org>; Wed, 22 Apr 2026 12:24:26 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id B4F5D3061D4F\n\tfor <patchwork-incoming@ozlabs.org>; Wed, 22 Apr 2026 02:18:31 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id EE46137F72B;\n\tWed, 22 Apr 2026 02:17:09 +0000 (UTC)","from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com\n [45.249.212.56])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 07C7B318EE4;\n\tWed, 22 Apr 2026 02:17:05 +0000 (UTC)","from mail.maildlp.com (unknown [172.19.163.177])\n\tby dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4g0jX53mNGzKHMVC;\n\tWed, 22 Apr 2026 10:16:37 +0800 (CST)","from mail02.huawei.com (unknown [10.116.40.252])\n\tby mail.maildlp.com (Postfix) with ESMTP id 8C63B4059E;\n\tWed, 22 Apr 2026 10:16:57 +0800 (CST)","from huaweicloud.com (unknown [10.50.85.155])\n\tby APP3 (Coremail) with SMTP id _Ch0CgB3JL6PL+hpqkgUBQ--.2635S25;\n\tWed, 22 Apr 2026 10:16:57 +0800 (CST)"],"ARC-Seal":["i=2; a=rsa-sha256; d=ozlabs.org; s=201707; t=1776824670; cv=pass;\n\tb=Veo0BnfbQS9Igd3MjPB2wFGME2G/ViWo6sl0uAM0Rlz8BxgqWr/d4ikOP00De/3f1YS3JwYfPxeJngQ5rRCwPtSPvmtXLEAAjEmQ4PoZuJy3DfS24ADjE4RVw5leQRm/COx66f22R4QhAGkCIMsLCP+pH6OIYUZ9wUyfwQnDEzaKTxqe04KjUwyKQ7o6UuJ+sNtlC34Zp/G/FFmKw/BUF7dQd6TK+BfHDh6vDWty3MQCovd+zFgJf3q2gvcmEQb3Mt9dr8A5j1jQmw+wN2QWigw72hAXIliPpcXWPAv+3Cw6KtXq1PLyMVveecC1LNR3yC5gumM8r6rUjKQ5hakMZA==","i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776824229; cv=none;\n b=ry/cNvpNgRfdFENvBwi4YaRq1oU4rFl6zRkN1B+gVv+vTFg/2OZQPP1opkWBpZNE5t8dkSs6gUxMoeF4fS/QlrkDyilRC75yi4+nD9fTAh5A9w8dIF7xdGaYrGNZXz+Qv2zB8hmDp8j2C1xu9jaOi1BYAi99KqUXqvDHXNo8ihg="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=ozlabs.org; s=201707;\n\tt=1776824670; c=relaxed/relaxed;\n\tbh=Ts6TzBdtfVefY48+G5PEriliIYJTMKL0kJ4o1zS+wsc=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=WbY199maaJ2hcSoly2bMIya6RKiPc9/kaLDVDNRaS/wnPIBjfoD0RwcUUvdwk1DxWjyoEWZqIWVZqRZPzcKcin3MsW9hugtaiStSxl1ogffi7LfqGS7uZELE/WwGEscTYf/lyeDYr1Bw0ls5u9kE/ACTQg6mjsI1I9qXjh+t6Kg+UsJ/KYEU7aRhnG9vpuyEyc6NK19AxtFva0zkyFvX3RB60x6S9BjYnRwTFATNwmmz4FoB69YlFSJ2Gzfpv4zLYY3CtTfNlkdrW24FmjC1fT2ObmA/m6iV2KlpmqhE8B4v0/ZNLfz/V53D6o22sDeWdgjv5LDBBbRLBLQj9RuDrg==","i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776824229; c=relaxed/simple;\n\tbh=Az1p7Z0+js2vdk8ppJIgCWml4zi9NJHrRJulMljaR50=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=fP4Z9+L83nqYOxnQmp4AFnWh/rYMAl+TtUxDXbH0wHK8UotEmQMbIqwSWeqvzH5Sz7q6BprgEukzHFGc+A/0WXKXI1+O0XpcagXArMCdF7YVhBjn9i2ijpUQjKkGF2mty/5qYyTzpNVtRwnuyrp0X9ZPu5pWcBpUb0ynbnfTmLY="],"ARC-Authentication-Results":["i=2; gandalf.ozlabs.org;\n dmarc=none (p=none dis=none) header.from=huaweicloud.com;\n spf=pass (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-ext4+bounces-15986-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org) smtp.mailfrom=vger.kernel.org","i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=huaweicloud.com;\n spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56"],"From":"Zhang Yi <yi.zhang@huaweicloud.com>","To":"linux-ext4@vger.kernel.org,\n\tlinux-fsdevel@vger.kernel.org","Cc":"linux-kernel@vger.kernel.org,\n\ttytso@mit.edu,\n\tadilger.kernel@dilger.ca,\n\tlibaokun@linux.alibaba.com,\n\tjack@suse.cz,\n\tojaswin@linux.ibm.com,\n\tritesh.list@gmail.com,\n\tdjwong@kernel.org,\n\thch@infradead.org,\n\tyi.zhang@huawei.com,\n\tyi.zhang@huaweicloud.com,\n\tyizhang089@gmail.com,\n\tyangerkun@huawei.com,\n\tyukuai@fnnas.com","Subject":"[PATCH v3 21/22] ext4: update i_disksize to i_size on ordered I/O\n completion","Date":"Wed, 22 Apr 2026 10:10:41 +0800","Message-ID":"<20260422021042.4157510-22-yi.zhang@huaweicloud.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260422021042.4157510-1-yi.zhang@huaweicloud.com>","References":"<20260422021042.4157510-1-yi.zhang@huaweicloud.com>","Precedence":"bulk","X-Mailing-List":"linux-ext4@vger.kernel.org","List-Id":"<linux-ext4.vger.kernel.org>","List-Subscribe":"<mailto:linux-ext4+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-ext4+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-CM-TRANSID":"_Ch0CgB3JL6PL+hpqkgUBQ--.2635S25","X-Coremail-Antispam":"1UD129KBjvJXoW3WF13JFWxZw1kXr4kuF45KFg_yoWfXrWkpF\n\tW5K34rAw18XasF9rs2qryUXw1Fva18Gw48JFy7ur4vvFy5Awn2vFyxtryfCFW8trZ5Xw4j\n\tqFWktr48Wr1kAr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2\n\t9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0\n\trVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI\n\tkIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2\n\tz4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F\n\t4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq\n\t3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7\n\tIYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U\n\tM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2\n\tkIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE\n\tbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67\n\tAF67kF1VAFwI0_GFv_WrylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW5JVW7JwCI\n\t42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF\n\t4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI\n\tdaVFxhVjvjDU0xZFpf9x0JUWMKtUUUUU=","X-CM-SenderInfo":"d1lo6xhdqjqx5xdzvxpfor3voofrz/","X-Spam-Status":"No, score=-1.1 required=5.0 tests=ARC_SIGNED,ARC_VALID,\n\tDMARC_MISSING,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,\n\tSPF_HELO_NONE,SPF_PASS autolearn=disabled version=4.0.1","X-Spam-Checker-Version":"SpamAssassin 4.0.1 (2024-03-25) on gandalf.ozlabs.org"},"content":"From: Zhang Yi <yi.zhang@huawei.com>\n\nCurrently, i_disksize is updated after ordered data writeback to prevent\nexposing stale data in the post-EOF block. However, operations like\nfallocate and truncate update i_disksize directly. If the new i_disksize\nexceeds the original value, metadata may be written back before the\nzeroed data is persisted. To avoid this, we defer i_disksize updates\nwhen i_ordered_len is non-zero, only applying them after ordered I/O\ncompletes.\n\nBut this deferral introduces a new problem: on ordered I/O completion,\ni_disksize is updated only to the end of that specific I/O, discarding\nany later updates (e.g., from fallocate) and causing filesystem\ninconsistency. A potential fix would involve scanning for dirty or\nwriteback folios beyond the current position, then updating i_disksize\nto the start of the first such folio or to i_size. However, folio\nscanning is expensive and concurrency with operations like fallocate\nmakes this approach prohibitively complex.\n\nInstead, update i_disksize directly to i_size upon ordered I/O\ncompletion. This may expose zeroed data if dirty data within the range\nis not yet written to disk after crash recovery, but it will never\nexpose stale data. The is limited to unaligned append writes and is\ndeemed acceptable.\n\nSuggested-by: Jan Kara <jack@suse.cz>\nSigned-off-by: Zhang Yi <yi.zhang@huawei.com>\n---\n fs/ext4/ext4.h    | 40 +++++++++++++++++++++++++++++++---------\n fs/ext4/extents.c |  9 +++------\n fs/ext4/inode.c   |  3 ---\n fs/ext4/page-io.c | 23 ++++++++++++++++++-----\n 4 files changed, 52 insertions(+), 23 deletions(-)","diff":"diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h\nindex 760400395cb7..59dcec47675f 100644\n--- a/fs/ext4/ext4.h\n+++ b/fs/ext4/ext4.h\n@@ -3495,13 +3495,21 @@ do {\t\t\t\t\t\t\t\t\\\n #define EXT4_FREECLUSTERS_WATERMARK 0\n #endif\n \n-/* Update i_disksize. Requires i_rwsem to avoid races with truncate */\n+/*\n+ * Update i_disksize. Requires i_rwsem to avoid races with truncate.\n+ *\n+ * In the iomap buffered I/O path, a non-zero i_ordered_len indicates that\n+ * an ordered I/O (zeroing the EOF partial block) is still in progress.\n+ * In that case, i_disksize will be updated after the ordered data has\n+ * been written out.\n+ */\n static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize)\n {\n \tWARN_ON_ONCE(S_ISREG(inode->i_mode) &&\n \t\t     !inode_is_locked(inode));\n \tdown_write(&EXT4_I(inode)->i_data_sem);\n-\tif (newsize > EXT4_I(inode)->i_disksize)\n+\tif (newsize > EXT4_I(inode)->i_disksize &&\n+\t    READ_ONCE(EXT4_I(inode)->i_ordered_len) == 0)\n \t\tWRITE_ONCE(EXT4_I(inode)->i_disksize, newsize);\n \tup_write(&EXT4_I(inode)->i_data_sem);\n }\n@@ -3515,7 +3523,8 @@ static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize)\n \t\ti_size_write(inode, newsize);\n \t\tchanged = 1;\n \t}\n-\tif (newsize > EXT4_I(inode)->i_disksize) {\n+\tif (newsize > EXT4_I(inode)->i_disksize &&\n+\t    READ_ONCE(EXT4_I(inode)->i_ordered_len) == 0) {\n \t\text4_update_i_disksize(inode, newsize);\n \t\tchanged |= 2;\n \t}\n@@ -3523,19 +3532,32 @@ static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize)\n }\n \n /*\n- * Set i_size and i_disksize to 'newsize'.\n+ * Set i_size and i_disksize to 'newsize'.  In the iomap buffered I/O path,\n+ * if i_ordered_len is non-zero and newsize exceeds the current i_disksize,\n+ * the actual i_disksize update is deferred until after the ordered data is\n+ * written out. In that case, i_disksize will be set to i_size upon I/O\n+ * completion.\n  *\n  * Both i_rwsem and i_data_sem are required here to avoid races between\n- * generic append writeback and concurrent truncate that also modify\n- * i_size and i_disksize.\n+ * generic append writeback (or ordered I/O writeback) and concurrent\n+ * operations like fallocate and truncate that also modify i_size and\n+ * i_disksize.\n  */\n-static inline void ext4_set_inode_size(struct inode *inode, loff_t newsize)\n+static inline void __ext4_set_inode_size(struct inode *inode, loff_t newsize)\n {\n \tWARN_ON_ONCE(S_ISREG(inode->i_mode) && !inode_is_locked(inode));\n+\tWARN_ON_ONCE(!rwsem_is_locked(&EXT4_I(inode)->i_data_sem));\n \n-\tdown_write(&EXT4_I(inode)->i_data_sem);\n \ti_size_write(inode, newsize);\n-\tEXT4_I(inode)->i_disksize = newsize;\n+\tif (READ_ONCE(EXT4_I(inode)->i_ordered_len) == 0 ||\n+\t    newsize < EXT4_I(inode)->i_disksize)\n+\t\tEXT4_I(inode)->i_disksize = newsize;\n+}\n+\n+static inline void ext4_set_inode_size(struct inode *inode, loff_t newsize)\n+{\n+\tdown_write(&EXT4_I(inode)->i_data_sem);\n+\t__ext4_set_inode_size(inode, newsize);\n \tup_write(&EXT4_I(inode)->i_data_sem);\n }\n \ndiff --git a/fs/ext4/extents.c b/fs/ext4/extents.c\nindex 125f628e738a..e0c36cd920bf 100644\n--- a/fs/ext4/extents.c\n+++ b/fs/ext4/extents.c\n@@ -5531,7 +5531,7 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len)\n \text4_lblk_t start_lblk, end_lblk;\n \thandle_t *handle;\n \tunsigned int credits;\n-\tloff_t start, new_size;\n+\tloff_t start;\n \tint ret;\n \n \ttrace_ext4_collapse_range(inode, offset, len);\n@@ -5597,9 +5597,7 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len)\n \t\tgoto out_handle;\n \t}\n \n-\tnew_size = inode->i_size - len;\n-\ti_size_write(inode, new_size);\n-\tEXT4_I(inode)->i_disksize = new_size;\n+\t__ext4_set_inode_size(inode, inode->i_size - len);\n \n \tup_write(&EXT4_I(inode)->i_data_sem);\n \tret = ext4_mark_inode_dirty(handle, inode);\n@@ -5671,8 +5669,7 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)\n \text4_fc_mark_ineligible(sb, EXT4_FC_REASON_FALLOC_RANGE, handle);\n \n \t/* Expand file to avoid data loss if there is error while shifting */\n-\tinode->i_size += len;\n-\tEXT4_I(inode)->i_disksize += len;\n+\text4_set_inode_size(inode, inode->i_size + len);\n \tret = ext4_mark_inode_dirty(handle, inode);\n \tif (ret)\n \t\tgoto out_handle;\ndiff --git a/fs/ext4/inode.c b/fs/ext4/inode.c\nindex 17bd4403c782..d983336390c7 100644\n--- a/fs/ext4/inode.c\n+++ b/fs/ext4/inode.c\n@@ -4805,9 +4805,6 @@ int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end)\n \t * truncating up or performing an append write, because there might be\n \t * exposing stale on-disk data which may caused by concurrent post-EOF\n \t * mmap write during folio writeback.\n-\t *\n-\t * TODO: In the iomap path, handle this by updating i_disksize to\n-\t * i_size after the zeroed data has been written back.\n \t */\n \tif (did_zero && zero_written && !IS_DAX(inode)) {\n \t\tif (ext4_should_order_data(inode)) {\ndiff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c\nindex 9c88671836fe..589c74b9f8a3 100644\n--- a/fs/ext4/page-io.c\n+++ b/fs/ext4/page-io.c\n@@ -647,13 +647,13 @@ static void ext4_iomap_wb_ordered_wait(struct inode *inode,\n }\n \n static int ext4_iomap_wb_update_disksize(handle_t *handle, struct inode *inode,\n-\t\t\t\t\t loff_t end)\n+\t\t\t\t\t loff_t end, bool is_ordered)\n {\n-\tloff_t new_disksize = end;\n+\tloff_t new_disksize, i_size;\n \tstruct ext4_inode_info *ei = EXT4_I(inode);\n \tint ret;\n \n-\tif (new_disksize <= READ_ONCE(ei->i_disksize))\n+\tif (end <= READ_ONCE(ei->i_disksize) && !is_ordered)\n \t\treturn 0;\n \n \t/*\n@@ -661,7 +661,18 @@ static int ext4_iomap_wb_update_disksize(handle_t *handle, struct inode *inode,\n \t * are avoided by checking i_size under i_data_sem.\n \t */\n \tdown_write(&ei->i_data_sem);\n-\tnew_disksize = min(new_disksize, i_size_read(inode));\n+\ti_size = i_size_read(inode);\n+\n+\t/*\n+\t * Update i_disksize to i_size when completing an ordered I/O that\n+\t * zeroes the old EOF partial block. This ensures i_disksize is\n+\t * correctly advanced during truncate-up on a blocksize-unaligned\n+\t * file, preventing it from remaining stale. A downside is that\n+\t * zeroed data may be exposed after crash recovery if the dirty\n+\t * data in this range is not yet on disk, but stale data will\n+\t * never be exposed.\n+\t */\n+\tnew_disksize = is_ordered ? i_size : min(end, i_size);\n \tif (new_disksize > ei->i_disksize)\n \t\tei->i_disksize = new_disksize;\n \tup_write(&ei->i_data_sem);\n@@ -678,6 +689,7 @@ static void ext4_iomap_finish_ioend(struct iomap_ioend *ioend)\n \tstruct super_block *sb = inode->i_sb;\n \tloff_t pos = ioend->io_offset;\n \tsize_t size = ioend->io_size;\n+\tunsigned long io_mode = (unsigned long)ioend->io_private;\n \thandle_t *handle;\n \tint credits;\n \tint ret, err;\n@@ -707,7 +719,8 @@ static void ext4_iomap_finish_ioend(struct iomap_ioend *ioend)\n \t\t\tgoto out_journal;\n \t}\n \n-\tret = ext4_iomap_wb_update_disksize(handle, inode, pos + size);\n+\tret = ext4_iomap_wb_update_disksize(handle, inode, pos + size,\n+\t\t\tio_mode == EXT4_IOMAP_IOEND_ORDER_IO);\n out_journal:\n \terr = ext4_journal_stop(handle);\n \tif (!ret)\n","prefixes":["v3","21/22"]}