From: Mark Tinguely <tinguely@sgi.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH v3] xfs: free the efi AIL entry on log recovery failure
Date: Mon, 23 Dec 2013 10:42:25 -0600 [thread overview]
Message-ID: <52B867F1.2030804@sgi.com> (raw)
In-Reply-To: <20131211113126.GA6248@infradead.org>
Sorry it took me so long to get to this.
I like the idea to keep the majority of EFI items off the AIL, but it
does not simply the EFI recovery processing. xfs_recover_process_efi()
will place the EFI entry on the AIL and recreate the hanging on unmount
problem when there is an error in the extent free or transaction commit.
Since the patch removes the XFS_EFI_RECOVERED flag/code, it is harder to
remove this entry. If you leave the XFS_EFI_RECOVERED flag/code in XFS,
the patch to avoid a hang in xfs_ail_push_all_sync() will be the same as
before.
As you commented, it does leak some memory, which can be easily fixed...
On 12/11/13 05:31, Christoph Hellwig wrote
> Use a cancellation table, similar to how we handle buffers instead of
> abusing the AIL during recovery.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
> ---
...
> @@ -3059,82 +3065,50 @@ xlog_recover_efi_pass2(
> struct xlog_recover_item *item,
> xfs_lsn_t lsn)
> {
> - int error;
> - xfs_mount_t *mp = log->l_mp;
> - xfs_efi_log_item_t *efip;
> - xfs_efi_log_format_t *efi_formatp;
> + struct xfs_efi_cancel *ecp;
> + int error;
> + xfs_mount_t *mp = log->l_mp;
> + xfs_efi_log_format_t *efi_formatp;
typedef got leaked back in.
...
> @@ -3618,27 +3592,26 @@ xlog_recover_process_data(
> }
>
> /*
> - * Process an extent free intent item that was recovered from
> - * the log. We need to free the extents that it describes.
> + * Process an extent free intent item that was recovered from the log.
> + * We need to free the extents that it describes.
> */
> STATIC int
> xlog_recover_process_efi(
> - xfs_mount_t *mp,
> - xfs_efi_log_item_t *efip)
> + struct xlog *log,
> + struct xfs_efi_cancel *ecp)
> {
> - xfs_efd_log_item_t *efdp;
> - xfs_trans_t *tp;
> - int i;
> - int error = 0;
> - xfs_extent_t *extp;
> + struct xfs_mount *mp = log->l_mp;
> + struct xfs_efi_log_item *efip = ecp->ec_efip;
> + struct xfs_efd_log_item *efdp;
> + struct xfs_trans *tp;
> + struct xfs_extent *extp;
> xfs_fsblock_t startblock_fsb;
> -
> - ASSERT(!test_bit(XFS_EFI_RECOVERED,&efip->efi_flags));
> + int error = 0;
> + int i;
>
> /*
> - * First check the validity of the extents described by the
> - * EFI. If any are bad, then assume that all are bad and
> - * just toss the EFI.
> + * First check the validity of the extents described by the EFI.
> + * If any are bad, then assume that all are bad and just toss the EFI.
> */
> for (i = 0; i< efip->efi_format.efi_nextents; i++) {
> extp =&(efip->efi_format.efi_extents[i]);
> @@ -3652,12 +3625,14 @@ xlog_recover_process_efi(
> * This will pull the EFI from the AIL and
> * free the memory associated with it.
> */
> - set_bit(XFS_EFI_RECOVERED,&efip->efi_flags);
> xfs_efi_release(efip, efip->efi_format.efi_nextents);
> return XFS_ERROR(EIO);
> }
> }
Soo at this point we are dealing with the EFIs that do not have matching
EFD. The EFI are in the new l_efi_cancel and not on the AIL. I am
correct in thinking that there is no reason to do a xfs_efi_release() above?
>
> + spin_lock(&log->l_ailp->xa_lock);
> + xfs_trans_ail_update(log->l_ailp,&efip->efi_item, ecp->ec_lsn);
we now added the EFI to the AIL. If anything fails in the
xfs_free_extent()/xfs_trans_commit then EFI has to be removed which is
now trickier without the XFS_EFI_RECOVERED flag.
I suppose we could:
1) leave the XFS_EFI_RECOVERED counter/code.
2) manually decrease the counter. *
3) manually remove the entry from the AIL. *
* terrible hack that everyone will NACK.
> - */
> STATIC int
> xlog_recover_process_efis(
> struct xlog *log)
> {
...
> - spin_lock(&ailp->xa_lock);
> + list_for_each_entry_safe(ecp, next,&log->l_efi_cancel, ec_list) {
> + list_del(&ecp->ec_list);
> + error = xlog_recover_process_efi(log, ecp);
> if (error)
> - goto out;
> - lip = xfs_trans_ail_cursor_next(ailp,&cur);
> + break; /* XXX: will leak remaining EFIs.. */
...rather than leaking the rest of the efi cancel entries:
/* comment here about removing entries on error */
if (!error)
error = xlog_recover_process_efi(log, ecp);
Again, sorry for the delay. I will wait to see what you want to do with
this patch before resubmitting the patch to free EFI from the AIL.
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
prev parent reply other threads:[~2013-12-23 16:42 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-06 21:20 [PATCH 0/2] misc log recovery patches Mark Tinguely
2013-12-06 21:20 ` [PATCH 1/2] xfs: fix double free on error when cleaning log items Mark Tinguely
2013-12-09 0:29 ` Dave Chinner
2013-12-06 21:20 ` [PATCH 2/2] xfs: free the efi AIL entry on log recovery failure Mark Tinguely
2013-12-08 0:52 ` [PATCH v3] " Mark Tinguely
2013-12-09 1:00 ` Dave Chinner
2013-12-11 11:31 ` Christoph Hellwig
2013-12-11 17:25 ` Mark Tinguely
2013-12-23 16:42 ` Mark Tinguely [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=52B867F1.2030804@sgi.com \
--to=tinguely@sgi.com \
--cc=hch@infradead.org \
--cc=xfs@oss.sgi.com \
/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