aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iget.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r--fs/xfs/xfs_iget.c30
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