From: Brian Foster <bfoster@redhat.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH] xfs: don't unlock invalidated buf on aborted tx commit
Date: Wed, 22 Aug 2018 09:05:21 -0400 [thread overview]
Message-ID: <20180822130520.GD26084@bfoster> (raw)
In-Reply-To: <20180822060100.GA5665@infradead.org>
On Tue, Aug 21, 2018 at 11:01:00PM -0700, Christoph Hellwig wrote:
> > + int freed;
>
> I think this should be a bool..
>
Yep.
> > bool aborted;
> > bool hold = !!(bip->bli_flags & XFS_BLI_HOLD);
> > bool dirty = !!(bip->bli_flags & XFS_BLI_DIRTY);
> > + bool stale = !!(bip->bli_flags & XFS_BLI_STALE);
> > #if defined(DEBUG) || defined(XFS_WARN)
> > bool ordered = !!(bip->bli_flags & XFS_BLI_ORDERED);
> > #endif
> > + /*
> > + * The bli dirty state should match whether the blf has logged segments
> > + * except for ordered buffers, where only the bli should be dirty.
> > + */
> > + ASSERT((!ordered && dirty == xfs_buf_item_dirty_format(bip)) ||
> > + (ordered && dirty && !xfs_buf_item_dirty_format(bip)));
> > + ASSERT(!stale || (bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
> >
> > + trace_xfs_buf_item_unlock(bip);
> >
> > + aborted = test_bit(XFS_LI_ABORTED, &lip->li_flags);
> >
> > /*
> > + * Clear the buffer's association with this transaction and
> > + * per-transaction state from the bli, which has been copied above.
> > */
> > + bp->b_transp = NULL;
> > bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD | XFS_BLI_ORDERED);
> >
> > /*
> > + * Drop the transaction bli reference and free the item if clean or
> > + * aborted and we had the last reference. In either case this is the
> > + * last opportunity to free the item since it won't be written back.
> > + * Otherwise, the bli is still referenced or dirty and will be freed on
> > + * final unpin of the buffer (if stale) or writeback completion.
> > */
> > + freed = atomic_dec_and_test(&bip->bli_refcount);
> > + if (freed && (aborted || !dirty)) {
> > + ASSERT(!aborted || XFS_FORCED_SHUTDOWN(lip->li_mountp));
> > + ASSERT(!stale || aborted);
> > + /* an aborted item may be in the AIL, remove it first */
> > + if (aborted)
> > + xfs_trans_ail_remove(lip, SHUTDOWN_LOG_IO_ERROR);
> > + xfs_buf_item_relse(bp);
> > }
> >
> > /*
> > + * If the buffer was invalidated, leave it locked on transaction commit
> > + * unless we just dropped the final reference. The latter case should
> > + * only ever happen on abort because invalidation dirties the
> > + * transaction and the log would have grabbed another bli reference when
> > + * the buffer was pinned. In the non-abort case, the buffer is unlocked
> > + * on final unpin and the bli freed since stale buffers are not written
> > + * back.
> > */
> > + if (stale && !freed)
> > + return;
> > + ASSERT(!stale || (aborted && freed));
> >
> > if (!hold)
> > xfs_buf_relse(bp);
>
> I find the logic much more convoluted than what was there before.
>
> I seems like we could apply your stale fix without reshuffling the
> code like this:
>
> if (atomic_dec_and_test(&bip->bli_refcount)) {
> if (aborted) {
> ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
> xfs_trans_ail_remove(lip, SHUTDOWN_LOG_IO_ERROR);
> xfs_buf_item_relse(bp);
> } else if (!dirty) {
> ASSERT(!stale);
> xfs_buf_item_relse(bp);
> }
> } else {
> if (stale)
> return;
> }
>
> if (!hold)
> xfs_buf_relse(bp);
>
> which at least to me is a lot easier to read.
What you have here looks logically equivalent and exactly like the 1-2
liner I originally introduced to test the fix. I refactored the function
because I found it duplicated some logic, was unnecessarily long and
some of the comments actually look stale/out of place.
The logic fix here is indeed very small, as you and Dave have both
pointed out. I think what Dave proposed is roughly equivalent to what
you suggest and more closely resembles the original flow, so I'll take a
closer look at that and post a v2.
Brian
prev parent reply other threads:[~2018-08-22 16:30 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-21 14:01 [PATCH] xfs: don't unlock invalidated buf on aborted tx commit Brian Foster
2018-08-21 19:56 ` Bill O'Donnell
2018-08-22 0:28 ` Dave Chinner
2018-08-22 13:05 ` Brian Foster
2018-08-24 14:56 ` Brian Foster
2018-08-22 6:01 ` Christoph Hellwig
2018-08-22 13:05 ` Brian Foster [this message]
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=20180822130520.GD26084@bfoster \
--to=bfoster@redhat.com \
--cc=hch@infradead.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;
as well as URLs for NNTP newsgroup(s).