aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorDavid Chinner <david@fromorbit.com>2008-10-30 02:37:37 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 02:37:37 -0400
commit7a3be02baef7bdec43965103441bde5de4dd8601 (patch)
treec2f26102f69819c8910141f6e4718f1c85f92515 /fs/xfs/linux-2.6
parent396beb85311689e38634926058d9a3bb0576ca8a (diff)
[XFS] use the inode radix tree for reclaiming inodes
Use the reclaim tag to walk the radix tree and find the inodes under reclaim. This was the only user of the deleted inode list. SGI-PV: 988142 SGI-Modid: xfs-linux-melb:xfs-kern:32333a Signed-off-by: David Chinner <david@fromorbit.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c81
1 files changed, 71 insertions, 10 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 9e7f4dccab72..bbb40e27840b 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -685,32 +685,93 @@ xfs_inode_clear_reclaim_tag(
685 xfs_put_perag(mp, pag); 685 xfs_put_perag(mp, pag);
686} 686}
687 687
688int 688
689xfs_reclaim_inodes( 689STATIC void
690xfs_reclaim_inodes_ag(
690 xfs_mount_t *mp, 691 xfs_mount_t *mp,
691 int noblock, 692 int ag,
693 int noblock,
692 int mode) 694 int mode)
693{ 695{
694 xfs_inode_t *ip, *n; 696 xfs_inode_t *ip = NULL;
697 xfs_perag_t *pag = &mp->m_perag[ag];
698 int nr_found;
699 int first_index;
700 int skipped;
695 701
696restart: 702restart:
697 XFS_MOUNT_ILOCK(mp); 703 first_index = 0;
698 list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) { 704 skipped = 0;
705 do {
706 /*
707 * use a gang lookup to find the next inode in the tree
708 * as the tree is sparse and a gang lookup walks to find
709 * the number of objects requested.
710 */
711 read_lock(&pag->pag_ici_lock);
712 nr_found = radix_tree_gang_lookup_tag(&pag->pag_ici_root,
713 (void**)&ip, first_index, 1,
714 XFS_ICI_RECLAIM_TAG);
715
716 if (!nr_found) {
717 read_unlock(&pag->pag_ici_lock);
718 break;
719 }
720
721 /* update the index for the next lookup */
722 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
723
724 ASSERT(xfs_iflags_test(ip, (XFS_IRECLAIMABLE|XFS_IRECLAIM)));
725
726 /* ignore if already under reclaim */
727 if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
728 read_unlock(&pag->pag_ici_lock);
729 continue;
730 }
731
699 if (noblock) { 732 if (noblock) {
700 if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) 733 if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
734 read_unlock(&pag->pag_ici_lock);
701 continue; 735 continue;
736 }
702 if (xfs_ipincount(ip) || 737 if (xfs_ipincount(ip) ||
703 !xfs_iflock_nowait(ip)) { 738 !xfs_iflock_nowait(ip)) {
704 xfs_iunlock(ip, XFS_ILOCK_EXCL); 739 xfs_iunlock(ip, XFS_ILOCK_EXCL);
740 read_unlock(&pag->pag_ici_lock);
705 continue; 741 continue;
706 } 742 }
707 } 743 }
708 XFS_MOUNT_IUNLOCK(mp); 744 read_unlock(&pag->pag_ici_lock);
745
746 /*
747 * hmmm - this is an inode already in reclaim. Do
748 * we even bother catching it here?
749 */
709 if (xfs_reclaim_inode(ip, noblock, mode)) 750 if (xfs_reclaim_inode(ip, noblock, mode))
710 delay(1); 751 skipped++;
752 } while (nr_found);
753
754 if (skipped) {
755 delay(1);
711 goto restart; 756 goto restart;
712 } 757 }
713 XFS_MOUNT_IUNLOCK(mp); 758 return;
759
760}
761
762int
763xfs_reclaim_inodes(
764 xfs_mount_t *mp,
765 int noblock,
766 int mode)
767{
768 int i;
769
770 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
771 if (!mp->m_perag[i].pag_ici_init)
772 continue;
773 xfs_reclaim_inodes_ag(mp, i, noblock, mode);
774 }
714 return 0; 775 return 0;
715} 776}
716 777