Merge branch 'master' into for-2.6.35
[safe/jmp/linux-2.6] / fs / xfs / xfs_iget.c
index e281eb4..6845db9 100644 (file)
@@ -190,13 +190,12 @@ xfs_iget_cache_hit(
                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 @@ xfs_iget_cache_hit(
                        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)) {