From nobody Mon Feb 9 19:55:42 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 1CD591553A2; Fri, 9 Aug 2024 12:05:22 +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=1723205126; cv=none; b=jzwDCj1BKfwuzvjIBcKXTJ8ggoF/dc1fDucwWX+VspoCGm3QTNhC0An5OmQ1e77O8O9EYQWyb7VVl5WvgTPiTbx4eITee+tUxTEoPhCv2ucgDhkCV5XxR+vKt+F8l9pfEkOpwMbIHRIEM0zjBKuh7zwvvL5gA/ZnB/x5vjsSukM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723205126; c=relaxed/simple; bh=8FXevOaaW4dMe8R/a9rzmc74R1/c7ClSkFGxKPEfuV0=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=NocAiFA85lHf1LYFxxAOjteLipu0Cn6PHYTz6gXXZshlAjQENpMEekufFWMd4lw972ihsFIsy0PQhQTy4UqIL9oqnvCY/RDpooQn+4VDLtcYDCLR9S34opT+MkhcYMkaFwwYOofckdfdnCMqygQpgUp7FVLYoORmnjfII0sCFmg= 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.216]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTP id 4WgMzb5yRlz4f3l21; Fri, 9 Aug 2024 20:04:59 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.252]) by mail.maildlp.com (Postfix) with ESMTP id 47BC81A0A22; Fri, 9 Aug 2024 20:05:14 +0800 (CST) Received: from huaweicloud.com (unknown [10.175.127.227]) by APP3 (Coremail) with SMTP id _Ch0CgC3Gbj0BbZm1E6mBA--.50645S4; Fri, 09 Aug 2024 20:05:12 +0800 (CST) From: Zhihao Cheng To: tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz Cc: linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, chengzhihao1@huawei.com, yi.zhang@huawei.com Subject: [PATCH] ext4: dax: Fix overflowing extents beyond inode size when partially writing Date: Fri, 9 Aug 2024 20:15:32 +0800 Message-Id: <20240809121532.2105494-1-chengzhihao@huaweicloud.com> X-Mailer: git-send-email 2.31.1 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: _Ch0CgC3Gbj0BbZm1E6mBA--.50645S4 X-Coremail-Antispam: 1UD129KBjvJXoWxAF4ftr1UZF18Cry8Jry8AFb_yoW5XFW5pr 9xKFyY9rWvqasFgay8tF4DZw4qk3W7GrWUCr1UKwn0vF9rZryfKF1jyF4FvF15JrWkuF12 qrsYkry8uw12y3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUyKb4IE77IF4wAFF20E14v26r4j6ryUM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4 vEj48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7Cj xVAFwI0_Cr0_Gr1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I 0E14v26rxl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40E x7xfMcIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x 0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lc7CjxVAaw2AFwI0_JF0_Jw1l42xK82IYc2Ij 64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x 8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE 2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42 xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF 7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUotCzDUUUU X-CM-SenderInfo: xfkh0wx2klxt3r6k3tpzhluzxrxghudrp/ Content-Type: text/plain; charset="utf-8" From: Zhihao Cheng The dax_iomap_rw() does two things in each iteration: map written blocks and copy user data to blocks. If the process is killed by user(See signal handling in dax_iomap_iter()), the copied data will be returned and added on inode size, which means that the length of written extents may exceed the inode size, then fsck will fail. An example is given as: dd if=3D/dev/urandom of=3Dfile bs=3D4M count=3D1 dax_iomap_rw iomap_iter // round 1 ext4_iomap_begin ext4_iomap_alloc // allocate 0~2M extents(written flag) dax_iomap_iter // copy 2M data iomap_iter // round 2 iomap_iter_advance iter->pos +=3D iter->processed // iter->pos =3D 2M ext4_iomap_begin ext4_iomap_alloc // allocate 2~4M extents(written flag) dax_iomap_iter fatal_signal_pending done =3D iter->pos - iocb->ki_pos // done =3D 2M ext4_handle_inode_extension ext4_update_inode_size // inode size =3D 2M fsck reports: Inode 13, i_size is 2097152, should be 4194304. Fix? Fix the problem by truncating extents if the written length is smaller than expected. Fixes: 776722e85d3b ("ext4: DAX iomap write support") CC: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D219136 Signed-off-by: Zhihao Cheng Reviewed-by: Jan Kara --- fs/ext4/file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index c89e434db6b7..be061bb64067 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -334,10 +334,10 @@ static ssize_t ext4_handle_inode_extension(struct ino= de *inode, loff_t offset, * Clean up the inode after DIO or DAX extending write has completed and t= he * inode size has been updated using ext4_handle_inode_extension(). */ -static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t coun= t) +static void ext4_inode_extension_cleanup(struct inode *inode, bool need_tr= unc) { lockdep_assert_held_write(&inode->i_rwsem); - if (count < 0) { + if (need_trunc) { ext4_truncate_failed_write(inode); /* * If the truncate operation failed early, then the inode may @@ -586,7 +586,7 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, = struct iov_iter *from) * writeback of delalloc blocks. */ WARN_ON_ONCE(ret =3D=3D -EIOCBQUEUED); - ext4_inode_extension_cleanup(inode, ret); + ext4_inode_extension_cleanup(inode, ret < 0); } =20 out: @@ -670,7 +670,7 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter= *from) =20 if (extend) { ret =3D ext4_handle_inode_extension(inode, offset, ret); - ext4_inode_extension_cleanup(inode, ret); + ext4_inode_extension_cleanup(inode, ret < (ssize_t)count); } out: inode_unlock(inode); --=20 2.39.2