[XFS] Really fix use after free in xfs_iunpin.

The previous attempts to fix the linux inode use-after-free in xfs_iunpin
simply made the problem harder to hit. We actually need complete exclusion
between xfs_reclaim and xfs_iunpin, as well as ensuring that the i_flags
are consistent during both of these functions. Introduce a new spinlock
for exclusion and the i_flags, and fix up xfs_iunpin to use igrab before
marking the inode dirty.

SGI-PV: 952967
SGI-Modid: xfs-linux-melb:xfs-kern:26964a

Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
This commit is contained in:
David Chinner
2006-09-28 11:06:03 +10:00
committed by Tim Shimmin
parent 01106eae97
commit f273ab848b
6 changed files with 35 additions and 3 deletions

View File

@ -243,7 +243,9 @@ again:
XFS_STATS_INC(xs_ig_found);
spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_IRECLAIMABLE;
spin_unlock(&ip->i_flags_lock);
version = ih->ih_version;
read_unlock(&ih->ih_lock);
xfs_ihash_promote(ih, ip, version);
@ -297,7 +299,9 @@ finish_inode:
if (lock_flags != 0)
xfs_ilock(ip, lock_flags);
spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_ISTALE;
spin_unlock(&ip->i_flags_lock);
vn_trace_exit(vp, "xfs_iget.found",
(inst_t *)__return_address);
@ -367,7 +371,9 @@ finish_inode:
ih->ih_next = ip;
ip->i_udquot = ip->i_gdquot = NULL;
ih->ih_version++;
spin_lock(&ip->i_flags_lock);
ip->i_flags |= XFS_INEW;
spin_unlock(&ip->i_flags_lock);
write_unlock(&ih->ih_lock);