From bae01eda8e6ef3ba66ee068d91fd4dd31a649c6f Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 30 Nov 2017 19:28:20 +0800 Subject: [PATCH] f2fs: fix error handling in fill_super In fill_super, if we fail to call f2fs_build_stats(), it needs to detach from global f2fs shrink list, otherwise once system starts to shrink slab cache, we will encounter below panic: BUG: unable to handle kernel paging request at 00007d35 Oops: 0002 [#1] PREEMPT SMP EIP: __lock_acquire+0x70/0x12c0 Call Trace: lock_acquire+0xae/0x220 mutex_trylock+0xc5/0xf0 f2fs_shrink_count+0x32/0xb0 [f2fs] shrink_slab+0xf1/0x5b0 drop_slab_node+0x35/0x60 drop_slab+0xf/0x20 drop_caches_sysctl_handler+0x79/0xc0 proc_sys_call_handler+0xa4/0xc0 proc_sys_write+0x1f/0x30 __vfs_write+0x24/0x150 SyS_write+0x44/0x90 do_fast_syscall_32+0xa1/0x1ca entry_SYSENTER_32+0x4c/0x7b In addition, this patch relocates f2fs_join_shrinker in fill_super to avoid unneeded error handling of it. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2fabb131d385..f56230759b38 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2615,18 +2615,16 @@ try_onemore: goto free_nm; } - f2fs_join_shrinker(sbi); - err = f2fs_build_stats(sbi); if (err) - goto free_nm; + goto free_node_inode; /* read root inode and dentry */ root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); if (IS_ERR(root)) { f2fs_msg(sb, KERN_ERR, "Failed to read root inode"); err = PTR_ERR(root); - goto free_node_inode; + goto free_stats; } if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { iput(root); @@ -2722,6 +2720,8 @@ skip_recovery: sbi->valid_super_block ? 1 : 2, err); } + f2fs_join_shrinker(sbi); + f2fs_msg(sbi->sb, KERN_NOTICE, "Mounted with checkpoint version = %llx", cur_cp_version(F2FS_CKPT(sbi))); f2fs_update_time(sbi, CP_TIME); @@ -2748,14 +2748,12 @@ free_sysfs: free_root_inode: dput(sb->s_root); sb->s_root = NULL; -free_node_inode: - truncate_inode_pages_final(NODE_MAPPING(sbi)); - mutex_lock(&sbi->umount_mutex); - release_ino_entry(sbi, true); - f2fs_leave_shrinker(sbi); - iput(sbi->node_inode); - mutex_unlock(&sbi->umount_mutex); +free_stats: f2fs_destroy_stats(sbi); +free_node_inode: + release_ino_entry(sbi, true); + truncate_inode_pages_final(NODE_MAPPING(sbi)); + iput(sbi->node_inode); free_nm: destroy_node_manager(sbi); free_sm: