Skip to content

Commit

Permalink
xfs: check for stale inode before acquiring iflock on push
Browse files Browse the repository at this point in the history
An inode in the AIL can be flush locked and marked stale if
a cluster free transaction occurs at the right time. The
inode item is then marked as flushing, which causes xfsaild
to spin and leaves the filesystem stalled. This is
reproduced by running xfstests 273 in a loop for an
extended period of time.

Check for stale inodes before the flush lock. This marks
the inode as pinned, leads to a log flush and allows the
filesystem to proceed.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
  • Loading branch information
Brian Foster authored and Ben Myers committed Jun 21, 2012
1 parent 51c8422 commit 76e8f13
Showing 1 changed file with 8 additions and 9 deletions.
17 changes: 8 additions & 9 deletions fs/xfs/xfs_inode_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,14 @@ xfs_inode_item_push(
goto out_unlock;
}

/*
* Stale inode items should force out the iclog.
*/
if (ip->i_flags & XFS_ISTALE) {
rval = XFS_ITEM_PINNED;
goto out_unlock;
}

/*
* Someone else is already flushing the inode. Nothing we can do
* here but wait for the flush to finish and remove the item from
Expand All @@ -514,15 +522,6 @@ xfs_inode_item_push(
goto out_unlock;
}

/*
* Stale inode items should force out the iclog.
*/
if (ip->i_flags & XFS_ISTALE) {
xfs_ifunlock(ip);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return XFS_ITEM_PINNED;
}

ASSERT(iip->ili_fields != 0 || XFS_FORCED_SHUTDOWN(ip->i_mount));
ASSERT(iip->ili_logged == 0 || XFS_FORCED_SHUTDOWN(ip->i_mount));

Expand Down

0 comments on commit 76e8f13

Please sign in to comment.