diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_iget.c | 19 |
2 files changed, 15 insertions, 8 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index a9f6d20aff41..f9fc154d9f72 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
| @@ -688,12 +688,12 @@ xfs_inode_set_reclaim_tag( | |||
| 688 | struct xfs_perag *pag; | 688 | struct xfs_perag *pag; |
| 689 | 689 | ||
| 690 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | 690 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); |
| 691 | read_lock(&pag->pag_ici_lock); | 691 | write_lock(&pag->pag_ici_lock); |
| 692 | spin_lock(&ip->i_flags_lock); | 692 | spin_lock(&ip->i_flags_lock); |
| 693 | __xfs_inode_set_reclaim_tag(pag, ip); | 693 | __xfs_inode_set_reclaim_tag(pag, ip); |
| 694 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); | 694 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); |
| 695 | spin_unlock(&ip->i_flags_lock); | 695 | spin_unlock(&ip->i_flags_lock); |
| 696 | read_unlock(&pag->pag_ici_lock); | 696 | write_unlock(&pag->pag_ici_lock); |
| 697 | xfs_perag_put(pag); | 697 | xfs_perag_put(pag); |
| 698 | } | 698 | } |
| 699 | 699 | ||
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e281eb4a1c49..6845db90818f 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -190,13 +190,12 @@ xfs_iget_cache_hit( | |||
| 190 | trace_xfs_iget_reclaim(ip); | 190 | trace_xfs_iget_reclaim(ip); |
| 191 | 191 | ||
| 192 | /* | 192 | /* |
| 193 | * We need to set XFS_INEW atomically with clearing the | 193 | * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode |
| 194 | * reclaimable tag so that we do have an indicator of the | 194 | * from stomping over us while we recycle the inode. We can't |
| 195 | * inode still being initialized. | 195 | * clear the radix tree reclaimable tag yet as it requires |
| 196 | * pag_ici_lock to be held exclusive. | ||
| 196 | */ | 197 | */ |
| 197 | ip->i_flags |= XFS_INEW; | 198 | ip->i_flags |= XFS_IRECLAIM; |
| 198 | ip->i_flags &= ~XFS_IRECLAIMABLE; | ||
| 199 | __xfs_inode_clear_reclaim_tag(mp, pag, ip); | ||
| 200 | 199 | ||
| 201 | spin_unlock(&ip->i_flags_lock); | 200 | spin_unlock(&ip->i_flags_lock); |
| 202 | read_unlock(&pag->pag_ici_lock); | 201 | read_unlock(&pag->pag_ici_lock); |
| @@ -216,7 +215,15 @@ xfs_iget_cache_hit( | |||
| 216 | trace_xfs_iget_reclaim(ip); | 215 | trace_xfs_iget_reclaim(ip); |
| 217 | goto out_error; | 216 | goto out_error; |
| 218 | } | 217 | } |
| 218 | |||
| 219 | write_lock(&pag->pag_ici_lock); | ||
| 220 | spin_lock(&ip->i_flags_lock); | ||
| 221 | ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM); | ||
| 222 | ip->i_flags |= XFS_INEW; | ||
| 223 | __xfs_inode_clear_reclaim_tag(mp, pag, ip); | ||
| 219 | inode->i_state = I_NEW; | 224 | inode->i_state = I_NEW; |
| 225 | spin_unlock(&ip->i_flags_lock); | ||
| 226 | write_unlock(&pag->pag_ici_lock); | ||
| 220 | } else { | 227 | } else { |
| 221 | /* If the VFS inode is being torn down, pause and try again. */ | 228 | /* If the VFS inode is being torn down, pause and try again. */ |
| 222 | if (!igrab(inode)) { | 229 | if (!igrab(inode)) { |
