aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-02-19 04:23:32 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-02-24 02:00:39 -0500
commit6437d1b0adb46f29aafcbf10950a89211028ca09 (patch)
tree3596b9ba5000ed637de0d557478886f494ee9dc0
parent8618b881e9fd0e1817ff5cb7befadd3240d54830 (diff)
f2fs: fix to do build_stat prior to the recovery procedure
At the end of the recovery procedure, write_checkpoint is called and updates the cp count which is managed by f2fs stat. But, previously build_stat() is called after the recovery procedure, which results in: BUG: unable to handle kernel NULL pointer dereference at 000000000000012c IP: [<ffffffffa03b1030>] write_checkpoint+0x720/0xbc0 [f2fs] Call Trace: [<ffffffff810a6b44>] ? mark_held_locks+0x74/0x140 [<ffffffff8109a3e0>] ? __init_waitqueue_head+0x60/0x60 [<ffffffffa03bf036>] recover_fsync_data+0x656/0xf20 [f2fs] [<ffffffff812ee3eb>] ? security_d_instantiate+0x1b/0x30 [<ffffffffa03aeb4d>] f2fs_fill_super+0x94d/0xa00 [f2fs] [<ffffffff811a9825>] mount_bdev+0x1a5/0x1f0 [<ffffffff8114915e>] ? __get_free_pages+0xe/0x40 [<ffffffffa03ae200>] ? f2fs_remount+0x130/0x130 [f2fs] [<ffffffffa03aa575>] f2fs_mount+0x15/0x20 [f2fs] [<ffffffff811aa713>] mount_fs+0x43/0x1b0 [<ffffffff811c7124>] vfs_kern_mount+0x74/0x160 [<ffffffff811c5cb1>] ? __get_fs_type+0x51/0x60 [<ffffffff811c9727>] do_mount+0x237/0xb50 [<ffffffff811c936a>] ? copy_mount_options+0x3a/0x170 So, this patche changes the order of recovery_fsync_data() and f2fs_build_stats(). Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/super.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 1a85f83abd53..475560e5ee71 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -989,28 +989,9 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
989 goto free_root_inode; 989 goto free_root_inode;
990 } 990 }
991 991
992 /* recover fsynced data */
993 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {
994 err = recover_fsync_data(sbi);
995 if (err)
996 f2fs_msg(sb, KERN_ERR,
997 "Cannot recover all fsync data errno=%ld", err);
998 }
999
1000 /*
1001 * If filesystem is not mounted as read-only then
1002 * do start the gc_thread.
1003 */
1004 if (!(sb->s_flags & MS_RDONLY)) {
1005 /* After POR, we can run background GC thread.*/
1006 err = start_gc_thread(sbi);
1007 if (err)
1008 goto free_gc;
1009 }
1010
1011 err = f2fs_build_stats(sbi); 992 err = f2fs_build_stats(sbi);
1012 if (err) 993 if (err)
1013 goto free_gc; 994 goto free_root_inode;
1014 995
1015 if (f2fs_proc_root) 996 if (f2fs_proc_root)
1016 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); 997 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
@@ -1032,17 +1013,36 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
1032 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL, 1013 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL,
1033 "%s", sb->s_id); 1014 "%s", sb->s_id);
1034 if (err) 1015 if (err)
1035 goto fail; 1016 goto free_proc;
1036 1017
1018 /* recover fsynced data */
1019 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {
1020 err = recover_fsync_data(sbi);
1021 if (err)
1022 f2fs_msg(sb, KERN_ERR,
1023 "Cannot recover all fsync data errno=%ld", err);
1024 }
1025
1026 /*
1027 * If filesystem is not mounted as read-only then
1028 * do start the gc_thread.
1029 */
1030 if (!(sb->s_flags & MS_RDONLY)) {
1031 /* After POR, we can run background GC thread.*/
1032 err = start_gc_thread(sbi);
1033 if (err)
1034 goto free_kobj;
1035 }
1037 return 0; 1036 return 0;
1038fail: 1037
1038free_kobj:
1039 kobject_del(&sbi->s_kobj);
1040free_proc:
1039 if (sbi->s_proc) { 1041 if (sbi->s_proc) {
1040 remove_proc_entry("segment_info", sbi->s_proc); 1042 remove_proc_entry("segment_info", sbi->s_proc);
1041 remove_proc_entry(sb->s_id, f2fs_proc_root); 1043 remove_proc_entry(sb->s_id, f2fs_proc_root);
1042 } 1044 }
1043 f2fs_destroy_stats(sbi); 1045 f2fs_destroy_stats(sbi);
1044free_gc:
1045 stop_gc_thread(sbi);
1046free_root_inode: 1046free_root_inode:
1047 dput(sb->s_root); 1047 dput(sb->s_root);
1048 sb->s_root = NULL; 1048 sb->s_root = NULL;