From: Christoph Hellwig <hch@infradead.org>
To: Patrick Schreurs <patrick@news-service.com>
Cc: Christoph Hellwig <hch@infradead.org>,
Tommy van Leeuwen <tommy@news-service.com>,
Bas Couwenberg <bas@news-service.com>, XFS List <xfs@oss.sgi.com>
Subject: Re: 2.6.31 xfs_fs_destroy_inode: cannot reclaim
Date: Mon, 12 Oct 2009 19:38:54 -0400 [thread overview]
Message-ID: <20091012233854.GA29446@infradead.org> (raw)
In-Reply-To: <4AD18C8D.90808@news-service.com>
On Sun, Oct 11, 2009 at 09:43:09AM +0200, Patrick Schreurs wrote:
> Hello Christoph,
>
> Attached you'll find a screenshot from a 2.6.31.3 server, which includes
> your patches and has XFS_DEBUG turned on. I truly hope this is useful to
> you.
Thanks. The patch below should fix the inode reclaim race that could
lead to the double free you're seeing. To be applied ontop of all
the other patches I sent you.
Index: xfs/fs/xfs/linux-2.6/xfs_sync.c
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_sync.c 2009-10-11 19:09:43.828254119 +0200
+++ xfs/fs/xfs/linux-2.6/xfs_sync.c 2009-10-12 13:48:14.886006087 +0200
@@ -670,22 +670,22 @@ xfs_reclaim_inode(
{
xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino);
- /* The hash lock here protects a thread in xfs_iget_core from
- * racing with us on linking the inode back with a vnode.
- * Once we have the XFS_IRECLAIM flag set it will not touch
- * us.
+ /*
+ * The hash lock here protects a thread in xfs_iget from racing with
+ * us on recycling the inode. Once we have the XFS_IRECLAIM flag set
+ * it will not touch it.
*/
- write_lock(&pag->pag_ici_lock);
spin_lock(&ip->i_flags_lock);
- if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
- !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) {
+ ASSERT_ALWAYS(__xfs_iflags_test(ip, XFS_IRECLAIMABLE));
+ if (__xfs_iflags_test(ip, XFS_IRECLAIM)) {
spin_unlock(&ip->i_flags_lock);
write_unlock(&pag->pag_ici_lock);
- return -EAGAIN;
+ return 0;
}
__xfs_iflags_set(ip, XFS_IRECLAIM);
spin_unlock(&ip->i_flags_lock);
write_unlock(&pag->pag_ici_lock);
+
xfs_put_perag(ip->i_mount, pag);
/*
@@ -758,27 +758,107 @@ __xfs_inode_clear_reclaim_tag(
XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
}
-STATIC int
-xfs_reclaim_inode_now(
- struct xfs_inode *ip,
+STATIC xfs_inode_t *
+xfs_reclaim_ag_lookup(
+ struct xfs_mount *mp,
struct xfs_perag *pag,
+ uint32_t *first_index)
+{
+ int nr_found;
+ struct xfs_inode *ip;
+
+ /*
+ * use a gang lookup to find the next inode in the tree
+ * as the tree is sparse and a gang lookup walks to find
+ * the number of objects requested.
+ */
+ write_lock(&pag->pag_ici_lock);
+ nr_found = radix_tree_gang_lookup_tag(&pag->pag_ici_root,
+ (void **)&ip, *first_index, 1, XFS_ICI_RECLAIM_TAG);
+ if (!nr_found)
+ goto unlock;
+
+ /*
+ * Update the index for the next lookup. Catch overflows
+ * into the next AG range which can occur if we have inodes
+ * in the last block of the AG and we are currently
+ * pointing to the last inode.
+ */
+ *first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
+ if (*first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
+ goto unlock;
+
+ return ip;
+
+unlock:
+ write_unlock(&pag->pag_ici_lock);
+ return NULL;
+}
+
+STATIC int
+xfs_reclaim_ag_walk(
+ struct xfs_mount *mp,
+ xfs_agnumber_t ag,
int flags)
{
- /* ignore if already under reclaim */
- if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
- read_unlock(&pag->pag_ici_lock);
- return 0;
+ struct xfs_perag *pag = &mp->m_perag[ag];
+ uint32_t first_index;
+ int last_error = 0;
+ int skipped;
+
+restart:
+ skipped = 0;
+ first_index = 0;
+ do {
+ int error = 0;
+ xfs_inode_t *ip;
+
+ ip = xfs_reclaim_ag_lookup(mp, pag, &first_index);
+ if (!ip)
+ break;
+
+ error = xfs_reclaim_inode(ip, flags);
+ if (error == EAGAIN) {
+ skipped++;
+ continue;
+ }
+ if (error)
+ last_error = error;
+ /*
+ * bail out if the filesystem is corrupted.
+ */
+ if (error == EFSCORRUPTED)
+ break;
+
+ } while (1);
+
+ if (skipped) {
+ delay(1);
+ goto restart;
}
- read_unlock(&pag->pag_ici_lock);
- return xfs_reclaim_inode(ip, flags);
+ xfs_put_perag(mp, pag);
+ return last_error;
}
int
xfs_reclaim_inodes(
- xfs_mount_t *mp,
- int mode)
+ xfs_mount_t *mp,
+ int mode)
{
- return xfs_inode_ag_iterator(mp, xfs_reclaim_inode_now, mode,
- XFS_ICI_RECLAIM_TAG);
+ int error = 0;
+ int last_error = 0;
+ xfs_agnumber_t ag;
+
+ for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
+ if (!mp->m_perag[ag].pag_ici_init)
+ continue;
+ error = xfs_reclaim_ag_walk(mp, ag, mode);
+ if (error) {
+ last_error = error;
+ if (error == EFSCORRUPTED)
+ break;
+ }
+ }
+ return XFS_ERROR(last_error);
}
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2009-10-12 23:37 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-16 10:27 2.6.31 xfs_fs_destroy_inode: cannot reclaim Tommy van Leeuwen
2009-09-17 18:59 ` Christoph Hellwig
2009-09-29 10:15 ` Patrick Schreurs
2009-09-29 12:57 ` Christoph Hellwig
2009-09-30 10:48 ` Patrick Schreurs
2009-09-30 12:41 ` Christoph Hellwig
2009-10-02 14:24 ` Bas Couwenberg
2009-10-05 21:43 ` Christoph Hellwig
2009-10-06 9:04 ` Patrick Schreurs
2009-10-07 1:19 ` Christoph Hellwig
2009-10-08 8:45 ` Patrick Schreurs
2009-10-11 7:43 ` Patrick Schreurs
2009-10-11 12:24 ` Christoph Hellwig
2009-10-12 23:38 ` Christoph Hellwig [this message]
2009-10-15 15:06 ` Tommy van Leeuwen
2009-10-18 23:59 ` Christoph Hellwig
2009-10-19 1:17 ` Dave Chinner
2009-10-19 3:53 ` Christoph Hellwig
2009-10-19 1:16 ` Dave Chinner
2009-10-19 3:54 ` Christoph Hellwig
2009-10-20 3:40 ` Dave Chinner
2009-10-21 9:45 ` Tommy van Leeuwen
2009-10-22 8:59 ` Christoph Hellwig
2009-10-27 10:41 ` Tommy van Leeuwen
[not found] ` <89c4f90c0910280519k759230c1r7b1586932ac792f7@mail.gmail.com>
2009-10-30 10:16 ` Christoph Hellwig
2009-11-03 14:46 ` Patrick Schreurs
2009-11-14 16:21 ` Christoph Hellwig
[not found] ` <4B0A8075.8080008@news-service.com>
[not found] ` <20091211115932.GA20632@infradead.org>
[not found] ` <4B3F9F88.9030307@news-service.com>
[not found] ` <20100107110446.GA13802@discord.disaster>
[not found] ` <4B45CFAC.4000607@news-service.com>
2010-01-08 11:31 ` [PATCH] Inode reclaim fixes (was Re: 2.6.31 xfs_fs_destroy_inode: cannot reclaim) Dave Chinner
2010-01-11 20:22 ` Patrick Schreurs
2010-01-15 11:01 ` Patrick Schreurs
2010-02-01 16:52 ` Patrick Schreurs
2010-02-08 10:16 ` Patrick Schreurs
2010-02-08 19:42 ` Christoph Hellwig
2010-02-09 8:48 ` Patrick Schreurs
2010-02-09 10:31 ` Christoph Hellwig
2010-02-10 12:42 ` Patrick Schreurs
2010-02-10 14:55 ` Christoph Hellwig
2010-02-10 15:42 ` Patrick Schreurs
2010-02-10 15:47 ` Christoph Hellwig
2010-02-24 18:30 ` Patrick Schreurs
2010-02-25 23:45 ` Dave Chinner
2010-03-01 9:51 ` Christoph Hellwig
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=20091012233854.GA29446@infradead.org \
--to=hch@infradead.org \
--cc=bas@news-service.com \
--cc=patrick@news-service.com \
--cc=tommy@news-service.com \
--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 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.