From mboxrd@z Thu Jan 1 00:00:00 1970 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 lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1EF53C87FCF for ; Tue, 5 Aug 2025 02:43:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: Reply-To:From:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Subject:In-Reply-To:MIME-Version:References: Message-ID:To:Date:Sender:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=lyZ65itaDXyTjWILR0rMvIgo6kOThxbFK8lQAPSDrNg=; b=Sa1SGsOLu+/nqpbh2411KCgAyA iMkuq01UjLYTxhZ7Maxm9ibbqfx2/kpJJY9CRGVtpiuwMTV6WoyW6mk0VmJU19nBcyCl4vaAw84bL NgmEG0nJVnraSvLhmsydpZU8nupS9gBMyce3jxm/62KKUNgHh5faxC0i8rtFT1IygppA=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1uj7e4-0001jq-UU; Tue, 05 Aug 2025 02:43:21 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1uj7dI-0001ga-PC for linux-f2fs-devel@lists.sourceforge.net; Tue, 05 Aug 2025 02:42:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=In-Reply-To:Content-Type:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=vWTQuOru/wf251Gtkk8KRzKDxqUzOnMXVEVrDJ+6hnY=; b=g07Ror2mPnZmHbf1+cmoBovu6j W9qTSpSbHprC1jl4Cs7J+PuBUyQgIWbyVyOmoCHjeSUNZ402ZKiP5Zvc7DSU1x1WN28QTtL6Zr/Hv SmqGDUVzBkr/UHaq8MOXFgZdLiarWkcEPy4aPwxOay8bC78JyFPoZT5YwtJCzHt6g0bw=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To :From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=vWTQuOru/wf251Gtkk8KRzKDxqUzOnMXVEVrDJ+6hnY=; b=mlulVj0CX2GZTEvmyRZIE5YP6q clWULn6g+fI/Dtk6FkiAuUoxh94dI9PA5Fnz1WOTyOtujg2uwAChjJ10iyF0A5BOYAIeauHN5JkJN IHiRW9QlxkMkdnFMXoMhqnBYPBS0HiiNL3H+OchZhQeC8O9v0hka2/StDDDW1KjK9EYo=; Received: from sea.source.kernel.org ([172.234.252.31]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1uj7dJ-0008HN-1A for linux-f2fs-devel@lists.sourceforge.net; Tue, 05 Aug 2025 02:42:33 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 947B7451C2; Tue, 5 Aug 2025 02:42:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 47F7BC4CEE7; Tue, 5 Aug 2025 02:42:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754361742; bh=8PINAAZCgLYFEM6lvYFZR7CfiG8y3mThZSagJ96DhAY=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=YyDnPgujcYEWcaB/UDTK1Q9+1dNXijlb32UB8iRCP3CYeyDCyald2J16XFv12J/rj A6i0ZRYwqPynl8d8A54k+fW3OSoa5lJqjZ4opDqmxXIgdMm97Dp62+/xkvK2Ih8mpk nIN66psXoMplVk6RoeBtrLkyI1EohgBRjumLou1bUSWRnIBVQ7L3+CPhEQFjKRgR1P oOJ6G+Ww8b8G6OkJEIDmmdrrIjQUqoGnPr6hjlAlanl8VXOXrdSzKyK1YmrMNAtBGO VM/W7DF5l5bCo/x+1KxU/Y9OmiFoRgceMJ0PyKJtN3GoqELDoxt0rtTmePKTz/FfAQ Jn8dZvcn3fAOw== Date: Tue, 5 Aug 2025 02:42:20 +0000 To: Chao Yu Message-ID: References: <20250804014340.2537172-1-chao@kernel.org> <20250804014340.2537172-3-chao@kernel.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20250804014340.2537172-3-chao@kernel.org> X-Headers-End: 1uj7dJ-0008HN-1A Subject: Re: [f2fs-dev] [PATCH v2 3/3] f2fs: fix to zero data after EOF for compressed file correctly X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Jaegeuk Kim via Linux-f2fs-devel Reply-To: Jaegeuk Kim Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net Chao, it seems you made a clean up before this? Can you post it first? On 08/04, Chao Yu wrote: > generic/091 may fail, then it bisects to the bad commit ba8dac350faf > ("f2fs: fix to zero post-eof page"). > > What will cause generic/091 to fail is something like below Testcase #1: > 1. write 16k as compressed blocks > 2. truncate to 12k > 3. truncate to 20k > 4. verify data in range of [12k, 16k], however data is not zero as > expected > > Script of Testcase #1 > mkfs.f2fs -f -O extra_attr,compression /dev/vdb > mount -t f2fs -o compress_extension=* /dev/vdb /mnt/f2fs > dd if=/dev/zero of=/mnt/f2fs/file bs=12k count=1 > dd if=/dev/random of=/mnt/f2fs/file bs=4k count=1 seek=3 conv=notrunc > sync > truncate -s $((12*1024)) /mnt/f2fs/file > truncate -s $((20*1024)) /mnt/f2fs/file > dd if=/mnt/f2fs/file of=/mnt/f2fs/data bs=4k count=1 skip=3 > od /mnt/f2fs/data > umount /mnt/f2fs > > Analisys: > in step 2), we will redirty all data pages from #0 to #3 in compressed > cluster, and zero page #3, > in step 3), f2fs_setattr() will call f2fs_zero_post_eof_page() to drop > all page cache post eof, includeing dirtied page #3, > in step 4) when we read data from page #3, it will decompressed cluster > and extra random data to page #3, finally, we hit the non-zeroed data > post eof. > > However, the commit ba8dac350faf ("f2fs: fix to zero post-eof page") just > let the issue be reproduced easily, w/o the commit, it can reproduce this > bug w/ below Testcase #2: > 1. write 16k as compressed blocks > 2. truncate to 8k > 3. truncate to 12k > 4. truncate to 20k > 5. verify data in range of [12k, 16k], however data is not zero as > expected > > Script of Testcase #2 > mkfs.f2fs -f -O extra_attr,compression /dev/vdb > mount -t f2fs -o compress_extension=* /dev/vdb /mnt/f2fs > dd if=/dev/zero of=/mnt/f2fs/file bs=12k count=1 > dd if=/dev/random of=/mnt/f2fs/file bs=4k count=1 seek=3 conv=notrunc > sync > truncate -s $((8*1024)) /mnt/f2fs/file > truncate -s $((12*1024)) /mnt/f2fs/file > truncate -s $((20*1024)) /mnt/f2fs/file > echo 3 > /proc/sys/vm/drop_caches > dd if=/mnt/f2fs/file of=/mnt/f2fs/data bs=4k count=1 skip=3 > od /mnt/f2fs/data > umount /mnt/f2fs > > Anlysis: > in step 2), we will redirty all data pages from #0 to #3 in compressed > cluster, and zero page #2 and #3, > in step 3), we will truncate page #3 in page cache, > in step 4), expand file size, > in step 5), hit random data post eof w/ the same reason in Testcase #1. > > Root Cause: > In f2fs_truncate_partial_cluster(), after we truncate partial data block > on compressed cluster, all pages in cluster including the one post eof > will be dirtied, after another tuncation, dirty page post eof will be > dropped, however on-disk compressed cluster is still valid, it includes > invalid data post eof, result in exposing previous data post eof while > reading. > > Fix: > In f2fs_truncate_partial_cluster(), let change as below to fix: > - call filemap_write_and_wait_range() to flush dirty page > - call truncate_pagecache() to drop pages or zero partial page post eof > - call f2fs_do_truncate_blocks() to truncate non-compress cluster to > last vali block > > Fixes: 3265d3db1f16 ("f2fs: support partial truncation on compressed inode") > Reported-by: Jan Prusakowski > Signed-off-by: Chao Yu > --- > v2: > - should dirty & flush all pages in cluster and truncate blocks post eof > later > fs/f2fs/compress.c | 20 ++++++++++++++------ > 1 file changed, 14 insertions(+), 6 deletions(-) > > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c > index e37a7ed801e5..6ad8d3bc6df7 100644 > --- a/fs/f2fs/compress.c > +++ b/fs/f2fs/compress.c > @@ -1245,17 +1245,25 @@ int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock) > for (i = (1 << log_cluster_size) - 1; i >= 0; i--) { > struct folio *folio = page_folio(rpages[i]); > loff_t start = (loff_t)folio->index << PAGE_SHIFT; > + loff_t offset = from > start ? from - start : 0; > > - if (from > start) { > - folio_zero_segment(folio, from - start, > - folio_size(folio)); > + folio_zero_segment(folio, offset, folio_size(folio)); > + > + if (from >= start) > break; > - } > - folio_zero_segment(folio, 0, folio_size(folio)); > } > > f2fs_compress_write_end(inode, fsdata, start_idx, true); > - return 0; > + > + err = filemap_write_and_wait_range(inode->i_mapping, > + round_down(from, 1 << log_cluster_size << PAGE_SHIFT), > + LLONG_MAX); > + if (err) > + return err; > + > + truncate_pagecache(inode, from); > + > + return f2fs_do_truncate_blocks(inode, round_up(from, PAGE_SIZE), lock); > } > > static int f2fs_write_compressed_pages(struct compress_ctx *cc, > -- > 2.49.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E7315A927 for ; Tue, 5 Aug 2025 02:42:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754361743; cv=none; b=bD4Gr5aMwKI4LXYfX1M6WQnaWTvk8TyFua6j9SNDhLbs32oAm09ONvl16Tjmh7T3tw+2Cf3HhdBhqBjCzSn3gHiGGjJslJOFRfU0X8+4e1r7LpmnmWVMNhnX/+HQLMTv2pwq9B8WvEN0oLUhsIAR2HQqhj9bo35r+p6aCAAkqMY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754361743; c=relaxed/simple; bh=8PINAAZCgLYFEM6lvYFZR7CfiG8y3mThZSagJ96DhAY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=f3622Pvtkl3Cl+hdqrKTqsA92Je5Z8d4px3MUg7Fe8GdUNdodtf//JsWXsdVFBypEnCTbJ2mLcvw0jxsWgvt973yzvFkLUss7UyzB3pXIJ/VfivNFgwM66YmLa7kr81HZ9XdLYEk7uOb7aw/bKgT49dwC/cU0UFraeIeXFdbALA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YyDnPguj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YyDnPguj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 47F7BC4CEE7; Tue, 5 Aug 2025 02:42:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754361742; bh=8PINAAZCgLYFEM6lvYFZR7CfiG8y3mThZSagJ96DhAY=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=YyDnPgujcYEWcaB/UDTK1Q9+1dNXijlb32UB8iRCP3CYeyDCyald2J16XFv12J/rj A6i0ZRYwqPynl8d8A54k+fW3OSoa5lJqjZ4opDqmxXIgdMm97Dp62+/xkvK2Ih8mpk nIN66psXoMplVk6RoeBtrLkyI1EohgBRjumLou1bUSWRnIBVQ7L3+CPhEQFjKRgR1P oOJ6G+Ww8b8G6OkJEIDmmdrrIjQUqoGnPr6hjlAlanl8VXOXrdSzKyK1YmrMNAtBGO VM/W7DF5l5bCo/x+1KxU/Y9OmiFoRgceMJ0PyKJtN3GoqELDoxt0rtTmePKTz/FfAQ Jn8dZvcn3fAOw== Date: Tue, 5 Aug 2025 02:42:20 +0000 From: Jaegeuk Kim To: Chao Yu Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, Jan Prusakowski Subject: Re: [PATCH v2 3/3] f2fs: fix to zero data after EOF for compressed file correctly Message-ID: References: <20250804014340.2537172-1-chao@kernel.org> <20250804014340.2537172-3-chao@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20250804014340.2537172-3-chao@kernel.org> Chao, it seems you made a clean up before this? Can you post it first? On 08/04, Chao Yu wrote: > generic/091 may fail, then it bisects to the bad commit ba8dac350faf > ("f2fs: fix to zero post-eof page"). > > What will cause generic/091 to fail is something like below Testcase #1: > 1. write 16k as compressed blocks > 2. truncate to 12k > 3. truncate to 20k > 4. verify data in range of [12k, 16k], however data is not zero as > expected > > Script of Testcase #1 > mkfs.f2fs -f -O extra_attr,compression /dev/vdb > mount -t f2fs -o compress_extension=* /dev/vdb /mnt/f2fs > dd if=/dev/zero of=/mnt/f2fs/file bs=12k count=1 > dd if=/dev/random of=/mnt/f2fs/file bs=4k count=1 seek=3 conv=notrunc > sync > truncate -s $((12*1024)) /mnt/f2fs/file > truncate -s $((20*1024)) /mnt/f2fs/file > dd if=/mnt/f2fs/file of=/mnt/f2fs/data bs=4k count=1 skip=3 > od /mnt/f2fs/data > umount /mnt/f2fs > > Analisys: > in step 2), we will redirty all data pages from #0 to #3 in compressed > cluster, and zero page #3, > in step 3), f2fs_setattr() will call f2fs_zero_post_eof_page() to drop > all page cache post eof, includeing dirtied page #3, > in step 4) when we read data from page #3, it will decompressed cluster > and extra random data to page #3, finally, we hit the non-zeroed data > post eof. > > However, the commit ba8dac350faf ("f2fs: fix to zero post-eof page") just > let the issue be reproduced easily, w/o the commit, it can reproduce this > bug w/ below Testcase #2: > 1. write 16k as compressed blocks > 2. truncate to 8k > 3. truncate to 12k > 4. truncate to 20k > 5. verify data in range of [12k, 16k], however data is not zero as > expected > > Script of Testcase #2 > mkfs.f2fs -f -O extra_attr,compression /dev/vdb > mount -t f2fs -o compress_extension=* /dev/vdb /mnt/f2fs > dd if=/dev/zero of=/mnt/f2fs/file bs=12k count=1 > dd if=/dev/random of=/mnt/f2fs/file bs=4k count=1 seek=3 conv=notrunc > sync > truncate -s $((8*1024)) /mnt/f2fs/file > truncate -s $((12*1024)) /mnt/f2fs/file > truncate -s $((20*1024)) /mnt/f2fs/file > echo 3 > /proc/sys/vm/drop_caches > dd if=/mnt/f2fs/file of=/mnt/f2fs/data bs=4k count=1 skip=3 > od /mnt/f2fs/data > umount /mnt/f2fs > > Anlysis: > in step 2), we will redirty all data pages from #0 to #3 in compressed > cluster, and zero page #2 and #3, > in step 3), we will truncate page #3 in page cache, > in step 4), expand file size, > in step 5), hit random data post eof w/ the same reason in Testcase #1. > > Root Cause: > In f2fs_truncate_partial_cluster(), after we truncate partial data block > on compressed cluster, all pages in cluster including the one post eof > will be dirtied, after another tuncation, dirty page post eof will be > dropped, however on-disk compressed cluster is still valid, it includes > invalid data post eof, result in exposing previous data post eof while > reading. > > Fix: > In f2fs_truncate_partial_cluster(), let change as below to fix: > - call filemap_write_and_wait_range() to flush dirty page > - call truncate_pagecache() to drop pages or zero partial page post eof > - call f2fs_do_truncate_blocks() to truncate non-compress cluster to > last vali block > > Fixes: 3265d3db1f16 ("f2fs: support partial truncation on compressed inode") > Reported-by: Jan Prusakowski > Signed-off-by: Chao Yu > --- > v2: > - should dirty & flush all pages in cluster and truncate blocks post eof > later > fs/f2fs/compress.c | 20 ++++++++++++++------ > 1 file changed, 14 insertions(+), 6 deletions(-) > > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c > index e37a7ed801e5..6ad8d3bc6df7 100644 > --- a/fs/f2fs/compress.c > +++ b/fs/f2fs/compress.c > @@ -1245,17 +1245,25 @@ int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock) > for (i = (1 << log_cluster_size) - 1; i >= 0; i--) { > struct folio *folio = page_folio(rpages[i]); > loff_t start = (loff_t)folio->index << PAGE_SHIFT; > + loff_t offset = from > start ? from - start : 0; > > - if (from > start) { > - folio_zero_segment(folio, from - start, > - folio_size(folio)); > + folio_zero_segment(folio, offset, folio_size(folio)); > + > + if (from >= start) > break; > - } > - folio_zero_segment(folio, 0, folio_size(folio)); > } > > f2fs_compress_write_end(inode, fsdata, start_idx, true); > - return 0; > + > + err = filemap_write_and_wait_range(inode->i_mapping, > + round_down(from, 1 << log_cluster_size << PAGE_SHIFT), > + LLONG_MAX); > + if (err) > + return err; > + > + truncate_pagecache(inode, from); > + > + return f2fs_do_truncate_blocks(inode, round_up(from, PAGE_SIZE), lock); > } > > static int f2fs_write_compressed_pages(struct compress_ctx *cc, > -- > 2.49.0