diff options
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r-- | fs/xfs/xfs_iget.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index fa402a6bbbcf..6845db90818f 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -73,7 +73,6 @@ xfs_inode_alloc( | |||
73 | ASSERT(atomic_read(&ip->i_pincount) == 0); | 73 | ASSERT(atomic_read(&ip->i_pincount) == 0); |
74 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | 74 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); |
75 | ASSERT(completion_done(&ip->i_flush)); | 75 | ASSERT(completion_done(&ip->i_flush)); |
76 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | ||
77 | 76 | ||
78 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | 77 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); |
79 | 78 | ||
@@ -191,13 +190,12 @@ xfs_iget_cache_hit( | |||
191 | trace_xfs_iget_reclaim(ip); | 190 | trace_xfs_iget_reclaim(ip); |
192 | 191 | ||
193 | /* | 192 | /* |
194 | * We need to set XFS_INEW atomically with clearing the | 193 | * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode |
195 | * reclaimable tag so that we do have an indicator of the | 194 | * from stomping over us while we recycle the inode. We can't |
196 | * inode still being initialized. | 195 | * clear the radix tree reclaimable tag yet as it requires |
196 | * pag_ici_lock to be held exclusive. | ||
197 | */ | 197 | */ |
198 | ip->i_flags |= XFS_INEW; | 198 | ip->i_flags |= XFS_IRECLAIM; |
199 | ip->i_flags &= ~XFS_IRECLAIMABLE; | ||
200 | __xfs_inode_clear_reclaim_tag(mp, pag, ip); | ||
201 | 199 | ||
202 | spin_unlock(&ip->i_flags_lock); | 200 | spin_unlock(&ip->i_flags_lock); |
203 | read_unlock(&pag->pag_ici_lock); | 201 | read_unlock(&pag->pag_ici_lock); |
@@ -217,7 +215,15 @@ xfs_iget_cache_hit( | |||
217 | trace_xfs_iget_reclaim(ip); | 215 | trace_xfs_iget_reclaim(ip); |
218 | goto out_error; | 216 | goto out_error; |
219 | } | 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); | ||
220 | 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); | ||
221 | } else { | 227 | } else { |
222 | /* 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. */ |
223 | if (!igrab(inode)) { | 229 | if (!igrab(inode)) { |
@@ -375,7 +381,7 @@ xfs_iget( | |||
375 | return EINVAL; | 381 | return EINVAL; |
376 | 382 | ||
377 | /* get the perag structure and ensure that it's inode capable */ | 383 | /* get the perag structure and ensure that it's inode capable */ |
378 | pag = xfs_get_perag(mp, ino); | 384 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); |
379 | if (!pag->pagi_inodeok) | 385 | if (!pag->pagi_inodeok) |
380 | return EINVAL; | 386 | return EINVAL; |
381 | ASSERT(pag->pag_ici_init); | 387 | ASSERT(pag->pag_ici_init); |
@@ -399,7 +405,7 @@ again: | |||
399 | if (error) | 405 | if (error) |
400 | goto out_error_or_again; | 406 | goto out_error_or_again; |
401 | } | 407 | } |
402 | xfs_put_perag(mp, pag); | 408 | xfs_perag_put(pag); |
403 | 409 | ||
404 | *ipp = ip; | 410 | *ipp = ip; |
405 | 411 | ||
@@ -418,7 +424,7 @@ out_error_or_again: | |||
418 | delay(1); | 424 | delay(1); |
419 | goto again; | 425 | goto again; |
420 | } | 426 | } |
421 | xfs_put_perag(mp, pag); | 427 | xfs_perag_put(pag); |
422 | return error; | 428 | return error; |
423 | } | 429 | } |
424 | 430 | ||
@@ -489,12 +495,12 @@ xfs_ireclaim( | |||
489 | * added to the tree assert that it's been there before to catch | 495 | * added to the tree assert that it's been there before to catch |
490 | * problems with the inode life time early on. | 496 | * problems with the inode life time early on. |
491 | */ | 497 | */ |
492 | pag = xfs_get_perag(mp, ip->i_ino); | 498 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); |
493 | write_lock(&pag->pag_ici_lock); | 499 | write_lock(&pag->pag_ici_lock); |
494 | if (!radix_tree_delete(&pag->pag_ici_root, agino)) | 500 | if (!radix_tree_delete(&pag->pag_ici_root, agino)) |
495 | ASSERT(0); | 501 | ASSERT(0); |
496 | write_unlock(&pag->pag_ici_lock); | 502 | write_unlock(&pag->pag_ici_lock); |
497 | xfs_put_perag(mp, pag); | 503 | xfs_perag_put(pag); |
498 | 504 | ||
499 | /* | 505 | /* |
500 | * Here we do an (almost) spurious inode lock in order to coordinate | 506 | * Here we do an (almost) spurious inode lock in order to coordinate |