iwm-overlay/sys-kernel/vserver-sources/files/2.6.33-xfs_radix_tree_fix.p...

57 lines
2.2 KiB
Diff

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)) {