diff -urN linux-2.6.33-vserver-2.3.0.36.30.4-r1.orig//fs/xfs/linux-2.6/xfs_sync.c linux-2.6.33-vserver-2.3.0.36.30.4-r1//fs/xfs/linux-2.6/xfs_sync.c --- linux-2.6.33-vserver-2.3.0.36.30.4-r1.orig//fs/xfs/linux-2.6/xfs_sync.c 2010-02-24 18:52:17.000000000 +0000 +++ linux-2.6.33-vserver-2.3.0.36.30.4-r1//fs/xfs/linux-2.6/xfs_sync.c 2010-06-24 09:17:15.403911414 +0000 @@ -693,12 +693,12 @@ xfs_mount_t *mp = ip->i_mount; xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino); - read_lock(&pag->pag_ici_lock); + write_lock(&pag->pag_ici_lock); spin_lock(&ip->i_flags_lock); __xfs_inode_set_reclaim_tag(pag, ip); __xfs_iflags_set(ip, XFS_IRECLAIMABLE); spin_unlock(&ip->i_flags_lock); - read_unlock(&pag->pag_ici_lock); + write_unlock(&pag->pag_ici_lock); xfs_put_perag(mp, pag); } diff -urN linux-2.6.33-vserver-2.3.0.36.30.4-r1.orig//fs/xfs/xfs_iget.c linux-2.6.33-vserver-2.3.0.36.30.4-r1//fs/xfs/xfs_iget.c --- linux-2.6.33-vserver-2.3.0.36.30.4-r1.orig//fs/xfs/xfs_iget.c 2010-02-24 18:52:17.000000000 +0000 +++ linux-2.6.33-vserver-2.3.0.36.30.4-r1//fs/xfs/xfs_iget.c 2010-06-24 09:14:58.643911511 +0000 @@ -190,13 +190,12 @@ trace_xfs_iget_reclaim(ip); /* - * We need to set XFS_INEW atomically with clearing the - * reclaimable tag so that we do have an indicator of the - * inode still being initialized. + * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode + * from stomping over us while we recycle the inode. We can't + * clear the radix tree reclaimable tag yet as it requires + * pag_ici_lock to be held exclusive. */ - ip->i_flags |= XFS_INEW; - ip->i_flags &= ~XFS_IRECLAIMABLE; - __xfs_inode_clear_reclaim_tag(mp, pag, ip); + ip->i_flags |= XFS_IRECLAIM; spin_unlock(&ip->i_flags_lock); read_unlock(&pag->pag_ici_lock); @@ -216,7 +215,15 @@ trace_xfs_iget_reclaim(ip); goto out_error; } + + write_lock(&pag->pag_ici_lock); + spin_lock(&ip->i_flags_lock); + ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM); + ip->i_flags |= XFS_INEW; + __xfs_inode_clear_reclaim_tag(mp, pag, ip); inode->i_state = I_NEW; + spin_unlock(&ip->i_flags_lock); + write_unlock(&pag->pag_ici_lock); } else { /* If the VFS inode is being torn down, pause and try again. */ if (!igrab(inode)) {