From: Brian Foster <bfoster@redhat.com>
To: Dave Chinner <david@fromorbit.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 10/12] xfs: clean up AIL log item removal functions
Date: Mon, 20 Apr 2020 10:03:39 -0400 [thread overview]
Message-ID: <20200420140339.GH27516@bfoster> (raw)
In-Reply-To: <20200420043233.GL9800@dread.disaster.area>
On Mon, Apr 20, 2020 at 02:32:33PM +1000, Dave Chinner wrote:
> On Fri, Apr 17, 2020 at 11:08:57AM -0400, Brian Foster wrote:
> > We have two AIL removal functions with slightly different semantics.
> > xfs_trans_ail_delete() expects the caller to have the AIL lock and
> > for the associated item to be AIL resident. If not, the filesystem
> > is shut down. xfs_trans_ail_remove() acquires the AIL lock, checks
> > that the item is AIL resident and calls the former if so.
> >
> > These semantics lead to confused usage between the two. For example,
> > the _remove() variant takes a shutdown parameter to pass to the
> > _delete() variant, but immediately returns if the AIL bit is not
> > set. This means that _remove() would never shut down if an item is
> > not AIL resident, even though it appears that many callers would
> > expect it to.
> >
> > Make the following changes to clean up both of these functions:
> >
> > - Most callers of xfs_trans_ail_delete() acquire the AIL lock just
> > before the call. Update _delete() to acquire the lock and open
> > code the couple of callers that make additional checks under AIL
> > lock.
> > - Drop the unnecessary ailp parameter from _delete().
> > - Drop the unused shutdown parameter from _remove() and open code
> > the implementation.
> >
> > In summary, this leaves a _delete() variant that expects an AIL
> > resident item and a _remove() helper that checks the AIL bit. Audit
> > the existing callsites for use of the appropriate function and
> > update as necessary.
> >
> > Signed-off-by: Brian Foster <bfoster@redhat.com>
> ....
>
> Good start, but...
>
> > @@ -1032,10 +1033,11 @@ xfs_qm_dqflush_done(
> > goto out;
> >
> > spin_lock(&ailp->ail_lock);
> > - if (lip->li_lsn == qip->qli_flush_lsn)
> > - /* xfs_trans_ail_delete() drops the AIL lock */
> > - xfs_trans_ail_delete(ailp, lip, SHUTDOWN_CORRUPT_INCORE);
> > - else
> > + if (lip->li_lsn == qip->qli_flush_lsn) {
> > + /* xfs_ail_update_finish() drops the AIL lock */
> > + tail_lsn = xfs_ail_delete_one(ailp, lip);
> > + xfs_ail_update_finish(ailp, tail_lsn);
> > + } else
> > spin_unlock(&ailp->ail_lock);
>
> This drops the shutdown if the dquot is not in the AIL. It should be
> in the AIL, so if it isn't we should be shutting down...
>
It might not be in the AIL if we're in quotacheck because it does
everything in-core.
> > @@ -872,13 +872,14 @@ xfs_ail_delete_one(
> > */
> > void
> > xfs_trans_ail_delete(
> > - struct xfs_ail *ailp,
> > struct xfs_log_item *lip,
> > int shutdown_type)
> > {
> > + struct xfs_ail *ailp = lip->li_ailp;
> > struct xfs_mount *mp = ailp->ail_mount;
> > xfs_lsn_t tail_lsn;
> >
> > + spin_lock(&ailp->ail_lock);
> > if (!test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
> > spin_unlock(&ailp->ail_lock);
> > if (!XFS_FORCED_SHUTDOWN(mp)) {
> > diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
> > index 9135afdcee9d..7563c78e2997 100644
> > --- a/fs/xfs/xfs_trans_priv.h
> > +++ b/fs/xfs/xfs_trans_priv.h
> > @@ -94,22 +94,23 @@ xfs_trans_ail_update(
> > xfs_lsn_t xfs_ail_delete_one(struct xfs_ail *ailp, struct xfs_log_item *lip);
> > void xfs_ail_update_finish(struct xfs_ail *ailp, xfs_lsn_t old_lsn)
> > __releases(ailp->ail_lock);
> > -void xfs_trans_ail_delete(struct xfs_ail *ailp, struct xfs_log_item *lip,
> > - int shutdown_type);
> > +void xfs_trans_ail_delete(struct xfs_log_item *lip, int shutdown_type);
> >
> > static inline void
> > xfs_trans_ail_remove(
> > - struct xfs_log_item *lip,
> > - int shutdown_type)
> > + struct xfs_log_item *lip)
> > {
> > struct xfs_ail *ailp = lip->li_ailp;
> > + xfs_lsn_t tail_lsn;
> >
> > spin_lock(&ailp->ail_lock);
> > - /* xfs_trans_ail_delete() drops the AIL lock */
> > - if (test_bit(XFS_LI_IN_AIL, &lip->li_flags))
> > - xfs_trans_ail_delete(ailp, lip, shutdown_type);
> > - else
> > + /* xfs_ail_update_finish() drops the AIL lock */
> > + if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
> > + tail_lsn = xfs_ail_delete_one(ailp, lip);
> > + xfs_ail_update_finish(ailp, tail_lsn);
> > + } else {
> > spin_unlock(&ailp->ail_lock);
> > + }
> > }
>
> This makes xfs_trans_ail_delete() and xfs_trans_ail_remove() almost
> identical, except one will shutdown if the item is not in the AIL
> and the other won't. Wouldn't it be better to get it down to just
> one function that does everything, and remove the confusion of which
> to use altogether?
>
Yes, I was thinking about doing this when working on this patch but
determined it was easier to fix up both functions first and then
consider combining them in a separate step, but then never got back to
it. That might have been before I ended up open-coding some of the other
sites too so the end result wasn't really clear to me.
Regardless, I'll take another look and fold that change in if it makes
sense..
Brian
> void
> xfs_trans_ail_delete(
> struct xfs_log_item *lip,
> int shutdown)
> {
> struct xfs_ail *ailp = lip->li_ailp;
>
> spin_lock(&ailp->ail_lock);
> if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
> xfs_lsn_t tail_lsn = xfs_ail_delete_one(ailp, lip);
> xfs_ail_update_finish(ailp, tail_lsn);
> return;
> }
> spin_unlock(&ailp->ail_lock);
> if (!shutdown)
> return;
>
> /* do shutdown stuff */
> }
>
> -Dave.
>
> --
> Dave Chinner
> david@fromorbit.com
>
next prev parent reply other threads:[~2020-04-20 14:03 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-17 15:08 [PATCH 00/12] xfs: flush related error handling cleanups Brian Foster
2020-04-17 15:08 ` [PATCH 01/12] xfs: refactor failed buffer resubmission into xfsaild Brian Foster
2020-04-17 22:37 ` Allison Collins
2020-04-20 2:45 ` Dave Chinner
2020-04-20 13:58 ` Brian Foster
2020-04-20 22:19 ` Dave Chinner
2020-04-17 15:08 ` [PATCH 02/12] xfs: factor out buffer I/O failure simulation code Brian Foster
2020-04-17 22:37 ` Allison Collins
2020-04-20 2:48 ` Dave Chinner
2020-04-20 13:58 ` Brian Foster
2020-04-17 15:08 ` [PATCH 03/12] xfs: always attach iflush_done and simplify error handling Brian Foster
2020-04-18 0:07 ` Allison Collins
2020-04-20 13:59 ` Brian Foster
2020-04-20 3:08 ` Dave Chinner
2020-04-20 14:00 ` Brian Foster
2020-04-17 15:08 ` [PATCH 04/12] xfs: remove unnecessary shutdown check from xfs_iflush() Brian Foster
2020-04-18 0:27 ` Allison Collins
2020-04-20 3:10 ` Dave Chinner
2020-04-17 15:08 ` [PATCH 05/12] xfs: ratelimit unmount time per-buffer I/O error warning Brian Foster
2020-04-20 3:19 ` Dave Chinner
2020-04-20 14:02 ` Brian Foster
2020-04-20 22:23 ` Dave Chinner
2020-04-21 12:13 ` Brian Foster
2020-04-20 18:50 ` Allison Collins
2020-04-17 15:08 ` [PATCH 06/12] xfs: remove duplicate verification from xfs_qm_dqflush() Brian Foster
2020-04-20 3:53 ` Dave Chinner
2020-04-20 14:02 ` Brian Foster
2020-04-20 22:31 ` Dave Chinner
2020-04-17 15:08 ` [PATCH 07/12] xfs: abort consistently on dquot flush failure Brian Foster
2020-04-20 3:54 ` Dave Chinner
2020-04-20 18:50 ` Allison Collins
2020-04-17 15:08 ` [PATCH 08/12] xfs: remove unnecessary quotaoff intent item push handler Brian Foster
2020-04-20 3:58 ` Dave Chinner
2020-04-20 14:02 ` Brian Foster
2020-04-17 15:08 ` [PATCH 09/12] xfs: elide the AIL lock on log item failure tracking Brian Foster
2020-04-17 15:08 ` [PATCH 10/12] xfs: clean up AIL log item removal functions Brian Foster
2020-04-20 4:32 ` Dave Chinner
2020-04-20 14:03 ` Brian Foster [this message]
2020-04-17 15:08 ` [PATCH 11/12] xfs: remove unused iflush stale parameter Brian Foster
2020-04-20 4:34 ` Dave Chinner
2020-04-20 19:19 ` Allison Collins
2020-04-17 15:08 ` [PATCH 12/12] xfs: random buffer write failure errortag Brian Foster
2020-04-20 4:37 ` Dave Chinner
2020-04-20 14:04 ` Brian Foster
2020-04-20 22:42 ` Allison Collins
2020-04-19 22:53 ` [PATCH 00/12] xfs: flush related error handling cleanups Dave Chinner
2020-04-20 14:06 ` Brian Foster
2020-04-20 22:53 ` Dave Chinner
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=20200420140339.GH27516@bfoster \
--to=bfoster@redhat.com \
--cc=david@fromorbit.com \
--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).