All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: Brian Foster <bfoster@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, linux-afs@lists.infradead.org,
	linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-mm@kvack.org, Hugh Dickins <hughd@google.com>,
	linux-kernel@vger.kernel.org, fstests@vger.kernel.org
Subject: Re: [PATCH 1/5] truncate: Zero bytes after 'oldsize' if we're expanding the file
Date: Fri, 3 Feb 2023 15:07:05 +0000	[thread overview]
Message-ID: <Y90jGVTFxU/QLM5o@casper.infradead.org> (raw)
In-Reply-To: <Y90FYG+tNtBIl62S@bfoster>

On Fri, Feb 03, 2023 at 08:00:16AM -0500, Brian Foster wrote:
> On Thu, Feb 02, 2023 at 08:44:23PM +0000, Matthew Wilcox (Oracle) wrote:
> > POSIX requires that "If the file size is increased, the extended area
> > shall appear as if it were zero-filled".  It is possible to use mmap to
> > write past EOF and that data will become visible instead of zeroes.
> > This fixes the problem for the filesystems which simply call
> > truncate_setsize().  More complex filesystems will need their own
> > patches.
> > 
> > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> > ---
> >  mm/truncate.c | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/mm/truncate.c b/mm/truncate.c
> > index 7b4ea4c4a46b..cebfc5415e9a 100644
> > --- a/mm/truncate.c
> > +++ b/mm/truncate.c
> > @@ -763,9 +763,12 @@ void truncate_setsize(struct inode *inode, loff_t newsize)
> >  	loff_t oldsize = inode->i_size;
> >  
> >  	i_size_write(inode, newsize);
> > -	if (newsize > oldsize)
> > +	if (newsize > oldsize) {
> >  		pagecache_isize_extended(inode, oldsize, newsize);
> > -	truncate_pagecache(inode, newsize);
> > +		truncate_pagecache(inode, oldsize);
> > +	} else {
> > +		truncate_pagecache(inode, newsize);
> > +	}
> 
> I don't think this alone quite addresses the problem. Looking at ext4
> for example, if the eof page is dirty and writeback occurs between the
> i_size update (because writeback also zeroes the post-eof portion of the
> page) and the truncate_setsize() call, we end up with pagecache
> inconsistency because pagecache truncate doesn't dirty the page it
> zeroes.
> 
> So for example, with this series plus a nefariously placed
> filemap_flush() in ext4_setattr():
> 
> # xfs_io -fc "truncate 1" -c "mmap 0 1k" -c "mwrite 0 10" -c "truncate 5" -c "mread -v 0 5" /mnt/file
> 00000000:  58 00 00 00 00  X....
> # umount /mnt/; mount <dev> /mnt/
> # xfs_io -c "mmap 0 1k" -c "mread -v 0 5" /mnt/file 
> 00000000:  58 58 58 58 58  XXXXX

Hm, so switch the order of i_size_write() and truncate_pagecache()?
There could still be a store between old-EOF and new-EOF from another
thread, which would then be visible, but I don't think you could prove
that store should have been zeroed.  Not from the thread doing the
ftruncate() anyway -- I think the thread doing the store could prove
it, but that thread is relying on undefined behaviour anyway.


  reply	other threads:[~2023-02-03 15:07 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-02 20:44 [PATCH 0/5] Fix a minor POSIX conformance problem Matthew Wilcox (Oracle)
2023-02-02 20:44 ` [PATCH 1/5] truncate: Zero bytes after 'oldsize' if we're expanding the file Matthew Wilcox (Oracle)
2023-02-03 13:00   ` Brian Foster
2023-02-03 15:07     ` Matthew Wilcox [this message]
2023-02-02 20:44 ` [PATCH 2/5] ext4: " Matthew Wilcox (Oracle)
2023-02-02 20:44 ` [PATCH 3/5] tmpfs: " Matthew Wilcox (Oracle)
2023-02-02 20:44 ` [PATCH 4/5] afs: " Matthew Wilcox (Oracle)
2023-02-02 20:44 ` [PATCH 5/5] btrfs: " Matthew Wilcox (Oracle)
2023-02-02 20:44 ` [PATCH 6/5] generic: test ftruncate zeroes bytes after EOF Matthew Wilcox (Oracle)
2023-02-03 11:57   ` Johannes Thumshirn
2023-02-03 13:13     ` Matthew Wilcox
2023-02-03 16:35   ` Darrick J. Wong
2023-02-02 23:08 ` [PATCH 0/5] Fix a minor POSIX conformance problem Andreas Dilger
2023-02-03 13:21   ` Matthew Wilcox
2023-02-03 16:23     ` David Laight
2023-02-03 16:29       ` Matthew Wilcox
2023-02-27 13:49 ` [PATCH 4/5] afs: Zero bytes after 'oldsize' if we're expanding the file David Howells
2023-02-27 14:09   ` Matthew Wilcox
2023-02-27 14:20   ` David Howells
2023-02-27 14:49   ` David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y90jGVTFxU/QLM5o@casper.infradead.org \
    --to=willy@infradead.org \
    --cc=bfoster@redhat.com \
    --cc=fstests@vger.kernel.org \
    --cc=hughd@google.com \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.