From: Dominique Martinet <asmadeus@codewreck.org>
To: Hou Tao <houtao1@huawei.com>
Cc: v9fs-developer@lists.sourceforge.net, lucho@ionkov.net,
ericvh@gmail.com, linux-fsdevel@vger.kernel.org,
xingaopeng@huawei.com
Subject: Re: [PATCH v3 2/2] 9p: use i_lock to protect update of inode->i_blocks under 32-bit
Date: Thu, 24 Jan 2019 08:25:32 +0100 [thread overview]
Message-ID: <20190124072532.GA16424@nautica> (raw)
In-Reply-To: <20190124063514.8571-3-houtao1@huawei.com>
Hou Tao wrote on Thu, Jan 24, 2019:
> When v9fs_stat2inode() is invoked concurrently under 32-bit case
> and CONFIG_LBDAF is enabled, multiple updates of inode->i_blocks
> may corrupt the value of i_blocks because the assignment of 64-bit
> value under 32-bit host is not atomic.
>
> Fix it by using i_lock to protect update of inode->i_blocks. Also
> Skip the update when it's not requested.
>
> Suggested-by: Dominique Martinet <asmadeus@codewreck.org>
> Signed-off-by: Hou Tao <houtao1@huawei.com>
> ---
> fs/9p/v9fs_vfs.h | 10 ++++++++++
> fs/9p/vfs_inode.c | 7 ++++---
> fs/9p/vfs_inode_dotl.c | 16 +++++++++-------
> 3 files changed, 23 insertions(+), 10 deletions(-)
>
> diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
> index 3d371b9e461a..0bd4acfdb6af 100644
> --- a/fs/9p/v9fs_vfs.h
> +++ b/fs/9p/v9fs_vfs.h
> @@ -101,4 +101,14 @@ static inline void v9fs_i_size_write(struct inode *inode, loff_t i_size)
> if (sizeof(i_size) > sizeof(long))
> spin_unlock(&inode->i_lock);
> }
> +
> +static inline void v9fs_i_blocks_write(struct inode *inode, blkcnt_t i_blocks)
> +{
> + /* Avoid taking i_lock under 64-bits */
> + if (sizeof(i_blocks) > sizeof(long))
> + spin_lock(&inode->i_lock);
> + inode->i_blocks = i_blocks;
> + if (sizeof(i_blocks) > sizeof(long))
> + spin_unlock(&inode->i_lock);
> +}
> #endif
> diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
> index 72b779bc0942..f05ff3cfbfe7 100644
> --- a/fs/9p/vfs_inode.c
> +++ b/fs/9p/vfs_inode.c
> @@ -1218,10 +1218,11 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
> mode |= inode->i_mode & ~S_IALLUGO;
> inode->i_mode = mode;
>
> - if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE))
> + if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE)) {
> v9fs_i_size_write(inode, stat->length);
> - /* not real number of blocks, but 512 byte ones ... */
> - inode->i_blocks = (stat->length + 512 - 1) >> 9;
> + /* not real number of blocks, but 512 byte ones ... */
> + v9fs_i_blocks_write(inode, (stat->length + 512 - 1) >> 9);
hmm, part of me wants to abuse v9fs_i_size_write to also update i_blocks
as I think we'd usually want to keep both in sync.
In v9fs_file_write_iter we do not update i_blocks directly but
inode_add_bytes basically does the same thing... Speaking of which it's
assuming inode->i_bytes is set correctly initially; I _think_ we're
supposed to call inode_set_bytes() instead of writing i_blocks directly
in stat2inode?
Sorry, I'm not too familiar with this code and there doesn't seem to be
many users of inode_set_bytes so it's a bit puzzling to me.
I'm not using cache mode much but I have some very weird behaviour
currently if I mount something with cache=fscache :
- if I create a new file from 9p and stat on the same client, a size of
0-511 has block = 0 then it's just always off by 1
- if I create a file outside of 9p and stat it, for example starting
with 400 bytes, it starts with 8 blocks then the number of blocks
increase by 1 everytime 512 bytes are written regardless of initial
size.
Let's try to go back to some decent behaviour there first, and then
we can decide if it still make sense to separate v9fs_i_blocks_write and
v9fs_i_size_write or not.
--
Dominique
next prev parent reply other threads:[~2019-01-24 7:25 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-24 6:35 [PATCH v3 0/2] use i_lock to protect updates of i_blocks & Hou Tao
2019-01-24 6:35 ` [PATCH v3 1/2] 9p: use inode->i_lock to protect i_size_write() under 32-bit Hou Tao
2019-01-24 6:57 ` Dominique Martinet
2019-01-24 11:01 ` Hou Tao
2019-03-02 11:31 ` Hou Tao
2019-03-03 4:57 ` Dominique Martinet
2019-01-24 6:35 ` [PATCH v3 2/2] 9p: use i_lock to protect update of inode->i_blocks " Hou Tao
2019-01-24 7:25 ` Dominique Martinet [this message]
2019-01-24 14:03 ` Hou Tao
2019-01-24 14:45 ` Dominique Martinet
2019-01-24 14:53 ` Dominique Martinet
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=20190124072532.GA16424@nautica \
--to=asmadeus@codewreck.org \
--cc=ericvh@gmail.com \
--cc=houtao1@huawei.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=lucho@ionkov.net \
--cc=v9fs-developer@lists.sourceforge.net \
--cc=xingaopeng@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox