Commit bae01eda authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

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: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 4e6aad29
...@@ -2615,18 +2615,16 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2615,18 +2615,16 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
goto free_nm; goto free_nm;
} }
f2fs_join_shrinker(sbi);
err = f2fs_build_stats(sbi); err = f2fs_build_stats(sbi);
if (err) if (err)
goto free_nm; goto free_node_inode;
/* read root inode and dentry */ /* read root inode and dentry */
root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); root = f2fs_iget(sb, F2FS_ROOT_INO(sbi));
if (IS_ERR(root)) { if (IS_ERR(root)) {
f2fs_msg(sb, KERN_ERR, "Failed to read root inode"); f2fs_msg(sb, KERN_ERR, "Failed to read root inode");
err = PTR_ERR(root); err = PTR_ERR(root);
goto free_node_inode; goto free_stats;
} }
if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
iput(root); iput(root);
...@@ -2722,6 +2720,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2722,6 +2720,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
sbi->valid_super_block ? 1 : 2, err); sbi->valid_super_block ? 1 : 2, err);
} }
f2fs_join_shrinker(sbi);
f2fs_msg(sbi->sb, KERN_NOTICE, "Mounted with checkpoint version = %llx", f2fs_msg(sbi->sb, KERN_NOTICE, "Mounted with checkpoint version = %llx",
cur_cp_version(F2FS_CKPT(sbi))); cur_cp_version(F2FS_CKPT(sbi)));
f2fs_update_time(sbi, CP_TIME); f2fs_update_time(sbi, CP_TIME);
...@@ -2748,14 +2748,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2748,14 +2748,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
free_root_inode: free_root_inode:
dput(sb->s_root); dput(sb->s_root);
sb->s_root = NULL; sb->s_root = NULL;
free_stats:
f2fs_destroy_stats(sbi);
free_node_inode: free_node_inode:
truncate_inode_pages_final(NODE_MAPPING(sbi));
mutex_lock(&sbi->umount_mutex);
release_ino_entry(sbi, true); release_ino_entry(sbi, true);
f2fs_leave_shrinker(sbi); truncate_inode_pages_final(NODE_MAPPING(sbi));
iput(sbi->node_inode); iput(sbi->node_inode);
mutex_unlock(&sbi->umount_mutex);
f2fs_destroy_stats(sbi);
free_nm: free_nm:
destroy_node_manager(sbi); destroy_node_manager(sbi);
free_sm: free_sm:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment