Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2226009/?format=api
{ "id": 2226009, "url": "http://patchwork.ozlabs.org/api/patches/2226009/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/patch/20260422021042.4157510-21-yi.zhang@huaweicloud.com/", "project": { "id": 8, "url": "http://patchwork.ozlabs.org/api/projects/8/?format=api", "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-21-yi.zhang@huaweicloud.com>", "list_archive_url": null, "date": "2026-04-22T02:10:40", "name": "[v3,20/22] ext4: wait for ordered I/O in the iomap buffered I/O path", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "4a013e35d9c7393d317d947f7f6179077c40af34", "submitter": { "id": 85428, "url": "http://patchwork.ozlabs.org/api/people/85428/?format=api", "name": "Zhang Yi", "email": "yi.zhang@huaweicloud.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-ext4/patch/20260422021042.4157510-21-yi.zhang@huaweicloud.com/mbox/", "series": [ { "id": 500911, "url": "http://patchwork.ozlabs.org/api/series/500911/?format=api", "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/2226009/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2226009/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <SRS0=Ci/G=CV=vger.kernel.org=linux-ext4+bounces-15977-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=ci/g=cv=vger.kernel.org=linux-ext4+bounces-15977-patchwork-incoming=ozlabs.org@ozlabs.org;\n receiver=patchwork.ozlabs.org)", "gandalf.ozlabs.org;\n arc=pass smtp.remote-ip=172.105.105.114 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=172.105.105.114; helo=tor.lore.kernel.org;\n envelope-from=linux-ext4+bounces-15977-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org)", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=45.249.212.51", "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 4g0jcn3hRVz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 12:20:41 +1000 (AEST)", "from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\tby gandalf.ozlabs.org (Postfix) with ESMTP id 4g0jcn3CDmz4w1l\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 12:20:41 +1000 (AEST)", "by gandalf.ozlabs.org (Postfix)\n\tid 4g0jcn33shz4wK3; Wed, 22 Apr 2026 12:20:41 +1000 (AEST)", "from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114])\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 4g0jcj5DJCz4w1l\n\tfor <patchwork-incoming@ozlabs.org>; Wed, 22 Apr 2026 12:20:37 +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 500FA307DCF9\n\tfor <patchwork-incoming@ozlabs.org>; Wed, 22 Apr 2026 02:17:45 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 65C7B31DDBF;\n\tWed, 22 Apr 2026 02:17:07 +0000 (UTC)", "from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com\n [45.249.212.51])\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 BC47D3126BF;\n\tWed, 22 Apr 2026 02:17:03 +0000 (UTC)", "from mail.maildlp.com (unknown [172.19.163.170])\n\tby dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4g0jWN2FztzYQts7;\n\tWed, 22 Apr 2026 10:16:00 +0800 (CST)", "from mail02.huawei.com (unknown [10.116.40.252])\n\tby mail.maildlp.com (Postfix) with ESMTP id 7F521405D4;\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--.2635S24;\n\tWed, 22 Apr 2026 10:16:57 +0800 (CST)" ], "ARC-Seal": [ "i=2; a=rsa-sha256; d=ozlabs.org; s=201707; t=1776824441; cv=pass;\n\tb=hzGzaXCV5rdAb4diMzZ2TQC0fiETYDgwofqhIWezJAi7e0J1qnyvaalnk5RQj9qsdiMjG3gxm4+gszmoCQo47kRc8i2Z4Qobw72CyNltCSxQcDQ7xBsAWYlt51HrtOesQsYNs/gb5yGmmm598EU6tpI/VLU1upmITwoVx5evRuALUTem32fXQikAX9z1z8rYf9+racdP9zsnlztHq7960FXCermcJ9sFbwcNRPmdtXYD2jgXt0dtDKllhoQj88wfS/vQArmrA9nW63QZx1SC96d5nMuPyq8DTxghTUjDCag6LCLXY5T0YqfM60QRdD6JYKLALLS8YeGWd4W1GEbXRA==", "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776824227; cv=none;\n b=ecDZi5DtIgD8grnjDRwQHiidDxr0kF7xJXMZIuNCwhQ6sMBpHM14UGmxdMq83KYAwQysTvxPQy7aXw3xDUDqC+ZIZ5/VzL1dKKZym6Fj4eCg86M9UTAXBNaTMs9RSHg2hXa2aizNec3JYKfs2VAZ55JfRrihtkLjoDtH/gL/+Zo=" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; d=ozlabs.org; s=201707;\n\tt=1776824441; c=relaxed/relaxed;\n\tbh=p0LiYke6OMXjwrUiMmVpHPaolVTKDUy8H1flFyBilVs=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=YQ8LMCrY1O0KYrh6tC7wXjN+I8zZ2akZwdyMlt0DnVh4EriM+DSoFneKZgm0Y1ITw7cZNaq6tAA+bki2ju0IOPmO7K2V+Wsta5V+cwVtdp8z5xRfxs4y+zOFe3WngA4EUO8IELyya1pkrZHL/n8ExG7lkm6EWOrwEjpwJqkYm/HJsfZGbYHcaSplMAEHi8e6JaU8VIfIIvWJhqU5bqAEfvTODbjnXXkaWTqsv2jnmFQYC8LeQy6lyE/dwic0bHDkFOqtLre9VqCpodBIuPnIpOKSCE38I2L/7xiNJ2McKIUROlYwAHezdbsXhOnUqBF/VRUAHrDI6ULWl+LAzW5RsQ==", "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776824227; c=relaxed/simple;\n\tbh=VuThvL7HFbKLHMEQCWYtRfLW/E7czcP9Vozi62Ou0Dg=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=p1u73oLamVl4weVm2UDyM8NaXsT1rfs4ZDP8NfheSrrOmeRVSjy8h+gSF+xjgPBV27TaCyzBEoM+eb+lbfstvR4p3pwifNjd6fhI9bQ9rN4/o2bWhTizi8YrwaFA3mTnl4qyeem9a3fJWn3pEl+t0MUi4Fd/Zp3RG4tgwW/Gu10=" ], "ARC-Authentication-Results": [ "i=2; gandalf.ozlabs.org;\n dmarc=none (p=none dis=none) header.from=huaweicloud.com;\n spf=pass (client-ip=172.105.105.114; helo=tor.lore.kernel.org;\n envelope-from=linux-ext4+bounces-15977-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.51" ], "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 20/22] ext4: wait for ordered I/O in the iomap buffered I/O\n path", "Date": "Wed, 22 Apr 2026 10:10:40 +0800", "Message-ID": "<20260422021042.4157510-21-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--.2635S24", "X-Coremail-Antispam": "1UD129KBjvJXoW3Jr4ktrW3ZrWUWrWrCFWxZwb_yoWfur1DpF\n\tW3GryrGw48ZF929rs3Xw48Zr1Fq3WxKayrJFWfWanIvayUGryIkF1FyF15ZFyUKrZrJrWI\n\tqF48Jr47Wr1DJrJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2\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\nWait for ordered I/O to complete before updating i_disksize. This\nensures zeroed data is flushed to disk before the i_disksize metadata is\nupdated, preventing stale data exposure during unaligned post-EOF append\nwrites.\n\nSuggested-by: Jan Kara <jack@suse.cz>\nSigned-off-by: Zhang Yi <yi.zhang@huawei.com>\n---\n fs/ext4/ext4.h | 11 +++++++++\n fs/ext4/inode.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----\n fs/ext4/page-io.c | 53 ++++++++++++++++++++++++++++++++++++++++\n fs/ext4/super.c | 23 +++++++++++++-----\n 4 files changed, 137 insertions(+), 12 deletions(-)", "diff": "diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h\nindex 60ba488b01c5..760400395cb7 100644\n--- a/fs/ext4/ext4.h\n+++ b/fs/ext4/ext4.h\n@@ -1195,6 +1195,15 @@ struct ext4_inode_info {\n #ifdef CONFIG_FS_ENCRYPTION\n \tstruct fscrypt_inode_info *i_crypt_info;\n #endif\n+\n+\t/*\n+\t * Track ordered zeroed data during post-EOF append writes, fallocate,\n+\t * and truncate-up operations. These parameters are used only in the\n+\t * iomap buffered I/O path.\n+\t */\n+\text4_lblk_t i_ordered_lblk;\n+\text4_lblk_t i_ordered_len;\n+\twait_queue_head_t i_ordered_wq;\n };\n \n /*\n@@ -3877,6 +3886,8 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,\n \t\t\t __u64 len, __u64 *moved_len);\n \n /* page-io.c */\n+#define EXT4_IOMAP_IOEND_ORDER_IO\t1UL\t/* This I/O is an ordered one */\n+\n extern int __init ext4_init_pageio(void);\n extern void ext4_exit_pageio(void);\n extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);\ndiff --git a/fs/ext4/inode.c b/fs/ext4/inode.c\nindex d55899c1ef4c..17bd4403c782 100644\n--- a/fs/ext4/inode.c\n+++ b/fs/ext4/inode.c\n@@ -4352,12 +4352,37 @@ static int ext4_iomap_writeback_submit(struct iomap_writepage_ctx *wpc,\n {\n \tstruct iomap_ioend *ioend = wpc->wb_ctx;\n \tstruct ext4_inode_info *ei = EXT4_I(ioend->io_inode);\n+\text4_lblk_t start, end, order_lblk, order_len;\n \n \t/* Need to convert unwritten extents when I/Os are completed. */\n \tif ((ioend->io_flags & IOMAP_IOEND_UNWRITTEN) ||\n \t ioend->io_offset + ioend->io_size > READ_ONCE(ei->i_disksize))\n \t\tioend->io_bio.bi_end_io = ext4_iomap_end_bio;\n \n+\t/*\n+\t * Mark the I/O as ordered. Ordered I/O requires separate endio\n+\t * handling and must not be merged with regular I/O operations.\n+\t */\n+\torder_len = READ_ONCE(ei->i_ordered_len);\n+\tif (order_len) {\n+\t\t/*\n+\t\t * Pair with smp_store_release() in ext4_block_zero_eof().\n+\t\t * Ensure we see the updated i_ordered_lblk that was written\n+\t\t * before the release store to i_ordered_len.\n+\t\t */\n+\t\tsmp_rmb();\n+\t\torder_lblk = READ_ONCE(ei->i_ordered_lblk);\n+\t\tstart = ioend->io_offset >> ioend->io_inode->i_blkbits;\n+\t\tend = EXT4_B_TO_LBLK(ioend->io_inode,\n+\t\t\t\t ioend->io_offset + ioend->io_size);\n+\n+\t\tif (start <= order_lblk && end >= order_lblk + order_len) {\n+\t\t\tioend->io_bio.bi_end_io = ext4_iomap_end_bio;\n+\t\t\tioend->io_private = (void *)EXT4_IOMAP_IOEND_ORDER_IO;\n+\t\t\tioend->io_flags |= IOMAP_IOEND_BOUNDARY;\n+\t\t}\n+\t}\n+\n \treturn iomap_ioend_writeback_submit(wpc, error);\n }\n \n@@ -4799,12 +4824,12 @@ int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end)\n \t\t\t\treturn err;\n \t\t/*\n \t\t * inodes using the iomap buffered I/O path do not use the\n-\t\t * data=ordered mode. We submit zeroed range here.\n-\t\t *\n-\t\t * TODO: The end_io process needs to wait for I/O to completes\n-\t\t * before updating i_disksize.\n+\t\t * data=ordered mode. Submit zeroed range here. The end_io\n+\t\t * handler ext4_iomap_wb_ordered_wait() will wait for I/O\n+\t\t * completion before updating i_disksize.\n \t\t */\n \t\t} else if (ext4_inode_buffered_iomap(inode)) {\n+\t\t\tstruct ext4_inode_info *ei = EXT4_I(inode);\n \t\t\tstruct folio *folio;\n \t\t\tbool do_submit = false;\n \n@@ -4818,16 +4843,41 @@ int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end)\n \t\t\tfolio_wait_writeback(folio);\n \t\t\tWARN_ON_ONCE(folio_test_writeback(folio));\n \n-\t\t\tif (likely(folio_test_dirty(folio)))\n+\t\t\t/*\n+\t\t\t * Mark the ordered range. It will be cleared upon\n+\t\t\t * I/O completion in ext4_iomap_end_bio().\n+\t\t\t */\n+\t\t\tif (likely(folio_test_dirty(folio)) &&\n+\t\t\t READ_ONCE(ei->i_ordered_len) == 0) {\n+\t\t\t\tWRITE_ONCE(ei->i_ordered_lblk,\n+\t\t\t\t\t from >> inode->i_blkbits);\n+\t\t\t\t/*\n+\t\t\t\t * Pairs with smp_rmb() in\n+\t\t\t\t * ext4_iomap_writeback_submit() and\n+\t\t\t\t * ext4_iomap_wb_ordered_wait(). Ensure the\n+\t\t\t\t * updated i_ordered_lblk is visible when\n+\t\t\t\t * i_ordered_len becomes non-zero.\n+\t\t\t\t */\n+\t\t\t\tsmp_store_release(&ei->i_ordered_len, 1);\n \t\t\t\tdo_submit = true;\n+\t\t\t}\n \t\t\tfolio_unlock(folio);\n \t\t\tfolio_put(folio);\n \n \t\t\tif (do_submit) {\n \t\t\t\terr = filemap_fdatawrite_range(inode->i_mapping,\n \t\t\t\t\t\t\t from, end - 1);\n-\t\t\t\tif (err)\n+\t\t\t\tif (err) {\n+\t\t\t\t\t/*\n+\t\t\t\t\t * Pairs with wait_event() in\n+\t\t\t\t\t * ext4_iomap_wb_ordered_wait(). Ensure\n+\t\t\t\t\t * i_ordered_len = 0 is visible before\n+\t\t\t\t\t * waking up waiters.\n+\t\t\t\t\t */\n+\t\t\t\t\tsmp_store_release(&ei->i_ordered_len, 0);\n+\t\t\t\t\twake_up_all(&ei->i_ordered_wq);\n \t\t\t\t\treturn err;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n \t}\ndiff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c\nindex 07978e2cd9c8..9c88671836fe 100644\n--- a/fs/ext4/page-io.c\n+++ b/fs/ext4/page-io.c\n@@ -613,6 +613,39 @@ int ext4_bio_write_folio(struct ext4_io_submit *io, struct folio *folio,\n \treturn 0;\n }\n \n+/*\n+ * If the old disk size is not block size aligned and the current\n+ * writeback range is entirely beyond the old EOF block, we should\n+ * wait for the zeroed data written in ext4_block_zero_eof() to be\n+ * written out, otherwise, it may expose stale data in that block.\n+ */\n+static void ext4_iomap_wb_ordered_wait(struct inode *inode,\n+\t\t\t\t loff_t pos, loff_t end)\n+{\n+\tstruct ext4_inode_info *ei = EXT4_I(inode);\n+\tunsigned int blocksize = i_blocksize(inode);\n+\tloff_t disksize = READ_ONCE(ei->i_disksize);\n+\text4_lblk_t order_lblk, order_len;\n+\n+\tif (!(disksize & (blocksize - 1)) ||\n+\t pos <= round_up(disksize, blocksize))\n+\t\treturn;\n+\n+\torder_len = READ_ONCE(ei->i_ordered_len);\n+\tif (!order_len)\n+\t\treturn;\n+\n+\t/*\n+\t * Pair with smp_store_release() in ext4_iomap_end_bio() and\n+\t * ext4_block_zero_eof(). Ensure we see the updated i_ordered_lblk\n+\t * that was written before the release store to i_ordered_len.\n+\t */\n+\tsmp_rmb();\n+\torder_lblk = READ_ONCE(ei->i_ordered_lblk);\n+\tif ((pos >> inode->i_blkbits) >= order_lblk + order_len)\n+\t\twait_event(ei->i_ordered_wq, READ_ONCE(ei->i_ordered_len) == 0);\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 {\n@@ -656,6 +689,9 @@ static void ext4_iomap_finish_ioend(struct iomap_ioend *ioend)\n \t\tgoto out;\n \t}\n \n+\t/* Wait ordered zero data to be written out. */\n+\text4_iomap_wb_ordered_wait(inode, pos, pos + size);\n+\n \t/* We may need to convert one extent and dirty the inode. */\n \tcredits = ext4_chunk_trans_blocks(inode,\n \t\t\tEXT4_MAX_BLOCKS(size, pos, inode->i_blkbits));\n@@ -717,9 +753,26 @@ void ext4_iomap_end_bio(struct bio *bio)\n \tstruct inode *inode = ioend->io_inode;\n \tstruct ext4_inode_info *ei = EXT4_I(inode);\n \tstruct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);\n+\tunsigned long io_mode = (unsigned long)ioend->io_private;\n \tunsigned long flags;\n \tint ret;\n \n+\t/*\n+\t * This is an ordered I/O, clear the ordered range set in\n+\t * ext4_block_zero_eof() and wake up all waiters that will update\n+\t * the inode i_disksize.\n+\t */\n+\tif (io_mode == EXT4_IOMAP_IOEND_ORDER_IO) {\n+\t\t/*\n+\t\t * Pairs with wait_event() in ext4_iomap_wb_ordered_wait().\n+\t\t * Ensure i_ordered_len = 0 is visible before waking up\n+\t\t * waiters.\n+\t\t */\n+\t\tsmp_store_release(&ei->i_ordered_len, 0);\n+\t\twake_up_all(&ei->i_ordered_wq);\n+\t\tgoto defer;\n+\t}\n+\n \t/* Needs to convert unwritten extents or update the i_disksize. */\n \tif ((ioend->io_flags & IOMAP_IOEND_UNWRITTEN) ||\n \t ioend->io_offset + ioend->io_size > READ_ONCE(ei->i_disksize))\ndiff --git a/fs/ext4/super.c b/fs/ext4/super.c\nindex b2da4834b6bb..2fc07739c9e8 100644\n--- a/fs/ext4/super.c\n+++ b/fs/ext4/super.c\n@@ -1444,6 +1444,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)\n \text4_fc_init_inode(&ei->vfs_inode);\n \tspin_lock_init(&ei->i_fc_lock);\n \tmmb_init(&ei->i_metadata_bhs, &ei->vfs_inode.i_data);\n+\tei->i_ordered_lblk = 0;\n+\tei->i_ordered_len = 0;\n+\tinit_waitqueue_head(&ei->i_ordered_wq);\n \treturn &ei->vfs_inode;\n }\n \n@@ -1480,12 +1483,20 @@ static void ext4_destroy_inode(struct inode *inode)\n \t\tdump_stack();\n \t}\n \n-\tif (!(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ERROR_FS) &&\n-\t WARN_ON_ONCE(EXT4_I(inode)->i_reserved_data_blocks))\n-\t\text4_msg(inode->i_sb, KERN_ERR,\n-\t\t\t \"Inode %llu (%p): i_reserved_data_blocks (%u) not cleared!\",\n-\t\t\t inode->i_ino, EXT4_I(inode),\n-\t\t\t EXT4_I(inode)->i_reserved_data_blocks);\n+\tif (!(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ERROR_FS)) {\n+\t\tif (WARN_ON_ONCE(EXT4_I(inode)->i_reserved_data_blocks))\n+\t\t\text4_msg(inode->i_sb, KERN_ERR,\n+\t\t\t\t \"Inode %llu (%p): i_reserved_data_blocks (%u) not cleared!\",\n+\t\t\t\t inode->i_ino, EXT4_I(inode),\n+\t\t\t\t EXT4_I(inode)->i_reserved_data_blocks);\n+\n+\t\tif (WARN_ON_ONCE(EXT4_I(inode)->i_ordered_len))\n+\t\t\text4_msg(inode->i_sb, KERN_ERR,\n+\t\t\t\t \"Inode %llu (%p): i_ordered_lblk (%u) and i_ordered_len (%u) not cleared!\",\n+\t\t\t\t inode->i_ino, EXT4_I(inode),\n+\t\t\t\t EXT4_I(inode)->i_ordered_lblk,\n+\t\t\t\t EXT4_I(inode)->i_ordered_len);\n+\t}\n }\n \n static void ext4_shutdown(struct super_block *sb)\n", "prefixes": [ "v3", "20/22" ] }