aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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