diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 26 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 71 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 5 |
3 files changed, 46 insertions, 56 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index a1a881e68a9a..a9c6ccff7b48 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1025,11 +1025,6 @@ xfs_fs_put_super( | |||
1025 | { | 1025 | { |
1026 | struct xfs_mount *mp = XFS_M(sb); | 1026 | struct xfs_mount *mp = XFS_M(sb); |
1027 | 1027 | ||
1028 | /* | ||
1029 | * Unregister the memory shrinker before we tear down the mount | ||
1030 | * structure so we don't have memory reclaim racing with us here. | ||
1031 | */ | ||
1032 | xfs_inode_shrinker_unregister(mp); | ||
1033 | xfs_syncd_stop(mp); | 1028 | xfs_syncd_stop(mp); |
1034 | 1029 | ||
1035 | /* | 1030 | /* |
@@ -1416,8 +1411,6 @@ xfs_fs_fill_super( | |||
1416 | if (error) | 1411 | if (error) |
1417 | goto out_filestream_unmount; | 1412 | goto out_filestream_unmount; |
1418 | 1413 | ||
1419 | xfs_inode_shrinker_register(mp); | ||
1420 | |||
1421 | error = xfs_mountfs(mp); | 1414 | error = xfs_mountfs(mp); |
1422 | if (error) | 1415 | if (error) |
1423 | goto out_syncd_stop; | 1416 | goto out_syncd_stop; |
@@ -1440,7 +1433,6 @@ xfs_fs_fill_super( | |||
1440 | return 0; | 1433 | return 0; |
1441 | 1434 | ||
1442 | out_syncd_stop: | 1435 | out_syncd_stop: |
1443 | xfs_inode_shrinker_unregister(mp); | ||
1444 | xfs_syncd_stop(mp); | 1436 | xfs_syncd_stop(mp); |
1445 | out_filestream_unmount: | 1437 | out_filestream_unmount: |
1446 | xfs_filestream_unmount(mp); | 1438 | xfs_filestream_unmount(mp); |
@@ -1465,7 +1457,6 @@ xfs_fs_fill_super( | |||
1465 | } | 1457 | } |
1466 | 1458 | ||
1467 | fail_unmount: | 1459 | fail_unmount: |
1468 | xfs_inode_shrinker_unregister(mp); | ||
1469 | xfs_syncd_stop(mp); | 1460 | xfs_syncd_stop(mp); |
1470 | 1461 | ||
1471 | /* | 1462 | /* |
@@ -1491,6 +1482,21 @@ xfs_fs_mount( | |||
1491 | return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); | 1482 | return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); |
1492 | } | 1483 | } |
1493 | 1484 | ||
1485 | static int | ||
1486 | xfs_fs_nr_cached_objects( | ||
1487 | struct super_block *sb) | ||
1488 | { | ||
1489 | return xfs_reclaim_inodes_count(XFS_M(sb)); | ||
1490 | } | ||
1491 | |||
1492 | static void | ||
1493 | xfs_fs_free_cached_objects( | ||
1494 | struct super_block *sb, | ||
1495 | int nr_to_scan) | ||
1496 | { | ||
1497 | xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan); | ||
1498 | } | ||
1499 | |||
1494 | static const struct super_operations xfs_super_operations = { | 1500 | static const struct super_operations xfs_super_operations = { |
1495 | .alloc_inode = xfs_fs_alloc_inode, | 1501 | .alloc_inode = xfs_fs_alloc_inode, |
1496 | .destroy_inode = xfs_fs_destroy_inode, | 1502 | .destroy_inode = xfs_fs_destroy_inode, |
@@ -1504,6 +1510,8 @@ static const struct super_operations xfs_super_operations = { | |||
1504 | .statfs = xfs_fs_statfs, | 1510 | .statfs = xfs_fs_statfs, |
1505 | .remount_fs = xfs_fs_remount, | 1511 | .remount_fs = xfs_fs_remount, |
1506 | .show_options = xfs_fs_show_options, | 1512 | .show_options = xfs_fs_show_options, |
1513 | .nr_cached_objects = xfs_fs_nr_cached_objects, | ||
1514 | .free_cached_objects = xfs_fs_free_cached_objects, | ||
1507 | }; | 1515 | }; |
1508 | 1516 | ||
1509 | static struct file_system_type xfs_fs_type = { | 1517 | static struct file_system_type xfs_fs_type = { |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 8ecad5ff9f9b..9bd7e895a4e2 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -179,6 +179,8 @@ restart: | |||
179 | if (error == EFSCORRUPTED) | 179 | if (error == EFSCORRUPTED) |
180 | break; | 180 | break; |
181 | 181 | ||
182 | cond_resched(); | ||
183 | |||
182 | } while (nr_found && !done); | 184 | } while (nr_found && !done); |
183 | 185 | ||
184 | if (skipped) { | 186 | if (skipped) { |
@@ -986,6 +988,8 @@ restart: | |||
986 | 988 | ||
987 | *nr_to_scan -= XFS_LOOKUP_BATCH; | 989 | *nr_to_scan -= XFS_LOOKUP_BATCH; |
988 | 990 | ||
991 | cond_resched(); | ||
992 | |||
989 | } while (nr_found && !done && *nr_to_scan > 0); | 993 | } while (nr_found && !done && *nr_to_scan > 0); |
990 | 994 | ||
991 | if (trylock && !done) | 995 | if (trylock && !done) |
@@ -1003,7 +1007,7 @@ restart: | |||
1003 | * ensure that when we get more reclaimers than AGs we block rather | 1007 | * ensure that when we get more reclaimers than AGs we block rather |
1004 | * than spin trying to execute reclaim. | 1008 | * than spin trying to execute reclaim. |
1005 | */ | 1009 | */ |
1006 | if (trylock && skipped && *nr_to_scan > 0) { | 1010 | if (skipped && (flags & SYNC_WAIT) && *nr_to_scan > 0) { |
1007 | trylock = 0; | 1011 | trylock = 0; |
1008 | goto restart; | 1012 | goto restart; |
1009 | } | 1013 | } |
@@ -1021,44 +1025,38 @@ xfs_reclaim_inodes( | |||
1021 | } | 1025 | } |
1022 | 1026 | ||
1023 | /* | 1027 | /* |
1024 | * Inode cache shrinker. | 1028 | * Scan a certain number of inodes for reclaim. |
1025 | * | 1029 | * |
1026 | * When called we make sure that there is a background (fast) inode reclaim in | 1030 | * When called we make sure that there is a background (fast) inode reclaim in |
1027 | * progress, while we will throttle the speed of reclaim via doiing synchronous | 1031 | * progress, while we will throttle the speed of reclaim via doing synchronous |
1028 | * reclaim of inodes. That means if we come across dirty inodes, we wait for | 1032 | * reclaim of inodes. That means if we come across dirty inodes, we wait for |
1029 | * them to be cleaned, which we hope will not be very long due to the | 1033 | * them to be cleaned, which we hope will not be very long due to the |
1030 | * background walker having already kicked the IO off on those dirty inodes. | 1034 | * background walker having already kicked the IO off on those dirty inodes. |
1031 | */ | 1035 | */ |
1032 | static int | 1036 | void |
1033 | xfs_reclaim_inode_shrink( | 1037 | xfs_reclaim_inodes_nr( |
1034 | struct shrinker *shrink, | 1038 | struct xfs_mount *mp, |
1035 | struct shrink_control *sc) | 1039 | int nr_to_scan) |
1036 | { | 1040 | { |
1037 | struct xfs_mount *mp; | 1041 | /* kick background reclaimer and push the AIL */ |
1038 | struct xfs_perag *pag; | 1042 | xfs_syncd_queue_reclaim(mp); |
1039 | xfs_agnumber_t ag; | 1043 | xfs_ail_push_all(mp->m_ail); |
1040 | int reclaimable; | ||
1041 | int nr_to_scan = sc->nr_to_scan; | ||
1042 | gfp_t gfp_mask = sc->gfp_mask; | ||
1043 | |||
1044 | mp = container_of(shrink, struct xfs_mount, m_inode_shrink); | ||
1045 | if (nr_to_scan) { | ||
1046 | /* kick background reclaimer and push the AIL */ | ||
1047 | xfs_syncd_queue_reclaim(mp); | ||
1048 | xfs_ail_push_all(mp->m_ail); | ||
1049 | 1044 | ||
1050 | if (!(gfp_mask & __GFP_FS)) | 1045 | xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, &nr_to_scan); |
1051 | return -1; | 1046 | } |
1052 | 1047 | ||
1053 | xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, | 1048 | /* |
1054 | &nr_to_scan); | 1049 | * Return the number of reclaimable inodes in the filesystem for |
1055 | /* terminate if we don't exhaust the scan */ | 1050 | * the shrinker to determine how much to reclaim. |
1056 | if (nr_to_scan > 0) | 1051 | */ |
1057 | return -1; | 1052 | int |
1058 | } | 1053 | xfs_reclaim_inodes_count( |
1054 | struct xfs_mount *mp) | ||
1055 | { | ||
1056 | struct xfs_perag *pag; | ||
1057 | xfs_agnumber_t ag = 0; | ||
1058 | int reclaimable = 0; | ||
1059 | 1059 | ||
1060 | reclaimable = 0; | ||
1061 | ag = 0; | ||
1062 | while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { | 1060 | while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { |
1063 | ag = pag->pag_agno + 1; | 1061 | ag = pag->pag_agno + 1; |
1064 | reclaimable += pag->pag_ici_reclaimable; | 1062 | reclaimable += pag->pag_ici_reclaimable; |
@@ -1067,18 +1065,3 @@ xfs_reclaim_inode_shrink( | |||
1067 | return reclaimable; | 1065 | return reclaimable; |
1068 | } | 1066 | } |
1069 | 1067 | ||
1070 | void | ||
1071 | xfs_inode_shrinker_register( | ||
1072 | struct xfs_mount *mp) | ||
1073 | { | ||
1074 | mp->m_inode_shrink.shrink = xfs_reclaim_inode_shrink; | ||
1075 | mp->m_inode_shrink.seeks = DEFAULT_SEEKS; | ||
1076 | register_shrinker(&mp->m_inode_shrink); | ||
1077 | } | ||
1078 | |||
1079 | void | ||
1080 | xfs_inode_shrinker_unregister( | ||
1081 | struct xfs_mount *mp) | ||
1082 | { | ||
1083 | unregister_shrinker(&mp->m_inode_shrink); | ||
1084 | } | ||
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index e3a6ad27415f..2e1568597764 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -43,6 +43,8 @@ void xfs_quiesce_attr(struct xfs_mount *mp); | |||
43 | void xfs_flush_inodes(struct xfs_inode *ip); | 43 | void xfs_flush_inodes(struct xfs_inode *ip); |
44 | 44 | ||
45 | int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); | 45 | int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); |
46 | int xfs_reclaim_inodes_count(struct xfs_mount *mp); | ||
47 | void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan); | ||
46 | 48 | ||
47 | void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); | 49 | void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); |
48 | void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip); | 50 | void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip); |
@@ -54,7 +56,4 @@ int xfs_inode_ag_iterator(struct xfs_mount *mp, | |||
54 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), | 56 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), |
55 | int flags); | 57 | int flags); |
56 | 58 | ||
57 | void xfs_inode_shrinker_register(struct xfs_mount *mp); | ||
58 | void xfs_inode_shrinker_unregister(struct xfs_mount *mp); | ||
59 | |||
60 | #endif | 59 | #endif |