All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Zhihao Cheng <chengzhihao1@huawei.com>
Cc: Jan Kara <jack@suse.cz>,
	tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.com,
	tudor.ambarus@linaro.org, linux-ext4@vger.kernel.org,
	linux-kernel@vger.kernel.org, yi.zhang@huawei.com
Subject: Re: [PATCH] ext4: Fix i_disksize exceeding i_size problem in paritally written case
Date: Mon, 20 Mar 2023 17:24:46 +0100	[thread overview]
Message-ID: <20230320162446.vkqsxxcsmv4cacwa@quack3> (raw)
In-Reply-To: <48deeadf-05cd-3535-a589-907cfa252799@huawei.com>

On Mon 20-03-23 20:49:07, Zhihao Cheng wrote:
> [...]
> 
> > > BTW, I want send another patch as follows:
> > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> > > index bf0b7dea4900..570a687ae847 100644
> > > --- a/fs/ext4/inode.c
> > > +++ b/fs/ext4/inode.c
> > > @@ -3149,7 +3149,7 @@ static int ext4_da_write_end(struct file *file,
> > >                  return ext4_write_inline_data_end(inode, pos, len, copied,
> > > page);
> > > 
> > >          start = pos & (PAGE_SIZE - 1);
> > > -       end = start + copied - 1;
> > > +       end = start + (copied ? copied - 1 : copied);
> > > 
> > >          /*
> > >           * Since we are holding inode lock, we are sure i_disksize <=
> > > @@ -3167,7 +3167,7 @@ static int ext4_da_write_end(struct file *file,
> > >           * ext4_da_write_inline_data_end().
> > >           */
> > >          new_i_size = pos + copied;
> > > -       if (copied && new_i_size > inode->i_size &&
> > > +       if (new_i_size > inode->i_size &&
> > >              ext4_da_should_update_i_disksize(page, end))
> > >                  ext4_update_i_disksize(inode, new_i_size);
> > > 
> > > This modification handle unconsistent i_size and i_disksize imported by
> > > ea51d132dbf9 ("ext4: avoid hangs in ext4_da_should_update_i_disksize()").
> > > 
> > > Paritially written may display a fake inode size for user, for example:
> > > 
> > > 
> > > 
> > > i_disksize=1
> > > 
> > > generic_perform_write
> > > 
> > >   copied = iov_iter_copy_from_user_atomic(len) // copied = 0
> > > 
> > >   ext4_da_write_end // skip updating i_disksize
> > > 
> > >   generic_write_end
> > > 
> > >    if (pos + copied > inode->i_size) {  // 10 + 0 > 1, true
> > > 
> > >     i_size_write(inode, pos + copied);  // i_size = 10
> > > 
> > >    }
> > > 
> > > 
> > > 
> > >     0 1      10                4096
> > > 
> > >     |_|_______|_________..._____|
> > > 
> > >       |       |
> > > 
> > >      i_size  pos
> > > 
> > > 
> > > 
> > > Now, user see the i_size is 10 (i_disksize is still 1). After inode
> > > 
> > > destroyed, user will get the i_size is 1 read from disk.
> > 
> > OK, but shouldn't we rather change generic_write_end() to not increase
> > i_size if no write happened? Because that is what seems somewhat
> > problematic...
> > 
> > 								Honza
> > 
> 
> After looking through some code, I find some other places have similar
> problem:
> 1. In ext4_write_end(), i_size is updated by ext4 not generic_write_end().
> 2. The iommap framework, i_size is updated even copied is zero.
> 3. ubifs_write_end, i_size is updated even copied is zero.
> 
> It seems that fixing all places is not an easy work.

Well, yeah, probably not trivial but still desirable ;). Will you look into
that?

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

  reply	other threads:[~2023-03-20 16:32 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-17  1:35 [PATCH] ext4: Fix i_disksize exceeding i_size problem in paritally written case Zhihao Cheng
2023-03-17 12:45 ` Jan Kara
2023-03-18  7:03   ` Zhihao Cheng
2023-03-18  8:51     ` Zhihao Cheng
2023-03-20 11:20       ` Jan Kara
2023-03-20 12:49         ` Zhihao Cheng
2023-03-20 16:24           ` Jan Kara [this message]
2023-03-21  1:29             ` Zhihao Cheng

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=20230320162446.vkqsxxcsmv4cacwa@quack3 \
    --to=jack@suse.cz \
    --cc=adilger.kernel@dilger.ca \
    --cc=chengzhihao1@huawei.com \
    --cc=jack@suse.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tudor.ambarus@linaro.org \
    --cc=tytso@mit.edu \
    --cc=yi.zhang@huawei.com \
    /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.