From: Eryu Guan <eguan@redhat.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: Brian Foster <bfoster@redhat.com>,
Eric Sandeen <sandeen@redhat.com>,
fstests <fstests@vger.kernel.org>,
Zheng Liu <wenqing.lz@taobao.com>,
linux-xfs@vger.kernel.org
Subject: Re: [PATCH] test race when checking i_size on direct i/o read
Date: Wed, 20 Sep 2017 19:05:04 +0800 [thread overview]
Message-ID: <20170920110504.GU8034@eguan.usersys.redhat.com> (raw)
In-Reply-To: <20170919143406.GA7437@infradead.org>
On Tue, Sep 19, 2017 at 07:34:06AM -0700, Christoph Hellwig wrote:
> On Tue, Sep 19, 2017 at 10:13:52AM -0400, Brian Foster wrote:
> > Can we pass a boolean or flag to xfs_iomap_write_unwritten() to have it
> > update the incore i_size after unwritten extent conversion? Then move
> > (or remove) the associated update from xfs_dio_write_end_io().
>
> I don't think we even need a flag - all three callers of
> xfs_iomap_write_unwritten want to update the file size.
I tried this approach, but seems there's some problem in the buffered
aio path, generic/112 (aio fsx) failed quickly. But I haven't digged
into the reason (maybe I screwed it up, not the method is wrong..).
Then I tried Brian's suggestion, pass a boolean to
xfs_iomap_write_unwritten() to tell if we want it to update in-core
isize after unwritten extent conversion, and skip the in-core isize
update in xfs_dio_write_end_io() accordingly. This approach seems to
work, it passed the test Eric posted here, and fstests 'aio' group
tests, a run of 'quick' group didn't find any new failure as well.
I attached the WIP patch (without proper comments) I was testing, if
this looks fine I can format a formal patch and do more testings.
Thanks,
Eryu
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 29172609f2a3..288da47e9ac5 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -343,7 +343,7 @@ xfs_end_io(
error = xfs_reflink_end_cow(ip, offset, size);
break;
case XFS_IO_UNWRITTEN:
- error = xfs_iomap_write_unwritten(ip, offset, size);
+ error = xfs_iomap_write_unwritten(ip, offset, size, false);
break;
default:
ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_append_trans);
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 350b6d43ba23..f3ad024573e7 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -435,6 +435,7 @@ xfs_dio_write_end_io(
struct xfs_inode *ip = XFS_I(inode);
loff_t offset = iocb->ki_pos;
bool update_size = false;
+ bool write_unwritten = (flags & IOMAP_DIO_UNWRITTEN);
int error = 0;
trace_xfs_end_io_direct_write(ip, offset, size);
@@ -458,7 +459,8 @@ xfs_dio_write_end_io(
*/
spin_lock(&ip->i_flags_lock);
if (offset + size > i_size_read(inode)) {
- i_size_write(inode, offset + size);
+ if (!write_unwritten)
+ i_size_write(inode, offset + size);
update_size = true;
}
spin_unlock(&ip->i_flags_lock);
@@ -469,8 +471,8 @@ xfs_dio_write_end_io(
return error;
}
- if (flags & IOMAP_DIO_UNWRITTEN)
- error = xfs_iomap_write_unwritten(ip, offset, size);
+ if (write_unwritten)
+ error = xfs_iomap_write_unwritten(ip, offset, size, update_size);
else if (update_size)
error = xfs_setfilesize(ip, offset, size);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index a1909bc064e9..0a088586371e 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -829,7 +829,8 @@ int
xfs_iomap_write_unwritten(
xfs_inode_t *ip,
xfs_off_t offset,
- xfs_off_t count)
+ xfs_off_t count,
+ bool update_size)
{
xfs_mount_t *mp = ip->i_mount;
xfs_fileoff_t offset_fsb;
@@ -840,6 +841,7 @@ xfs_iomap_write_unwritten(
xfs_trans_t *tp;
xfs_bmbt_irec_t imap;
struct xfs_defer_ops dfops;
+ struct inode *inode = VFS_I(ip);
xfs_fsize_t i_size;
uint resblks;
int error;
@@ -900,6 +902,13 @@ xfs_iomap_write_unwritten(
if (i_size > offset + count)
i_size = offset + count;
+ if (update_size) {
+ spin_lock(&ip->i_flags_lock);
+ if (i_size > i_size_read(inode))
+ i_size_write(inode, i_size);
+ spin_unlock(&ip->i_flags_lock);
+ }
+
i_size = xfs_new_eof(ip, i_size);
if (i_size) {
ip->i_d.di_size = i_size;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 00db3ecea084..ee535065c5d0 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -27,7 +27,7 @@ int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
struct xfs_bmbt_irec *, int);
int xfs_iomap_write_allocate(struct xfs_inode *, int, xfs_off_t,
struct xfs_bmbt_irec *);
-int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t);
+int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
struct xfs_bmbt_irec *);
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index 2f2dc3c09ad0..4246876df7b7 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -274,7 +274,7 @@ xfs_fs_commit_blocks(
(end - 1) >> PAGE_SHIFT);
WARN_ON_ONCE(error);
- error = xfs_iomap_write_unwritten(ip, start, length);
+ error = xfs_iomap_write_unwritten(ip, start, length, false);
if (error)
goto out_drop_iolock;
}
next prev parent reply other threads:[~2017-09-20 11:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-18 20:35 [PATCH] test race when checking i_size on direct i/o read Eric Sandeen
2017-08-28 10:35 ` Eryu Guan
2017-08-29 13:46 ` Nikolay Borisov
2017-09-19 7:36 ` Eryu Guan
2017-09-19 14:13 ` Brian Foster
2017-09-19 14:34 ` Christoph Hellwig
2017-09-19 14:58 ` Brian Foster
2017-09-20 11:05 ` Eryu Guan [this message]
2017-09-20 12:55 ` Brian Foster
2017-09-21 10:09 ` Eryu Guan
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=20170920110504.GU8034@eguan.usersys.redhat.com \
--to=eguan@redhat.com \
--cc=bfoster@redhat.com \
--cc=fstests@vger.kernel.org \
--cc=hch@infradead.org \
--cc=linux-xfs@vger.kernel.org \
--cc=sandeen@redhat.com \
--cc=wenqing.lz@taobao.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.