From: Brian Foster <bfoster@redhat.com>
To: Carlos Maiolino <cmaiolino@redhat.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 2/2] xfs: Properly retry failed inode items in case of error during buffer writeback
Date: Mon, 19 Jun 2017 11:09:13 -0400 [thread overview]
Message-ID: <20170619150912.GE25516@bfoster.bfoster> (raw)
In-Reply-To: <20170619134940.GC25516@bfoster.bfoster>
On Mon, Jun 19, 2017 at 09:49:42AM -0400, Brian Foster wrote:
> On Fri, Jun 16, 2017 at 12:54:45PM +0200, Carlos Maiolino wrote:
> > When a buffer has been failed during writeback, the inode items into it
> > are kept flush locked, and are never resubmitted due the flush lock, so,
> > if any buffer fails to be written, the items in AIL are never written to
> > disk and never unlocked.
> >
> > This causes unmount operation to hang due these items flush locked in AIL,
> > but this also causes the items in AIL to never be written back, even when
> > the IO device comes back to normal.
> >
> > I've been testing this patch with a DM-thin device, creating a
> > filesystem larger than the real device.
> >
> > When writing enough data to fill the DM-thin device, XFS receives ENOSPC
> > errors from the device, and keep spinning on xfsaild (when 'retry
> > forever' configuration is set).
> >
> > At this point, the filesystem can not be unmounted because of the flush locked
> > items in AIL, but worse, the items in AIL are never retried at all
> > (once xfs_inode_item_push() will skip the items that are flush locked),
> > even if the underlying DM-thin device is expanded to the proper size.
> >
> > This patch fixes both cases, retrying any item that has been failed
> > previously, using the infra-structure provided by the previous patch.
> >
> > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> > ---
...
> > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> > index 08cb7d1..2719ac6 100644
> > --- a/fs/xfs/xfs_inode_item.c
> > +++ b/fs/xfs/xfs_inode_item.c
...
> > @@ -475,6 +476,18 @@ xfs_inode_item_unpin(
> > wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT);
> > }
> >
> > +/*
> > + * Callback used to mark a buffer with XFS_LI_FAILED when items in the buffer
> > + * have been failed during writeback
> > + */
> > +STATIC void
> > +xfs_inode_item_error(
> > + struct xfs_log_item *lip,
> > + struct xfs_buf *bp)
> > +{
Also if we're going to keep the ->iop_error() thing around, could we add
an 'ASSERT(xfs_isiflocked(INODE_ITEM(lip)->ili_inode))' here?
Brian
> > + xfs_set_li_failed(lip, bp);
> > +}
> > +
> > STATIC uint
> > xfs_inode_item_push(
> > struct xfs_log_item *lip,
> > @@ -491,6 +504,17 @@ xfs_inode_item_push(
> > if (xfs_ipincount(ip) > 0)
> > return XFS_ITEM_PINNED;
> >
> > + /*
> > + * The buffer containing this item failed to be written back
> > + * previously. Resubmit the buffer for IO.
> > + */
> > + if (lip->li_flags & XFS_LI_FAILED) {
> > + if (!xfs_buf_resubmit_failed_buffers(lip, buffer_list))
> > + rval = XFS_ITEM_FLUSHING;
> > +
> > + return rval;
> > + }
> > +
> > if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
> > return XFS_ITEM_LOCKED;
> >
> > @@ -622,7 +646,8 @@ static const struct xfs_item_ops xfs_inode_item_ops = {
> > .iop_unlock = xfs_inode_item_unlock,
> > .iop_committed = xfs_inode_item_committed,
> > .iop_push = xfs_inode_item_push,
> > - .iop_committing = xfs_inode_item_committing
> > + .iop_committing = xfs_inode_item_committing,
> > + .iop_error = xfs_inode_item_error
> > };
> >
> >
> > @@ -710,7 +735,8 @@ xfs_iflush_done(
> > * the AIL lock.
> > */
> > iip = INODE_ITEM(blip);
> > - if (iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn)
> > + if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) ||
> > + lip->li_flags & XFS_LI_FAILED)
> > need_ail++;
> >
> > blip = next;
> > @@ -718,7 +744,8 @@ xfs_iflush_done(
> >
> > /* make sure we capture the state of the initial inode. */
> > iip = INODE_ITEM(lip);
> > - if (iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn)
> > + if ((iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn) ||
> > + lip->li_flags & XFS_LI_FAILED)
> > need_ail++;
> >
> > /*
> > @@ -739,6 +766,9 @@ xfs_iflush_done(
> > if (INODE_ITEM(blip)->ili_logged &&
> > blip->li_lsn == INODE_ITEM(blip)->ili_flush_lsn)
> > mlip_changed |= xfs_ail_delete_one(ailp, blip);
> > + else {
> > + xfs_clear_li_failed(blip);
> > + }
> > }
> >
> > if (mlip_changed) {
> > diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> > index 50df5367..2d7cf91 100644
> > --- a/fs/xfs/xfs_trans.h
> > +++ b/fs/xfs/xfs_trans.h
> > @@ -49,6 +49,7 @@ typedef struct xfs_log_item {
> > struct xfs_ail *li_ailp; /* ptr to AIL */
> > uint li_type; /* item type */
> > uint li_flags; /* misc flags */
> > + struct xfs_buf *li_buf; /* real buffer pointer */
> > struct xfs_log_item *li_bio_list; /* buffer item list */
> > void (*li_cb)(struct xfs_buf *,
> > struct xfs_log_item *);
> > @@ -72,6 +73,31 @@ typedef struct xfs_log_item {
> > { XFS_LI_ABORTED, "ABORTED" }, \
> > { XFS_LI_FAILED, "FAILED" }
> >
> > +static inline void
> > +xfs_clear_li_failed(
> > + struct xfs_log_item *lip)
> > +{
> > + struct xfs_buf *bp = lip->li_buf;
> > +
>
> I think we should assert that ->xa_lock is held in both of these
> helpers. Note that we have to use lockdep_assert_held() for spinlocks.
>
> It also couldn't hurt to assert that XFS_LI_IN_AIL is set as well (we'd
> just have to reorder the _clear_li_failed() call in xfs_ail_delete_one()
> below).
>
> > + if (lip->li_flags & XFS_LI_FAILED) {
> > + lip->li_flags &= ~XFS_LI_FAILED;
> > + lip->li_buf = NULL;
> > + xfs_buf_rele(bp);
> > + }
> > +}
> > +
> > +static inline void
> > +xfs_set_li_failed(
> > + struct xfs_log_item *lip,
> > + struct xfs_buf *bp)
> > +{
> > + if (lip->li_flags & ~XFS_LI_FAILED) {
>
> I think you want !(lip->li_flags & XFS_LI_FAILED). ;)
>
> Brian
>
> > + xfs_buf_hold(bp);
> > + lip->li_flags |= XFS_LI_FAILED;
> > + lip->li_buf = bp;
> > + }
> > +}
> > +
> > struct xfs_item_ops {
> > void (*iop_size)(xfs_log_item_t *, int *, int *);
> > void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *);
> > diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> > index 9056c0f..c41d640 100644
> > --- a/fs/xfs/xfs_trans_ail.c
> > +++ b/fs/xfs/xfs_trans_ail.c
> > @@ -687,15 +687,15 @@ xfs_trans_ail_update_bulk(
> > bool
> > xfs_ail_delete_one(
> > struct xfs_ail *ailp,
> > - struct xfs_log_item *lip)
> > + struct xfs_log_item *lip)
> > {
> > struct xfs_log_item *mlip = xfs_ail_min(ailp);
> >
> > trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn);
> > xfs_ail_delete(ailp, lip);
> > lip->li_flags &= ~XFS_LI_IN_AIL;
> > + xfs_clear_li_failed(lip);
> > lip->li_lsn = 0;
> > -
> > return mlip == lip;
> > }
> >
> > --
> > 2.9.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2017-06-19 15:09 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-16 10:54 [PATCH 0/2 V4] Resubmit items failed during writeback Carlos Maiolino
2017-06-16 10:54 ` [PATCH 1/2 V4] xfs: Add infrastructure needed for error propagation during buffer IO failure Carlos Maiolino
2017-06-19 13:48 ` Brian Foster
2017-06-20 7:15 ` Carlos Maiolino
2017-06-16 10:54 ` [PATCH 2/2] xfs: Properly retry failed inode items in case of error during buffer writeback Carlos Maiolino
2017-06-16 11:06 ` Carlos Maiolino
2017-06-16 18:35 ` Luis R. Rodriguez
2017-06-16 19:24 ` Darrick J. Wong
2017-06-16 19:37 ` Luis R. Rodriguez
2017-06-16 19:45 ` Eric Sandeen
2017-06-19 10:59 ` Brian Foster
2017-06-20 16:52 ` Luis R. Rodriguez
2017-06-20 17:20 ` Brian Foster
2017-06-20 18:05 ` Luis R. Rodriguez
2017-06-21 10:10 ` Brian Foster
2017-06-21 15:25 ` Luis R. Rodriguez
2017-06-20 18:38 ` Luis R. Rodriguez
2017-06-20 7:01 ` Carlos Maiolino
2017-06-20 16:24 ` Luis R. Rodriguez
2017-06-21 11:51 ` Carlos Maiolino
2017-06-19 13:49 ` Brian Foster
2017-06-19 15:09 ` Brian Foster [this message]
2017-06-19 13:51 ` [PATCH 0/2 V4] Resubmit items failed during writeback Brian Foster
2017-06-19 17:42 ` Darrick J. Wong
2017-06-19 18:51 ` Brian Foster
2017-06-21 0:45 ` Darrick J. Wong
2017-06-21 10:15 ` Brian Foster
2017-06-21 11:03 ` Carlos Maiolino
2017-06-21 11:51 ` Brian Foster
2017-06-21 16:54 ` Darrick J. Wong
2017-06-22 12:05 ` Carlos Maiolino
2017-06-22 12:40 ` Brian Foster
2017-06-30 11:09 ` Carlos Maiolino
2017-06-30 11:33 ` Brian Foster
2017-06-30 12:22 ` Carlos Maiolino
2017-06-30 17:01 ` Darrick J. Wong
2017-07-03 8:37 ` Carlos Maiolino
2017-06-21 16:45 ` Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2017-05-11 13:57 [PATCH 0/2] " Carlos Maiolino
2017-05-11 13:57 ` [PATCH 2/2] xfs: Properly retry failed inode items in case of error during buffer writeback Carlos Maiolino
2017-05-11 15:32 ` Eric Sandeen
2017-05-12 8:19 ` Carlos Maiolino
2017-05-11 17:08 ` Brian Foster
2017-05-12 8:21 ` Carlos Maiolino
2017-05-12 11:37 ` Brian Foster
2017-05-17 11:47 ` Carlos Maiolino
2017-05-17 0:57 ` Dave Chinner
2017-05-17 10:41 ` Carlos Maiolino
2017-05-19 0:22 ` Dave Chinner
2017-05-19 11:27 ` Brian Foster
2017-05-19 23:39 ` Dave Chinner
2017-05-20 11:46 ` Brian Foster
2017-05-21 23:19 ` Dave Chinner
2017-05-22 12:51 ` Brian Foster
2017-05-23 11:23 ` Dave Chinner
2017-05-23 16:22 ` Brian Foster
2017-05-24 1:06 ` Dave Chinner
2017-05-24 12:42 ` Brian Foster
2017-05-24 13:26 ` Carlos Maiolino
2017-05-24 17:08 ` 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=20170619150912.GE25516@bfoster.bfoster \
--to=bfoster@redhat.com \
--cc=cmaiolino@redhat.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 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.