kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp);
 }
 
+static int init_threads(struct gfs2_sbd *sdp)
+{
+       struct task_struct *p;
+       int error = 0;
+
+       p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
+       if (IS_ERR(p)) {
+               error = PTR_ERR(p);
+               fs_err(sdp, "can't start logd thread: %d\n", error);
+               return error;
+       }
+       sdp->sd_logd_process = p;
+
+       p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
+       if (IS_ERR(p)) {
+               error = PTR_ERR(p);
+               fs_err(sdp, "can't start quotad thread: %d\n", error);
+               goto fail;
+       }
+       sdp->sd_quotad_process = p;
+       return 0;
+
+fail:
+       kthread_stop(sdp->sd_logd_process);
+       sdp->sd_logd_process = NULL;
+       return error;
+}
+
 /**
  * gfs2_fill_super - Read in superblock
  * @sb: The VFS superblock
                goto fail_per_node;
        }
 
+       if (!sb_rdonly(sb)) {
+               error = init_threads(sdp);
+               if (error) {
+                       gfs2_withdraw_delayed(sdp);
+                       goto fail_per_node;
+               }
+       }
+
        error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
        if (error)
                goto fail_per_node;
 
        gfs2_freeze_unlock(&freeze_gh);
        if (error) {
+               if (sdp->sd_quotad_process)
+                       kthread_stop(sdp->sd_quotad_process);
+               sdp->sd_quotad_process = NULL;
+               if (sdp->sd_logd_process)
+                       kthread_stop(sdp->sd_logd_process);
+               sdp->sd_logd_process = NULL;
                fs_err(sdp, "can't make FS RW: %d\n", error);
                goto fail_per_node;
        }
 
        return 0;
 }
 
-static int init_threads(struct gfs2_sbd *sdp)
-{
-       struct task_struct *p;
-       int error = 0;
-
-       p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
-       if (IS_ERR(p)) {
-               error = PTR_ERR(p);
-               fs_err(sdp, "can't start logd thread: %d\n", error);
-               return error;
-       }
-       sdp->sd_logd_process = p;
-
-       p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
-       if (IS_ERR(p)) {
-               error = PTR_ERR(p);
-               fs_err(sdp, "can't start quotad thread: %d\n", error);
-               goto fail;
-       }
-       sdp->sd_quotad_process = p;
-       return 0;
-
-fail:
-       kthread_stop(sdp->sd_logd_process);
-       sdp->sd_logd_process = NULL;
-       return error;
-}
-
 /**
  * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one
  * @sdp: the filesystem
        struct gfs2_log_header_host head;
        int error;
 
-       error = init_threads(sdp);
-       if (error) {
-               gfs2_withdraw_delayed(sdp);
-               return error;
-       }
-
        j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
-       if (gfs2_withdrawn(sdp)) {
-               error = -EIO;
-               goto fail;
-       }
+       if (gfs2_withdrawn(sdp))
+               return -EIO;
 
        error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
        if (error || gfs2_withdrawn(sdp))
-               goto fail;
+               return error;
 
        if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
                gfs2_consist(sdp);
-               error = -EIO;
-               goto fail;
+               return -EIO;
        }
 
        /*  Initialize some head of the log stuff  */
        gfs2_log_pointers_init(sdp, head.lh_blkno);
 
        error = gfs2_quota_init(sdp);
-       if (error || gfs2_withdrawn(sdp))
-               goto fail;
-
-       set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
-
-       return 0;
-
-fail:
-       if (sdp->sd_quotad_process)
-               kthread_stop(sdp->sd_quotad_process);
-       sdp->sd_quotad_process = NULL;
-       if (sdp->sd_logd_process)
-               kthread_stop(sdp->sd_logd_process);
-       sdp->sd_logd_process = NULL;
+       if (!error && !gfs2_withdrawn(sdp))
+               set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
        return error;
 }