diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 754bc591a247..37d33254981d 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -837,8 +837,12 @@ xfs_reclaim_inodes_ag( | |||
837 | int error = 0; | 837 | int error = 0; |
838 | int last_error = 0; | 838 | int last_error = 0; |
839 | xfs_agnumber_t ag; | 839 | xfs_agnumber_t ag; |
840 | int trylock = flags & SYNC_TRYLOCK; | ||
841 | int skipped; | ||
840 | 842 | ||
843 | restart: | ||
841 | ag = 0; | 844 | ag = 0; |
845 | skipped = 0; | ||
842 | while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { | 846 | while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { |
843 | unsigned long first_index = 0; | 847 | unsigned long first_index = 0; |
844 | int done = 0; | 848 | int done = 0; |
@@ -846,6 +850,15 @@ xfs_reclaim_inodes_ag( | |||
846 | 850 | ||
847 | ag = pag->pag_agno + 1; | 851 | ag = pag->pag_agno + 1; |
848 | 852 | ||
853 | if (trylock) { | ||
854 | if (!mutex_trylock(&pag->pag_ici_reclaim_lock)) { | ||
855 | skipped++; | ||
856 | continue; | ||
857 | } | ||
858 | first_index = pag->pag_ici_reclaim_cursor; | ||
859 | } else | ||
860 | mutex_lock(&pag->pag_ici_reclaim_lock); | ||
861 | |||
849 | do { | 862 | do { |
850 | struct xfs_inode *batch[XFS_LOOKUP_BATCH]; | 863 | struct xfs_inode *batch[XFS_LOOKUP_BATCH]; |
851 | int i; | 864 | int i; |
@@ -898,8 +911,25 @@ xfs_reclaim_inodes_ag( | |||
898 | 911 | ||
899 | } while (nr_found && !done && *nr_to_scan > 0); | 912 | } while (nr_found && !done && *nr_to_scan > 0); |
900 | 913 | ||
914 | if (trylock && !done) | ||
915 | pag->pag_ici_reclaim_cursor = first_index; | ||
916 | else | ||
917 | pag->pag_ici_reclaim_cursor = 0; | ||
918 | mutex_unlock(&pag->pag_ici_reclaim_lock); | ||
901 | xfs_perag_put(pag); | 919 | xfs_perag_put(pag); |
902 | } | 920 | } |
921 | |||
922 | /* | ||
923 | * if we skipped any AG, and we still have scan count remaining, do | ||
924 | * another pass this time using blocking reclaim semantics (i.e | ||
925 | * waiting on the reclaim locks and ignoring the reclaim cursors). This | ||
926 | * ensure that when we get more reclaimers than AGs we block rather | ||
927 | * than spin trying to execute reclaim. | ||
928 | */ | ||
929 | if (trylock && skipped && *nr_to_scan > 0) { | ||
930 | trylock = 0; | ||
931 | goto restart; | ||
932 | } | ||
903 | return XFS_ERROR(last_error); | 933 | return XFS_ERROR(last_error); |
904 | } | 934 | } |
905 | 935 | ||