diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 2 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 62 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_mount.h | 2 |
4 files changed, 15 insertions, 53 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index f2d1718c9165..80938c736c27 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -1883,7 +1883,6 @@ init_xfs_fs(void) | |||
| 1883 | goto out_cleanup_procfs; | 1883 | goto out_cleanup_procfs; |
| 1884 | 1884 | ||
| 1885 | vfs_initquota(); | 1885 | vfs_initquota(); |
| 1886 | xfs_inode_shrinker_init(); | ||
| 1887 | 1886 | ||
| 1888 | error = register_filesystem(&xfs_fs_type); | 1887 | error = register_filesystem(&xfs_fs_type); |
| 1889 | if (error) | 1888 | if (error) |
| @@ -1911,7 +1910,6 @@ exit_xfs_fs(void) | |||
| 1911 | { | 1910 | { |
| 1912 | vfs_exitquota(); | 1911 | vfs_exitquota(); |
| 1913 | unregister_filesystem(&xfs_fs_type); | 1912 | unregister_filesystem(&xfs_fs_type); |
| 1914 | xfs_inode_shrinker_destroy(); | ||
| 1915 | xfs_sysctl_unregister(); | 1913 | xfs_sysctl_unregister(); |
| 1916 | xfs_cleanup_procfs(); | 1914 | xfs_cleanup_procfs(); |
| 1917 | xfs_buf_terminate(); | 1915 | xfs_buf_terminate(); |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index be375827af98..f433819611cb 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
| @@ -828,14 +828,7 @@ xfs_reclaim_inodes( | |||
| 828 | 828 | ||
| 829 | /* | 829 | /* |
| 830 | * Shrinker infrastructure. | 830 | * Shrinker infrastructure. |
| 831 | * | ||
| 832 | * This is all far more complex than it needs to be. It adds a global list of | ||
| 833 | * mounts because the shrinkers can only call a global context. We need to make | ||
| 834 | * the shrinkers pass a context to avoid the need for global state. | ||
| 835 | */ | 831 | */ |
| 836 | static LIST_HEAD(xfs_mount_list); | ||
| 837 | static struct rw_semaphore xfs_mount_list_lock; | ||
| 838 | |||
| 839 | static int | 832 | static int |
| 840 | xfs_reclaim_inode_shrink( | 833 | xfs_reclaim_inode_shrink( |
| 841 | struct shrinker *shrink, | 834 | struct shrinker *shrink, |
| @@ -847,65 +840,38 @@ xfs_reclaim_inode_shrink( | |||
| 847 | xfs_agnumber_t ag; | 840 | xfs_agnumber_t ag; |
| 848 | int reclaimable = 0; | 841 | int reclaimable = 0; |
| 849 | 842 | ||
| 843 | mp = container_of(shrink, struct xfs_mount, m_inode_shrink); | ||
| 850 | if (nr_to_scan) { | 844 | if (nr_to_scan) { |
| 851 | if (!(gfp_mask & __GFP_FS)) | 845 | if (!(gfp_mask & __GFP_FS)) |
| 852 | return -1; | 846 | return -1; |
| 853 | 847 | ||
| 854 | down_read(&xfs_mount_list_lock); | 848 | xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0, |
| 855 | list_for_each_entry(mp, &xfs_mount_list, m_mplist) { | ||
| 856 | xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0, | ||
| 857 | XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan); | 849 | XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan); |
| 858 | if (nr_to_scan <= 0) | 850 | /* if we don't exhaust the scan, don't bother coming back */ |
| 859 | break; | 851 | if (nr_to_scan > 0) |
| 860 | } | 852 | return -1; |
| 861 | up_read(&xfs_mount_list_lock); | 853 | } |
| 862 | } | ||
| 863 | 854 | ||
| 864 | down_read(&xfs_mount_list_lock); | 855 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { |
| 865 | list_for_each_entry(mp, &xfs_mount_list, m_mplist) { | 856 | pag = xfs_perag_get(mp, ag); |
| 866 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { | 857 | reclaimable += pag->pag_ici_reclaimable; |
| 867 | pag = xfs_perag_get(mp, ag); | 858 | xfs_perag_put(pag); |
| 868 | reclaimable += pag->pag_ici_reclaimable; | ||
| 869 | xfs_perag_put(pag); | ||
| 870 | } | ||
| 871 | } | 859 | } |
| 872 | up_read(&xfs_mount_list_lock); | ||
| 873 | return reclaimable; | 860 | return reclaimable; |
| 874 | } | 861 | } |
| 875 | 862 | ||
| 876 | static struct shrinker xfs_inode_shrinker = { | ||
| 877 | .shrink = xfs_reclaim_inode_shrink, | ||
| 878 | .seeks = DEFAULT_SEEKS, | ||
| 879 | }; | ||
| 880 | |||
| 881 | void __init | ||
| 882 | xfs_inode_shrinker_init(void) | ||
| 883 | { | ||
| 884 | init_rwsem(&xfs_mount_list_lock); | ||
| 885 | register_shrinker(&xfs_inode_shrinker); | ||
| 886 | } | ||
| 887 | |||
| 888 | void | ||
| 889 | xfs_inode_shrinker_destroy(void) | ||
| 890 | { | ||
| 891 | ASSERT(list_empty(&xfs_mount_list)); | ||
| 892 | unregister_shrinker(&xfs_inode_shrinker); | ||
| 893 | } | ||
| 894 | |||
| 895 | void | 863 | void |
| 896 | xfs_inode_shrinker_register( | 864 | xfs_inode_shrinker_register( |
| 897 | struct xfs_mount *mp) | 865 | struct xfs_mount *mp) |
| 898 | { | 866 | { |
| 899 | down_write(&xfs_mount_list_lock); | 867 | mp->m_inode_shrink.shrink = xfs_reclaim_inode_shrink; |
| 900 | list_add_tail(&mp->m_mplist, &xfs_mount_list); | 868 | mp->m_inode_shrink.seeks = DEFAULT_SEEKS; |
| 901 | up_write(&xfs_mount_list_lock); | 869 | register_shrinker(&mp->m_inode_shrink); |
| 902 | } | 870 | } |
| 903 | 871 | ||
| 904 | void | 872 | void |
| 905 | xfs_inode_shrinker_unregister( | 873 | xfs_inode_shrinker_unregister( |
| 906 | struct xfs_mount *mp) | 874 | struct xfs_mount *mp) |
| 907 | { | 875 | { |
| 908 | down_write(&xfs_mount_list_lock); | 876 | unregister_shrinker(&mp->m_inode_shrink); |
| 909 | list_del(&mp->m_mplist); | ||
| 910 | up_write(&xfs_mount_list_lock); | ||
| 911 | } | 877 | } |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index cdcbaaca9880..e28139aaa4aa 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
| @@ -55,8 +55,6 @@ int xfs_inode_ag_iterator(struct xfs_mount *mp, | |||
| 55 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), | 55 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), |
| 56 | int flags, int tag, int write_lock, int *nr_to_scan); | 56 | int flags, int tag, int write_lock, int *nr_to_scan); |
| 57 | 57 | ||
| 58 | void xfs_inode_shrinker_init(void); | ||
| 59 | void xfs_inode_shrinker_destroy(void); | ||
| 60 | void xfs_inode_shrinker_register(struct xfs_mount *mp); | 58 | void xfs_inode_shrinker_register(struct xfs_mount *mp); |
| 61 | void xfs_inode_shrinker_unregister(struct xfs_mount *mp); | 59 | void xfs_inode_shrinker_unregister(struct xfs_mount *mp); |
| 62 | 60 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 1d2c7eed4eda..5761087ee8ea 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
| @@ -259,7 +259,7 @@ typedef struct xfs_mount { | |||
| 259 | wait_queue_head_t m_wait_single_sync_task; | 259 | wait_queue_head_t m_wait_single_sync_task; |
| 260 | __int64_t m_update_flags; /* sb flags we need to update | 260 | __int64_t m_update_flags; /* sb flags we need to update |
| 261 | on the next remount,rw */ | 261 | on the next remount,rw */ |
| 262 | struct list_head m_mplist; /* inode shrinker mount list */ | 262 | struct shrinker m_inode_shrink; /* inode reclaim shrinker */ |
| 263 | } xfs_mount_t; | 263 | } xfs_mount_t; |
| 264 | 264 | ||
| 265 | /* | 265 | /* |
