diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index cd518581a3bb..e42418f92215 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2707,10 +2707,24 @@ xfs_idestroy( | |||
2707 | ktrace_free(ip->i_dir_trace); | 2707 | ktrace_free(ip->i_dir_trace); |
2708 | #endif | 2708 | #endif |
2709 | if (ip->i_itemp) { | 2709 | if (ip->i_itemp) { |
2710 | /* XXXdpd should be able to assert this but shutdown | 2710 | /* |
2711 | * is leaving the AIL behind. */ | 2711 | * Only if we are shutting down the fs will we see an |
2712 | ASSERT(((ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL) == 0) || | 2712 | * inode still in the AIL. If it is there, we should remove |
2713 | XFS_FORCED_SHUTDOWN(ip->i_mount)); | 2713 | * it to prevent a use-after-free from occurring. |
2714 | */ | ||
2715 | xfs_mount_t *mp = ip->i_mount; | ||
2716 | xfs_log_item_t *lip = &ip->i_itemp->ili_item; | ||
2717 | int s; | ||
2718 | |||
2719 | ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || | ||
2720 | XFS_FORCED_SHUTDOWN(ip->i_mount)); | ||
2721 | if (lip->li_flags & XFS_LI_IN_AIL) { | ||
2722 | AIL_LOCK(mp, s); | ||
2723 | if (lip->li_flags & XFS_LI_IN_AIL) | ||
2724 | xfs_trans_delete_ail(mp, lip, s); | ||
2725 | else | ||
2726 | AIL_UNLOCK(mp, s); | ||
2727 | } | ||
2714 | xfs_inode_item_destroy(ip); | 2728 | xfs_inode_item_destroy(ip); |
2715 | } | 2729 | } |
2716 | kmem_zone_free(xfs_inode_zone, ip); | 2730 | kmem_zone_free(xfs_inode_zone, ip); |