aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iget.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-12-03 06:20:25 -0500
committerNiv Sardi <xaiki@sgi.com>2008-12-03 23:39:20 -0500
commit5cafdeb2891a415a5dbf0ad80f0afedf8369e6bb (patch)
treef1d6653c4dee098e46f4bdc4ddda60cf4a6d35fd /fs/xfs/xfs_iget.c
parentccd0be6cfc6943c4e0b3e3cdb598e0b7354a2d78 (diff)
cleanup the inode reclaim path
Merge xfs_iextract and xfs_idestroy into xfs_ireclaim as they are never called individually. Also rewrite most comments in this area as they were severly out of date. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r--fs/xfs/xfs_iget.c128
1 files changed, 86 insertions, 42 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 27ec2417b852..f58e5e000fce 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -450,65 +450,109 @@ xfs_iput_new(
450 IRELE(ip); 450 IRELE(ip);
451} 451}
452 452
453
454/* 453/*
455 * This routine embodies the part of the reclaim code that pulls 454 * This is called free all the memory associated with an inode.
456 * the inode from the inode hash table and the mount structure's 455 * It must free the inode itself and any buffers allocated for
457 * inode list. 456 * if_extents/if_data and if_broot. It must also free the lock
458 * This should only be called from xfs_reclaim(). 457 * associated with the inode.
458 *
459 * Note: because we don't initialise everything on reallocation out
460 * of the zone, we must ensure we nullify everything correctly before
461 * freeing the structure.
459 */ 462 */
460void 463void
461xfs_ireclaim(xfs_inode_t *ip) 464xfs_ireclaim(
465 struct xfs_inode *ip)
462{ 466{
463 /* 467 struct xfs_mount *mp = ip->i_mount;
464 * Remove from old hash list and mount list. 468 struct xfs_perag *pag;
465 */
466 XFS_STATS_INC(xs_ig_reclaims);
467 469
468 xfs_iextract(ip); 470 XFS_STATS_INC(xs_ig_reclaims);
469 471
470 /* 472 /*
471 * Here we do a spurious inode lock in order to coordinate with inode 473 * Remove the inode from the per-AG radix tree. It doesn't matter
472 * cache radix tree lookups. This is because the lookup can reference 474 * if it was never added to it because radix_tree_delete can deal
473 * the inodes in the cache without taking references. We make that OK 475 * with that case just fine.
474 * here by ensuring that we wait until the inode is unlocked after the
475 * lookup before we go ahead and free it. We get both the ilock and
476 * the iolock because the code may need to drop the ilock one but will
477 * still hold the iolock.
478 */ 476 */
479 xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 477 pag = xfs_get_perag(mp, ip->i_ino);
478 write_lock(&pag->pag_ici_lock);
479 radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino));
480 write_unlock(&pag->pag_ici_lock);
481 xfs_put_perag(mp, pag);
480 482
481 /* 483 /*
482 * Release dquots (and their references) if any. An inode may escape 484 * Here we do an (almost) spurious inode lock in order to coordinate
483 * xfs_inactive and get here via vn_alloc->vn_reclaim path. 485 * with inode cache radix tree lookups. This is because the lookup
486 * can reference the inodes in the cache without taking references.
487 *
488 * We make that OK here by ensuring that we wait until the inode is
489 * unlocked after the lookup before we go ahead and free it. We get
490 * both the ilock and the iolock because the code may need to drop the
491 * ilock one but will still hold the iolock.
484 */ 492 */
485 XFS_QM_DQDETACH(ip->i_mount, ip); 493 xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
486
487 /* 494 /*
488 * Free all memory associated with the inode. 495 * Release dquots (and their references) if any.
489 */ 496 */
497 XFS_QM_DQDETACH(ip->i_mount, ip);
490 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 498 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
491 xfs_idestroy(ip);
492}
493 499
494/* 500 switch (ip->i_d.di_mode & S_IFMT) {
495 * This routine removes an about-to-be-destroyed inode from 501 case S_IFREG:
496 * all of the lists in which it is located with the exception 502 case S_IFDIR:
497 * of the behavior chain. 503 case S_IFLNK:
498 */ 504 xfs_idestroy_fork(ip, XFS_DATA_FORK);
499void 505 break;
500xfs_iextract( 506 }
501 xfs_inode_t *ip)
502{
503 xfs_mount_t *mp = ip->i_mount;
504 xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino);
505 507
506 write_lock(&pag->pag_ici_lock); 508 if (ip->i_afp)
507 radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino)); 509 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
508 write_unlock(&pag->pag_ici_lock);
509 xfs_put_perag(mp, pag);
510 510
511 mp->m_ireclaims++; 511#ifdef XFS_INODE_TRACE
512 ktrace_free(ip->i_trace);
513#endif
514#ifdef XFS_BMAP_TRACE
515 ktrace_free(ip->i_xtrace);
516#endif
517#ifdef XFS_BTREE_TRACE
518 ktrace_free(ip->i_btrace);
519#endif
520#ifdef XFS_RW_TRACE
521 ktrace_free(ip->i_rwtrace);
522#endif
523#ifdef XFS_ILOCK_TRACE
524 ktrace_free(ip->i_lock_trace);
525#endif
526#ifdef XFS_DIR2_TRACE
527 ktrace_free(ip->i_dir_trace);
528#endif
529 if (ip->i_itemp) {
530 /*
531 * Only if we are shutting down the fs will we see an
532 * inode still in the AIL. If it is there, we should remove
533 * it to prevent a use-after-free from occurring.
534 */
535 xfs_log_item_t *lip = &ip->i_itemp->ili_item;
536 struct xfs_ail *ailp = lip->li_ailp;
537
538 ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
539 XFS_FORCED_SHUTDOWN(ip->i_mount));
540 if (lip->li_flags & XFS_LI_IN_AIL) {
541 spin_lock(&ailp->xa_lock);
542 if (lip->li_flags & XFS_LI_IN_AIL)
543 xfs_trans_ail_delete(ailp, lip);
544 else
545 spin_unlock(&ailp->xa_lock);
546 }
547 xfs_inode_item_destroy(ip);
548 ip->i_itemp = NULL;
549 }
550 /* asserts to verify all state is correct here */
551 ASSERT(atomic_read(&ip->i_iocount) == 0);
552 ASSERT(atomic_read(&ip->i_pincount) == 0);
553 ASSERT(!spin_is_locked(&ip->i_flags_lock));
554 ASSERT(completion_done(&ip->i_flush));
555 kmem_zone_free(xfs_inode_zone, ip);
512} 556}
513 557
514/* 558/*