ocfs2: fix crash when initialize filecheck kobj fails
authorJoseph Qi <joseph.qi@linux.alibaba.com>
Wed, 16 Mar 2022 23:15:09 +0000 (16:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 17 Mar 2022 18:02:13 +0000 (11:02 -0700)
Once s_root is set, genric_shutdown_super() will be called if
fill_super() fails.  That means, we will call ocfs2_dismount_volume()
twice in such case, which can lead to kernel crash.

Fix this issue by initializing filecheck kobj before setting s_root.

Link: https://lkml.kernel.org/r/20220310081930.86305-1-joseph.qi@linux.alibaba.com
Fixes: 5f483c4abb50 ("ocfs2: add kobject for online file check")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/ocfs2/super.c

index 2772dec..8bde30f 100644 (file)
@@ -1105,17 +1105,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
                goto read_super_error;
        }
 
-       root = d_make_root(inode);
-       if (!root) {
-               status = -ENOMEM;
-               mlog_errno(status);
-               goto read_super_error;
-       }
-
-       sb->s_root = root;
-
-       ocfs2_complete_mount_recovery(osb);
-
        osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
                                                &ocfs2_kset->kobj);
        if (!osb->osb_dev_kset) {
@@ -1133,6 +1122,17 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
                goto read_super_error;
        }
 
+       root = d_make_root(inode);
+       if (!root) {
+               status = -ENOMEM;
+               mlog_errno(status);
+               goto read_super_error;
+       }
+
+       sb->s_root = root;
+
+       ocfs2_complete_mount_recovery(osb);
+
        if (ocfs2_mount_local(osb))
                snprintf(nodestr, sizeof(nodestr), "local");
        else