summary refs log tree commit diff
path: root/fs/xfs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-02-10 18:36:04 +1100
committerTim Shimmin <tes@sgi.com>2007-02-10 18:36:04 +1100
commitf74eaf59b36c0ad01f416b567f89c737bbf82bae (patch)
tree2420bc97336a79b317b461cb7ece9f5bc40d8aec /fs/xfs
parente5889e90dda328443161e9512f1123c9814d03de (diff)
downloadlinux-f74eaf59b36c0ad01f416b567f89c737bbf82bae.tar.gz
[XFS] Fix inode log item use-after-free on forced shutdown
SGI-PV: 959388
SGI-Modid: xfs-linux-melb:xfs-kern:27805a

Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_inode.c22
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(
 	ktrace_free(ip->i_dir_trace);
 #endif
 	if (ip->i_itemp) {
-		/* XXXdpd should be able to assert this but shutdown
-		 * is leaving the AIL behind. */
-		ASSERT(((ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL) == 0) ||
-		       XFS_FORCED_SHUTDOWN(ip->i_mount));
+		/*
+		 * Only if we are shutting down the fs will we see an
+		 * inode still in the AIL. If it is there, we should remove
+		 * it to prevent a use-after-free from occurring.
+		 */
+		xfs_mount_t	*mp = ip->i_mount;
+		xfs_log_item_t	*lip = &ip->i_itemp->ili_item;
+		int		s;
+
+		ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
+				       XFS_FORCED_SHUTDOWN(ip->i_mount));
+		if (lip->li_flags & XFS_LI_IN_AIL) {
+			AIL_LOCK(mp, s);
+			if (lip->li_flags & XFS_LI_IN_AIL)
+				xfs_trans_delete_ail(mp, lip, s);
+			else
+				AIL_UNLOCK(mp, s);
+		}
 		xfs_inode_item_destroy(ip);
 	}
 	kmem_zone_free(xfs_inode_zone, ip);