diff options
author | Dave Chinner <dchinner@redhat.com> | 2022-03-30 03:21:59 +0200 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2022-03-30 03:21:59 +0200 |
commit | d2d7c0473586d2f22e85d615275f34cf19f94447 (patch) | |
tree | d1eac5348d5a8c6a705b0d94543355c2ec059ee0 /fs/xfs/xfs_inode_item.h | |
parent | xfs: don't report reserved bnobt space as available (diff) | |
download | linux-d2d7c0473586d2f22e85d615275f34cf19f94447.tar.xz linux-d2d7c0473586d2f22e85d615275f34cf19f94447.zip |
xfs: aborting inodes on shutdown may need buffer lock
Most buffer io list operations are run with the bp->b_lock held, but
xfs_iflush_abort() can be called without the buffer lock being held
resulting in inodes being removed from the buffer list while other
list operations are occurring. This causes problems with corrupted
bp->b_io_list inode lists during filesystem shutdown, leading to
traversals that never end, double removals from the AIL, etc.
Fix this by passing the buffer to xfs_iflush_abort() if we have
it locked. If the inode is attached to the buffer, we're going to
have to remove it from the buffer list and we'd have to get the
buffer off the inode log item to do that anyway.
If we don't have a buffer passed in (e.g. from xfs_reclaim_inode())
then we can determine if the inode has a log item and if it is
attached to a buffer before we do anything else. If it does have an
attached buffer, we can lock it safely (because the inode has a
reference to it) and then perform the inode abort.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_inode_item.h')
-rw-r--r-- | fs/xfs/xfs_inode_item.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 1a302000d604..bbd836a44ff0 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -44,6 +44,7 @@ static inline int xfs_inode_clean(struct xfs_inode *ip) extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *); extern void xfs_inode_item_destroy(struct xfs_inode *); extern void xfs_iflush_abort(struct xfs_inode *); +extern void xfs_iflush_shutdown_abort(struct xfs_inode *); extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, struct xfs_inode_log_format *); |