The patch makes s_dentry_lru and s_inode_lru be destroyed later from the workqueue. This is preparation to split unregister_shrinker(super_block::s_shrink) in two stages, and to call finalize stage from destroy_super_work(). Note, that generic filesystem shrinker unregistration is safe to be splitted in two stages right after this patch, since super_cache_count() and super_cache_scan() have a deal with s_dentry_lru and s_inode_lru only. But there are two exceptions: XFS and SHMEM, which define .nr_cached_objects() and .free_cached_objects() callbacks. These two do not allow us to do the splitting right after this patch. They touch fs-specific data, which is destroyed earlier, than destroy_super_work(). So, we can't call unregister_shrinker_delayed_finalize() from destroy_super_work() because of them, and next patches make preparations to make this possible. Signed-off-by: Kirill Tkhai <ktkhai@xxxxxxxxxxxxx> --- fs/super.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/fs/super.c b/fs/super.c index 426161360af3..457834278e37 100644 --- a/fs/super.c +++ b/fs/super.c @@ -159,6 +159,11 @@ static void destroy_super_work(struct work_struct *work) destroy_work); int i; + WARN_ON(list_lru_count(&s->s_dentry_lru)); + WARN_ON(list_lru_count(&s->s_inode_lru)); + list_lru_destroy(&s->s_dentry_lru); + list_lru_destroy(&s->s_inode_lru); + for (i = 0; i < SB_FREEZE_LEVELS; i++) percpu_free_rwsem(&s->s_writers.rw_sem[i]); kfree(s); @@ -177,8 +182,6 @@ static void destroy_unused_super(struct super_block *s) if (!s) return; up_write(&s->s_umount); - list_lru_destroy(&s->s_dentry_lru); - list_lru_destroy(&s->s_inode_lru); security_sb_free(s); put_user_ns(s->s_user_ns); kfree(s->s_subtype); @@ -283,8 +286,6 @@ static void __put_super(struct super_block *s) { if (!--s->s_count) { list_del_init(&s->s_list); - WARN_ON(s->s_dentry_lru.node); - WARN_ON(s->s_inode_lru.node); WARN_ON(!list_empty(&s->s_mounts)); security_sb_free(s); put_user_ns(s->s_user_ns); @@ -327,14 +328,6 @@ void deactivate_locked_super(struct super_block *s) unregister_shrinker(&s->s_shrink); fs->kill_sb(s); - /* - * Since list_lru_destroy() may sleep, we cannot call it from - * put_super(), where we hold the sb_lock. Therefore we destroy - * the lru lists right now. - */ - list_lru_destroy(&s->s_dentry_lru); - list_lru_destroy(&s->s_inode_lru); - put_filesystem(fs); put_super(s); } else {