From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: chandanbabu@kernel.org, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 3/5] xfs: restrict when we try to align cow fork delalloc to cowextsz hints
Date: Thu, 13 Jun 2024 22:27:05 -0700 [thread overview]
Message-ID: <20240614052705.GC6147@frogsfrogsfrogs> (raw)
In-Reply-To: <20240614044155.GA9084@lst.de>
On Fri, Jun 14, 2024 at 06:41:55AM +0200, Christoph Hellwig wrote:
> On Thu, Jun 13, 2024 at 09:13:10PM -0700, Darrick J. Wong wrote:
> > > Looking at the caller below I don't think we need the use_cowextszhint
> > > flag here, we can just locally check for prealloc beeing non-0 in
> > > the branch below:
> >
> > That won't work, because xfs_buffered_write_iomap_begin only sets
> > @prealloc to nonzero if it thinks is an extending write. For the cow
> > fork, we create delalloc reservations that are aligned to the cowextsize
> > value for overwrites below eof.
>
> Yeah. For that we'd need to move the retry loop into
> xfs_bmapi_reserve_delalloc - which honestly feels like the more logical
> place for it anyway. As in the untested version below, also note
> my XXX comment about a comment being added:
>
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index c101cf266bc4db..58ff21cb84e0f5 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -4059,19 +4059,33 @@ xfs_bmapi_reserve_delalloc(
> uint64_t fdblocks;
> int error;
> xfs_fileoff_t aoff = off;
> + bool use_cowextszhint =
> + whichfork == XFS_COW_FORK && !prealloc;
>
> /*
> * Cap the alloc length. Keep track of prealloc so we know whether to
> * tag the inode before we return.
> */
> +retry:
> alen = XFS_FILBLKS_MIN(len + prealloc, XFS_MAX_BMBT_EXTLEN);
> if (!eof)
> alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
> if (prealloc && alen >= len)
> prealloc = alen - len;
>
> - /* Figure out the extent size, adjust alen */
> - if (whichfork == XFS_COW_FORK) {
> + /*
> + * If we're targeting the COW fork but aren't creating a speculative
> + * posteof preallocation, try to expand the reservation to align with
> + * the cow extent size hint if there's sufficient free space.
> + *
> + * Unlike the data fork, the CoW cancellation functions will free all
> + * the reservations at inactivation, so we don't require that every
> + * delalloc reservation have a dirty pagecache.
> + *
> + * XXX(hch): I can't see where we actually require dirty pagecache
> + * for speculative data fork preallocations. What am I missing?
IIRC a delalloc reservation in the data fork that isn't backing a dirty
page will just sit there in the data fork and never get reclaimed.
There's no writeback to turn it into an unwritten -> written extent.
The blockgc functions won't (can't?) walk the pagecache to find clean
regions that could be torn down. xfs destroy_inode just asserts on any
reservations that it finds.
--D
> + */
> + if (use_cowextszhint) {
> struct xfs_bmbt_irec prev;
> xfs_extlen_t extsz = xfs_get_cowextsz_hint(ip);
>
> @@ -4090,7 +4104,7 @@ xfs_bmapi_reserve_delalloc(
> */
> error = xfs_quota_reserve_blkres(ip, alen);
> if (error)
> - return error;
> + goto out;
>
> /*
> * Split changing sb for alen and indlen since they could be coming
> @@ -4140,6 +4154,16 @@ xfs_bmapi_reserve_delalloc(
> out_unreserve_quota:
> if (XFS_IS_QUOTA_ON(mp))
> xfs_quota_unreserve_blkres(ip, alen);
> +out:
> + if (error == -ENOSPC || error == -EDQUOT) {
> + trace_xfs_delalloc_enospc(ip, off, len);
> + if (prealloc || use_cowextszhint) {
> + /* retry without any preallocation */
> + prealloc = 0;
> + use_cowextszhint = false;
> + goto retry;
> + }
> + }
> return error;
> }
>
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 3783426739258c..34cce017fe7ce1 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -1148,27 +1148,13 @@ xfs_buffered_write_iomap_begin(
> }
> }
>
> -retry:
> error = xfs_bmapi_reserve_delalloc(ip, allocfork, offset_fsb,
> end_fsb - offset_fsb, prealloc_blocks,
> allocfork == XFS_DATA_FORK ? &imap : &cmap,
> allocfork == XFS_DATA_FORK ? &icur : &ccur,
> allocfork == XFS_DATA_FORK ? eof : cow_eof);
> - switch (error) {
> - case 0:
> - break;
> - case -ENOSPC:
> - case -EDQUOT:
> - /* retry without any preallocation */
> - trace_xfs_delalloc_enospc(ip, offset, count);
> - if (prealloc_blocks) {
> - prealloc_blocks = 0;
> - goto retry;
> - }
> - fallthrough;
> - default:
> + if (error)
> goto out_unlock;
> - }
>
> if (allocfork == XFS_COW_FORK) {
> trace_xfs_iomap_alloc(ip, offset, count, allocfork, &cmap);
next prev parent reply other threads:[~2024-06-14 5:27 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-12 17:46 [PATCHSET] xfs: random fixes for 6.10 Darrick J. Wong
2024-06-12 17:46 ` [PATCH 1/5] xfs: don't treat append-only files as having preallocations Darrick J. Wong
2024-06-13 6:03 ` Dave Chinner
2024-06-13 8:28 ` Christoph Hellwig
2024-06-17 5:03 ` Dave Chinner
2024-06-17 6:46 ` Christoph Hellwig
2024-06-17 23:28 ` Dave Chinner
2024-06-12 17:47 ` [PATCH 2/5] xfs: fix freeing speculative preallocations for preallocated files Darrick J. Wong
2024-06-12 17:47 ` [PATCH 3/5] xfs: restrict when we try to align cow fork delalloc to cowextsz hints Darrick J. Wong
2024-06-13 5:06 ` Christoph Hellwig
2024-06-14 4:13 ` Darrick J. Wong
2024-06-14 4:41 ` Christoph Hellwig
2024-06-14 5:27 ` Darrick J. Wong [this message]
2024-06-14 5:30 ` Christoph Hellwig
2024-06-12 17:47 ` [PATCH 4/5] xfs: allow unlinked symlinks and dirs with zero size Darrick J. Wong
2024-06-13 4:57 ` Christoph Hellwig
2024-06-12 17:47 ` [PATCH 5/5] xfs: verify buffer, inode, and dquot items every tx commit Darrick J. Wong
2024-06-13 5:07 ` Christoph Hellwig
2024-06-13 7:04 ` Dave Chinner
2024-06-14 3:49 ` Darrick J. Wong
2024-06-14 4:42 ` Christoph Hellwig
2024-06-14 5:23 ` Darrick J. Wong
2024-06-18 0:18 ` [PATCH v1.1 " Darrick J. Wong
2024-06-18 6:38 ` 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=20240614052705.GC6147@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=chandanbabu@kernel.org \
--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 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.