From patchwork Wed Dec 13 06:23:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baokun Li X-Patchwork-Id: 13490422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1F4AC4332F for ; Wed, 13 Dec 2023 06:20:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 064FC6B045B; Wed, 13 Dec 2023 01:20:09 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 014BE6B045C; Wed, 13 Dec 2023 01:20:08 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E1DCA6B045D; Wed, 13 Dec 2023 01:20:08 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id CCD936B045B for ; Wed, 13 Dec 2023 01:20:08 -0500 (EST) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 9B6BF1C1449 for ; Wed, 13 Dec 2023 06:20:08 +0000 (UTC) X-FDA: 81560794896.07.D740701 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf08.hostedemail.com (Postfix) with ESMTP id 53D51160013 for ; Wed, 13 Dec 2023 06:20:04 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf08.hostedemail.com: domain of libaokun1@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=libaokun1@huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1702448407; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references; bh=HYMW0L/qrDIg+LZJu/NonlZryS9EYl+EMd3kz9qkQDw=; b=mLBHBeIW7WiJpc6SwuqPpZHNGB/ejVJjjkiacpS1CxEn+v4BHQjlAigDVKvCHo1fJlkSkm XxhU2kREJ8WS0ryZu9Qu7jpgeJQqOkclHy6zlPfSUy9cvcNLm0iOBY6AcowiE5pW6dHLSR FHKuS1KkkNJJKrMPyto17hffjRGqATs= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf08.hostedemail.com: domain of libaokun1@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=libaokun1@huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1702448407; a=rsa-sha256; cv=none; b=c6lqQZ9+yrQx/rxr4k0eJMOoLPA2WAmxwvZaQe5BOXzvRN3CMgBf8w18SKABY8YskN1tBH B9LC64lnFlFCakevJJanpkl+2qft00oaExv/FWTDYyCAuuQaO45Lw8Pf+atYXnTrj1Z448 m7EPqk/m7HuvXidlOrBsW/1YrQk/Sog= Received: from mail.maildlp.com (unknown [172.19.88.194]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4SqlhD2bxzzZcFZ; Wed, 13 Dec 2023 14:19:56 +0800 (CST) Received: from dggpeml500021.china.huawei.com (unknown [7.185.36.21]) by mail.maildlp.com (Postfix) with ESMTPS id 5126114093C; Wed, 13 Dec 2023 14:20:00 +0800 (CST) Received: from huawei.com (10.175.127.227) by dggpeml500021.china.huawei.com (7.185.36.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Wed, 13 Dec 2023 14:19:59 +0800 From: Baokun Li To: , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2] mm/filemap: avoid buffered read/write race to read inconsistent data Date: Wed, 13 Dec 2023 14:23:24 +0800 Message-ID: <20231213062324.739009-1-libaokun1@huawei.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To dggpeml500021.china.huawei.com (7.185.36.21) X-Rspamd-Queue-Id: 53D51160013 X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: fhhujs8czban4augehncdjqo55d3hnew X-HE-Tag: 1702448404-734962 X-HE-Meta: U2FsdGVkX19R4E8Exe4eY8YufTXwea8zseLBhHP5H1TMHcdDGOx5MTPbpCkgv5I8+4Z4oZP2aAmf7lN73WlpOxvvtkgnrq1F3/FktSWXPEwTUyRAAh7IlwOqj1LMMNNHySZTouAFKk9tW2Vc3NOWOTuj2HFt3VnQ8DbvgAIU2YFtKRcyUchohjlPPMSyIaTZL6EcW7exgv/jGbPJqYPCXly5AHqF1AWLBVg1zKHIHgimXy83oST45Y4OtIzSNvVVQs0jDk57zonz6CgMwLBsLfhRCxahm8Kz4G/BmRdhHbRNLhaX0Qavmm5rbRwX9uQfEck8z/SYVKZ0BUyKhCXs5YmzZIxtOKVStYkfiszDlRgFb6LzOxCrAc8Q3h6V+DOesO45TYhc+3NiDQKGtM34G5lSVITtlDcuSxFiRpEcfvNmAvxelAtYiDIfxJ1dpTjkCVUYPJU/rdt0xpppcavfBxRSYys9pSbGnnhG63Sw/hWaTXz35ZAjJoe48IkMQaYGd2YWBYfUtFFpcQEhdox8X3Ubr5Y7nIT51bdGzJi5Z/oBB2ylKwSiAKSUy0ccGfk3QPai2O/sTylcr31JmPsD937HuBMbgaNV4aSZKuo7HoikkglNydilrCpTtVoacS6lKDUW3zr3JHtaHKF6kpPuhXGEIKAx7s8IIZwv8YZfBzwOxsyMp/UB/yEqeJfQz1Rpfe9Oa7r4ZDOC88XnV9x77hjlcmAk1uBLh5XCjwpYxo+vXBVqQvmPFYIdJmLXMt9DGi+uaPI/5cfaIEJ38VK/igKVh1ILdz7nEFTSfafMY/IEuGfts1YkTkI+QCkTM9yHZPrz2mQiXV9S0cgyqbM+Vmaf0aRmVEd8THwa2hcFhjJDRm+eFwwSSot3TPn5P3rTfzIJ2vPEhH9xcKlECd8DMsXmF/8nX4OWEMiJfnP8J+PwsE6FKYoBC7HKXSdVjGo2849uZwXpQSoJDecwIFq y88/tHlY P4G7xJi5/iL09oPv0V+4wij3Eu+1XfEU81XDN6724rN4lzYBXqBzjhitxzexYauqSBL7rlccHy8830l3gUBEfwS+YsNHSE15xWwxN2ZsHI/9iKDA69KOtbiKD7y/GmQd6sdTIpn/6/qJaP/pjvrbZzMrU1sYaVzat6Iam29BlYOBfPPnwAYrzAIHBg/wGJhg6QVbEWxRXBhp4co8ufI7o+zDRFmJCIDr3zTo9kcrIyAaO4AC1P0X1N6TdCFb1sPCh/7syUft8KIYSEPrmCMEBu7d+eg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The following concurrency may cause the data read to be inconsistent with the data on disk: cpu1 cpu2 ------------------------------|------------------------------ // Buffered write 2048 from 0 ext4_buffered_write_iter generic_perform_write copy_page_from_iter_atomic ext4_da_write_end ext4_da_do_write_end block_write_end __block_commit_write folio_mark_uptodate // Buffered read 4096 from 0 smp_wmb() ext4_file_read_iter set_bit(PG_uptodate, folio_flags) generic_file_read_iter i_size_write // 2048 filemap_read unlock_page(page) filemap_get_pages filemap_get_read_batch folio_test_uptodate(folio) ret = test_bit(PG_uptodate, folio_flags) if (ret) smp_rmb(); // Ensure that the data in page 0-2048 is up-to-date. // New buffered write 2048 from 2048 ext4_buffered_write_iter generic_perform_write copy_page_from_iter_atomic ext4_da_write_end ext4_da_do_write_end block_write_end __block_commit_write folio_mark_uptodate smp_wmb() set_bit(PG_uptodate, folio_flags) i_size_write // 4096 unlock_page(page) isize = i_size_read(inode) // 4096 // Read the latest isize 4096, but without smp_rmb(), there may be // Load-Load disorder resulting in the data in the 2048-4096 range // in the page is not up-to-date. copy_page_to_iter // copyout 4096 In the concurrency above, we read the updated i_size, but there is no read barrier to ensure that the data in the page is the same as the i_size at this point, so we may copy the unsynchronized page out. Hence adding the missing read memory barrier to fix this. This is a Load-Load reordering issue, which only occurs on some weak mem-ordering architectures (e.g. ARM64, ALPHA), but not on strong mem-ordering architectures (e.g. X86). And theoretically the problem doesn't only happen on ext4, filesystems that call filemap_read() but don't hold inode lock (e.g. btrfs, f2fs, ubifs ...) will have this problem, while filesystems with inode lock (e.g. xfs, nfs) won't have this problem. Cc: stable@kernel.org Signed-off-by: Baokun Li Reviewed-by: Jan Kara --- V1->V2: Change the comment to the one suggested by Jan Kara. mm/filemap.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm/filemap.c b/mm/filemap.c index 71f00539ac00..10c4583c06ce 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2607,6 +2607,15 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, goto put_folios; end_offset = min_t(loff_t, isize, iocb->ki_pos + iter->count); + /* + * Pairs with a barrier in + * block_write_end()->mark_buffer_dirty() or other page + * dirtying routines like iomap_write_end() to ensure + * changes to page contents are visible before we see + * increased inode size. + */ + smp_rmb(); + /* * Once we start copying data, we don't want to be touching any * cachelines that might be contended: