goto fail;
        }
 
+       /**
+        * If we're a spectator, we don't want to take the lock in EX because
+        * we cannot do the first-mount responsibility it implies: recovery.
+        */
+       if (sdp->sd_args.ar_spectator)
+               goto locks_done;
+
        error = mounted_lock(sdp, DLM_LOCK_EX, DLM_LKF_CONVERT|DLM_LKF_NOQUEUE);
        if (!error) {
                mounted_mode = DLM_LOCK_EX;
        if (lvb_gen < mount_gen) {
                /* wait for mounted nodes to update control_lock lvb to our
                   generation, which might include new recovery bits set */
-               fs_info(sdp, "control_mount wait1 block %u start %u mount %u "
-                       "lvb %u flags %lx\n", block_gen, start_gen, mount_gen,
-                       lvb_gen, ls->ls_recover_flags);
+               if (sdp->sd_args.ar_spectator) {
+                       fs_info(sdp, "Recovery is required. Waiting for a "
+                               "non-spectator to mount.\n");
+                       msleep_interruptible(1000);
+               } else {
+                       fs_info(sdp, "control_mount wait1 block %u start %u "
+                               "mount %u lvb %u flags %lx\n", block_gen,
+                               start_gen, mount_gen, lvb_gen,
+                               ls->ls_recover_flags);
+               }
                spin_unlock(&ls->ls_recover_spin);
                goto restart;
        }
 
        ktime_t t_start, t_jlck, t_jhd, t_tlck, t_rep;
        int ro = 0;
        unsigned int pass;
-       int error;
+       int error = 0;
        int jlocked = 0;
 
        t_start = ktime_get();
-       if (sdp->sd_args.ar_spectator ||
-           (jd->jd_jid != sdp->sd_lockstruct.ls_jid)) {
+       if (sdp->sd_args.ar_spectator)
+               goto fail;
+       if (jd->jd_jid != sdp->sd_lockstruct.ls_jid) {
                fs_info(sdp, "jid=%u: Trying to acquire journal lock...\n",
                        jd->jd_jid);
                jlocked = 1;
 
 
        spin_lock(&sdp->sd_jindex_spin);
        rv = -EBUSY;
-       if (sdp->sd_jdesc->jd_jid == jid)
+       /**
+        * If we're a spectator, we use journal0, but it's not really ours.
+        * So we need to wait for its recovery too. If we skip it we'd never
+        * queue work to the recovery workqueue, and so its completion would
+        * never clear the DFL_BLOCK_LOCKS flag, so all our locks would
+        * permanently stop working.
+        */
+       if (sdp->sd_jdesc->jd_jid == jid && !sdp->sd_args.ar_spectator)
                goto out;
        rv = -ENOENT;
        list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
-               if (jd->jd_jid != jid)
+               if (jd->jd_jid != jid && !sdp->sd_args.ar_spectator)
                        continue;
                rv = gfs2_recover_journal(jd, false);
                break;