aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c26
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c71
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h5
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
1485static int
1486xfs_fs_nr_cached_objects(
1487 struct super_block *sb)
1488{
1489 return xfs_reclaim_inodes_count(XFS_M(sb));
1490}
1491
1492static void
1493xfs_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
1494static const struct super_operations xfs_super_operations = { 1500static 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
1509static struct file_system_type xfs_fs_type = { 1517static 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 */
1032static int 1036void
1033xfs_reclaim_inode_shrink( 1037xfs_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; 1052int
1058 } 1053xfs_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
1070void
1071xfs_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
1079void
1080xfs_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);
43void xfs_flush_inodes(struct xfs_inode *ip); 43void xfs_flush_inodes(struct xfs_inode *ip);
44 44
45int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); 45int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
46int xfs_reclaim_inodes_count(struct xfs_mount *mp);
47void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
46 48
47void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); 49void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
48void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip); 50void __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
57void xfs_inode_shrinker_register(struct xfs_mount *mp);
58void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
59
60#endif 59#endif