From: Dave Chinner <david@fromorbit.com>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: Brian Foster <bfoster@redhat.com>, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 4/6] xfs: fix infinite loop when reserving free block pool
Date: Thu, 24 Mar 2022 08:11:47 +1100 [thread overview]
Message-ID: <20220323211147.GX1544202@dread.disaster.area> (raw)
In-Reply-To: <164779462946.550479.3987400627869935198.stgit@magnolia>
On Sun, Mar 20, 2022 at 09:43:49AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> Don't spin in an infinite loop trying to reserve blocks -- if we can't
> do it after 30 tries, we're racing with a nearly full filesystem, so
> just give up.
>
> Cc: Brian Foster <bfoster@redhat.com>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> Reviewed-by: Brian Foster <bfoster@redhat.com>
> ---
> fs/xfs/xfs_fsops.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
>
> diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
> index 710e857bb825..615334e4f689 100644
> --- a/fs/xfs/xfs_fsops.c
> +++ b/fs/xfs/xfs_fsops.c
> @@ -379,6 +379,7 @@ xfs_reserve_blocks(
> int64_t fdblks_delta = 0;
> uint64_t request;
> int64_t free;
> + unsigned int tries;
> int error = 0;
>
> /* If inval is null, report current values and return */
> @@ -430,9 +431,16 @@ xfs_reserve_blocks(
> * If the request is larger than the current reservation, reserve the
> * blocks before we update the reserve counters. Sample m_fdblocks and
> * perform a partial reservation if the request exceeds free space.
> + *
> + * The loop body estimates how many blocks it can request from fdblocks
> + * to stash in the reserve pool. This is a classic TOCTOU race since
> + * fdblocks updates are not always coordinated via m_sb_lock. We also
> + * cannot tell if @free remaining unchanged between iterations is due
> + * to an idle system or freed blocks being consumed immediately, so
> + * we'll try a finite number of times to satisfy the request.
> */
> error = -ENOSPC;
> - do {
> + for (tries = 0; tries < 30 && error == -ENOSPC; tries++) {
> free = percpu_counter_sum(&mp->m_fdblocks) -
> xfs_fdblocks_unavailable(mp);
> if (free <= 0)
> @@ -459,7 +467,7 @@ xfs_reserve_blocks(
> spin_unlock(&mp->m_sb_lock);
> error = xfs_mod_fdblocks(mp, -fdblks_delta, 0);
> spin_lock(&mp->m_sb_lock);
> - } while (error == -ENOSPC);
> + }
So the problem here is that if we don't get all of the reservation,
we get none of it, so we try again. This seems like we should simply
punch the error back out to userspace and let it retry rather than
try a few times and then fail anyway. Either way, userspace has to
handle failure to reserve enough blocks.
The other alternative here is that we just change the reserve block
limit when ENOSPC occurs and allow the xfs_mod_fdblocks() refill
code just fill up the pool as space is freed. That would greatly
simplify the code - we do a single attempt to reserve the new space,
and if it fails we don't care because the reserve space gets
refilled before free space is made available again. I think that's
preferable to having an arbitrary number of retries like this that's
going to end up failing anyway.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
next prev parent reply other threads:[~2022-03-23 21:11 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-20 16:43 [PATCHSET v3 0/6] xfs: fix incorrect reserve pool calculations and reporting Darrick J. Wong
2022-03-20 16:43 ` [PATCH 1/6] xfs: document the XFS_ALLOC_AGFL_RESERVE constant Darrick J. Wong
2022-03-23 20:39 ` Dave Chinner
2022-03-24 5:15 ` Darrick J. Wong
2022-03-24 5:58 ` Dave Chinner
2022-03-20 16:43 ` [PATCH 2/6] xfs: actually set aside enough space to handle a bmbt split Darrick J. Wong
2022-03-23 20:48 ` Dave Chinner
2022-03-24 5:26 ` Darrick J. Wong
2022-03-24 6:00 ` Dave Chinner
2022-03-20 16:43 ` [PATCH 3/6] xfs: don't include bnobt blocks when reserving free block pool Darrick J. Wong
2022-03-21 15:22 ` Brian Foster
2022-03-21 20:42 ` Darrick J. Wong
2022-03-23 20:51 ` Dave Chinner
2022-03-20 16:43 ` [PATCH 4/6] xfs: fix infinite loop " Darrick J. Wong
2022-03-23 21:11 ` Dave Chinner [this message]
2022-03-24 5:24 ` Darrick J. Wong
2022-03-24 6:21 ` Dave Chinner
2022-03-20 16:43 ` [PATCH 5/6] xfs: don't report reserved bnobt space as available Darrick J. Wong
2022-03-21 15:22 ` Brian Foster
2022-03-21 20:48 ` Darrick J. Wong
2022-03-23 21:12 ` Dave Chinner
2022-03-20 16:44 ` [PATCH 6/6] xfs: rename "alloc_set_aside" to be more descriptive Darrick J. Wong
2022-03-23 21:21 ` Dave Chinner
-- strict thread matches above, loose matches on Subject: below --
2022-03-17 21:20 [PATCHSET v2 0/6] xfs: fix incorrect reserve pool calculations and reporting Darrick J. Wong
2022-03-17 21:21 ` [PATCH 4/6] xfs: fix infinite loop when reserving free block pool Darrick J. Wong
2022-03-18 12:18 ` Brian Foster
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=20220323211147.GX1544202@dread.disaster.area \
--to=david@fromorbit.com \
--cc=bfoster@redhat.com \
--cc=djwong@kernel.org \
--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