From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Christoph Hellwig <hch@lst.de>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 08/11] xfs: merge COW handling into xfs_file_iomap_begin_delay
Date: Wed, 19 Dec 2018 12:20:45 -0800 [thread overview]
Message-ID: <20181219202045.GZ27208@magnolia> (raw)
In-Reply-To: <20181219193843.GE28624@lst.de>
On Wed, Dec 19, 2018 at 08:38:43PM +0100, Christoph Hellwig wrote:
> On Tue, Dec 18, 2018 at 03:36:41PM -0800, Darrick J. Wong wrote:
> > On Mon, Dec 03, 2018 at 05:25:00PM -0500, Christoph Hellwig wrote:
> > > Besides simplifying the code a bit this allows to actually implement
> > > the behavior of using COW preallocation for non-COW data mentioned
> > > in the current comments.
> > >
> > > Note that this breaks the current version of xfs/420, but that is
> > > because the test is broken. A separate fix will be sent for it.
> >
> > (Still waiting for this...)
>
> It was sent quite a while ago, but I need to resend it..
>
> >
> > > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > > ---
> > > fs/xfs/xfs_iomap.c | 132 ++++++++++++++++++++++++++++++-------------
> > > fs/xfs/xfs_reflink.c | 67 ----------------------
> > > fs/xfs/xfs_trace.h | 1 -
> > > 3 files changed, 93 insertions(+), 107 deletions(-)
> > >
> > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> > > index d851abac16a9..d19f99e5476a 100644
> > > --- a/fs/xfs/xfs_iomap.c
> > > +++ b/fs/xfs/xfs_iomap.c
> > > @@ -534,15 +534,16 @@ xfs_file_iomap_begin_delay(
> > > {
> > > struct xfs_inode *ip = XFS_I(inode);
> > > struct xfs_mount *mp = ip->i_mount;
> > > - struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
> > > xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
> > > xfs_fileoff_t maxbytes_fsb =
> > > XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
> > > xfs_fileoff_t end_fsb;
> > > - int error = 0, eof = 0;
> > > - struct xfs_bmbt_irec got;
> > > - struct xfs_iext_cursor icur;
> > > + struct xfs_bmbt_irec imap, cmap;
> > > + struct xfs_iext_cursor icur, ccur;
> > > xfs_fsblock_t prealloc_blocks = 0;
> > > + bool eof = false, cow_eof = false, shared;
> > > + int whichfork = XFS_DATA_FORK;
> > > + int error = 0;
> > >
> > > ASSERT(!XFS_IS_REALTIME_INODE(ip));
> > > ASSERT(!xfs_get_extsz_hint(ip));
> > > @@ -560,7 +561,7 @@ xfs_file_iomap_begin_delay(
> > >
> > > XFS_STATS_INC(mp, xs_blk_mapw);
> > >
> > > - if (!(ifp->if_flags & XFS_IFEXTENTS)) {
> > > + if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) {
> > > error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
> > > if (error)
> > > goto out_unlock;
> > > @@ -568,51 +569,92 @@ xfs_file_iomap_begin_delay(
> > >
> > > end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb);
> > >
> > > - eof = !xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got);
> > > + /*
> > > + * Search the data fork fork first to look up our source mapping. We
> > > + * always need the data fork map, as we have to return it to the
> > > + * iomap code so that the higher level write code can read data in to
> > > + * perform read-modify-write cycles for unaligned writes.
> > > + */
> > > + eof = !xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &icur, &imap);
> > > if (eof)
> > > - got.br_startoff = end_fsb; /* fake hole until the end */
> > > + imap.br_startoff = end_fsb; /* fake hole until the end */
> > >
> > > - if (got.br_startoff <= offset_fsb) {
> > > + /* We never need to allocate blocks for zeroing a hole. */
> > > + if ((flags & IOMAP_ZERO) && imap.br_startoff > offset_fsb) {
> > > + xfs_hole_to_iomap(ip, iomap, offset_fsb, imap.br_startoff);
> > > + goto out_unlock;
> > > + }
> > > +
> > > + /*
> > > + * Search the COW fork extent list even if we did not find a data fork
> > > + * extent. This serves two purposes: first this implements the
> > > + * speculative preallocation using cowextisze, so that we also unshare
> >
> > "cowextsize"
> >
> > > + * block adjacent to shared blocks instead of just the shared blocks
> > > + * themselves. Second the lookup in the extent list is generally faster
> > > + * than going out to the shared extent tree.
> > > + */
> > > + if (xfs_is_reflink_inode(ip)) {
> > > + cow_eof = !xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb,
> > > + &ccur, &cmap);
> > > + if (!cow_eof && cmap.br_startoff <= offset_fsb) {
> > > + trace_xfs_reflink_cow_found(ip, &cmap);
> > > + whichfork = XFS_COW_FORK;
> > > + goto done;
> > > + }
> > > + }
> > > +
> > > + if (imap.br_startoff <= offset_fsb) {
> > > /*
> > > * For reflink files we may need a delalloc reservation when
> > > * overwriting shared extents. This includes zeroing of
> > > * existing extents that contain data.
> > > */
> > > - if (xfs_is_reflink_inode(ip) &&
> > > - ((flags & IOMAP_WRITE) ||
> > > - got.br_state != XFS_EXT_UNWRITTEN)) {
> > > - xfs_trim_extent(&got, offset_fsb, end_fsb - offset_fsb);
> > > - error = xfs_reflink_reserve_cow(ip, &got);
> > > - if (error)
> > > - goto out_unlock;
> > > + if (!xfs_is_reflink_inode(ip) ||
> > > + ((flags & IOMAP_ZERO) && imap.br_state != XFS_EXT_NORM)) {
> > > + trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK,
> > > + &imap);
> > > + goto done;
> > > }
> > >
> > > - trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK, &got);
> > > - goto done;
> > > - }
> > > + xfs_trim_extent(&imap, offset_fsb, end_fsb - offset_fsb);
> > >
> > > - if (flags & IOMAP_ZERO) {
> > > - xfs_hole_to_iomap(ip, iomap, offset_fsb, got.br_startoff);
> > > - goto out_unlock;
> > > + /* Trim the mapping to the nearest shared extent boundary. */
> > > + error = xfs_reflink_trim_around_shared(ip, &imap, &shared);
> > > + if (error)
> > > + goto out_unlock;
> > > +
> > > + /* Not shared? Just report the (potentially capped) extent. */
> > > + if (!shared) {
> > > + trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK,
> > > + &imap);
> > > + goto done;
> > > + }
> > > +
> > > + /*
> > > + * Fork all the shared blocks from our write offset until the
> > > + * end of the extent.
> > > + */
> > > + whichfork = XFS_COW_FORK;
> > > + end_fsb = imap.br_startoff + imap.br_blockcount;
> > > + } else {
> > > + /*
> > > + * We cap the maximum length we map here to MAX_WRITEBACK_PAGES
> > > + * pages to keep the chunks of work done where somewhat
> > > + * symmetric with the work writeback does. This is a completely
> > > + * arbitrary number pulled out of thin air.
> > > + *
> > > + * Note that the values needs to be less than 32-bits wide until
> > > + * the lower level functions are updated.
> > > + */
> > > + count = min_t(loff_t, count, 1024 * PAGE_SIZE);
> > > + end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb);
> > > }
> > >
> > > error = xfs_qm_dqattach_locked(ip, false);
> > > if (error)
> > > goto out_unlock;
> > >
> > > - /*
> > > - * We cap the maximum length we map here to MAX_WRITEBACK_PAGES pages
> > > - * to keep the chunks of work done where somewhat symmetric with the
> > > - * work writeback does. This is a completely arbitrary number pulled
> > > - * out of thin air as a best guess for initial testing.
> > > - *
> > > - * Note that the values needs to be less than 32-bits wide until
> > > - * the lower level functions are updated.
> > > - */
> > > - count = min_t(loff_t, count, 1024 * PAGE_SIZE);
> > > - end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb);
> > > -
> > > - if (eof) {
> > > + if (eof && whichfork == XFS_DATA_FORK) {
> > > prealloc_blocks = xfs_iomap_prealloc_size(ip, offset, count,
> > > &icur);
> > > if (prealloc_blocks) {
> > > @@ -635,9 +677,11 @@ xfs_file_iomap_begin_delay(
> > > }
> > >
> > > retry:
> > > - error = xfs_bmapi_reserve_delalloc(ip, XFS_DATA_FORK, offset_fsb,
> > > - end_fsb - offset_fsb, prealloc_blocks, &got, &icur,
> > > - eof);
> > > + error = xfs_bmapi_reserve_delalloc(ip, whichfork, offset_fsb,
> > > + end_fsb - offset_fsb, prealloc_blocks,
> > > + whichfork == XFS_DATA_FORK ? &imap : &cmap,
> > > + whichfork == XFS_DATA_FORK ? &icur : &ccur,
> > > + whichfork == XFS_DATA_FORK ? eof : cow_eof);
> > > switch (error) {
> > > case 0:
> > > break;
> > > @@ -659,9 +703,19 @@ xfs_file_iomap_begin_delay(
> > > * them out if the write happens to fail.
> > > */
> > > iomap->flags |= IOMAP_F_NEW;
> > > - trace_xfs_iomap_alloc(ip, offset, count, XFS_DATA_FORK, &got);
> > > + trace_xfs_iomap_alloc(ip, offset, count, whichfork, &imap);
> >
> > I'm confused by this, if whichfork == COW then won't ftrace report
> > results from the wrong fork?
>
> The question is what the "right" fork to trace is as both matter here.
> At least we now clearly tell you which fork the trace belongs too.
True. But I think it's misleading to have a tracepoint report say "cow"
when the extent data it records is actually from the data fork, and
particularly because we sometimes pass cmap back to the caller when
whichfork == COW.
If I were tracing through here I'd probably want to know what we found
from both forks at that particular point in time so that I could
continue following the logic.
--D
next prev parent reply other threads:[~2018-12-19 20:20 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-03 22:24 COW improvements and always_cow support V3 Christoph Hellwig
2018-12-03 22:24 ` [PATCH 01/11] xfs: remove xfs_trim_extent_eof Christoph Hellwig
2018-12-18 21:45 ` Darrick J. Wong
2018-12-03 22:24 ` [PATCH 02/11] xfs: remove the io_type field from the writeback context and ioend Christoph Hellwig
2018-12-18 21:45 ` Darrick J. Wong
2018-12-03 22:24 ` [PATCH 03/11] xfs: remove the s_maxbytes checks in xfs_map_blocks Christoph Hellwig
2018-12-18 22:31 ` Darrick J. Wong
2018-12-03 22:24 ` [PATCH 04/11] xfs: rework the truncate race handling in the writeback path Christoph Hellwig
2018-12-18 23:03 ` Darrick J. Wong
2018-12-19 19:32 ` Christoph Hellwig
2018-12-03 22:24 ` [PATCH 05/11] xfs: make xfs_bmbt_to_iomap more useful Christoph Hellwig
2018-12-18 21:46 ` Darrick J. Wong
2018-12-03 22:24 ` [PATCH 06/11] xfs: don't use delalloc extents for COW on files with extsize hints Christoph Hellwig
2018-12-18 21:44 ` Darrick J. Wong
2018-12-19 19:29 ` Christoph Hellwig
2018-12-19 19:32 ` Darrick J. Wong
2018-12-03 22:24 ` [PATCH 07/11] xfs: also truncate holes covered by COW blocks Christoph Hellwig
2018-12-18 23:39 ` Darrick J. Wong
2018-12-03 22:25 ` [PATCH 08/11] xfs: merge COW handling into xfs_file_iomap_begin_delay Christoph Hellwig
2018-12-18 23:36 ` Darrick J. Wong
2018-12-19 19:38 ` Christoph Hellwig
2018-12-19 20:20 ` Darrick J. Wong [this message]
2018-12-03 22:25 ` [PATCH 09/11] xfs: report IOMAP_F_SHARED from xfs_file_iomap_begin_delay Christoph Hellwig
2018-12-18 23:38 ` Darrick J. Wong
2018-12-19 19:39 ` Christoph Hellwig
2018-12-03 22:25 ` [PATCH 10/11] xfs: make COW fork unwritten extent conversions more robust Christoph Hellwig
2018-12-18 22:22 ` Darrick J. Wong
2018-12-19 19:30 ` Christoph Hellwig
2018-12-03 22:25 ` [PATCH 11/11] xfs: introduce an always_cow mode Christoph Hellwig
2018-12-18 23:24 ` Darrick J. Wong
2018-12-19 19:37 ` Christoph Hellwig
2018-12-19 22:43 ` Dave Chinner
2018-12-20 7:07 ` Christoph Hellwig
2018-12-20 21:03 ` Dave Chinner
2018-12-21 6:27 ` Christoph Hellwig
2018-12-06 1:05 ` COW improvements and always_cow support V3 Darrick J. Wong
2018-12-06 4:16 ` Christoph Hellwig
2018-12-06 16:32 ` Darrick J. Wong
2018-12-06 20:09 ` Christoph Hellwig
2018-12-17 17:59 ` Darrick J. Wong
2018-12-18 18:05 ` Christoph Hellwig
2018-12-19 0:44 ` Darrick J. Wong
2018-12-20 7:09 ` Christoph Hellwig
2018-12-20 22:09 ` Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2019-01-17 16:36 COW improvements and always_cow support V4 Christoph Hellwig
2019-01-17 16:36 ` [PATCH 08/11] xfs: merge COW handling into xfs_file_iomap_begin_delay Christoph Hellwig
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=20181219202045.GZ27208@magnolia \
--to=darrick.wong@oracle.com \
--cc=hch@lst.de \
--cc=linux-xfs@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).