return error;
 }
 
-static void __loop_clr_fd(struct loop_device *lo, bool release)
+static void __loop_clr_fd(struct loop_device *lo)
 {
        struct queue_limits lim;
        struct file *filp;
        gfp_t gfp = lo->old_gfp_mask;
 
-       /*
-        * Freeze the request queue when unbinding on a live file descriptor and
-        * thus an open device.  When called from ->release we are guaranteed
-        * that there is no I/O in progress already.
-        */
-       if (!release)
-               blk_mq_freeze_queue(lo->lo_queue);
-
        spin_lock_irq(&lo->lo_lock);
        filp = lo->lo_backing_file;
        lo->lo_backing_file = NULL;
        mapping_set_gfp_mask(filp->f_mapping, gfp);
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
-       if (!release)
-               blk_mq_unfreeze_queue(lo->lo_queue);
 
        disk_force_media_change(lo->lo_disk);
 
                 * must be at least one and it can only become zero when the
                 * current holder is released.
                 */
-               if (!release)
-                       mutex_lock(&lo->lo_disk->open_mutex);
                err = bdev_disk_changed(lo->lo_disk, false);
-               if (!release)
-                       mutex_unlock(&lo->lo_disk->open_mutex);
                if (err)
                        pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
                                __func__, lo->lo_number, err);
                return -ENXIO;
        }
        /*
-        * If we've explicitly asked to tear down the loop device,
-        * and it has an elevated reference count, set it for auto-teardown when
-        * the last reference goes away. This stops $!~#$@ udev from
-        * preventing teardown because it decided that it needs to run blkid on
-        * the loopback device whenever they appear. xfstests is notorious for
-        * failing tests because blkid via udev races with a losetup
-        * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d
-        * command to fail with EBUSY.
+        * Mark the device for removing the backing device on last close.
+        * If we are the only opener, also switch the state to roundown here to
+        * prevent new openers from coming in.
         */
-       if (disk_openers(lo->lo_disk) > 1) {
-               lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
-               loop_global_unlock(lo, true);
-               return 0;
-       }
-       lo->lo_state = Lo_rundown;
+
+       lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
+       if (disk_openers(lo->lo_disk) == 1)
+               lo->lo_state = Lo_rundown;
        loop_global_unlock(lo, true);
 
-       __loop_clr_fd(lo, false);
        return 0;
 }
 
 }
 #endif
 
+static int lo_open(struct gendisk *disk, blk_mode_t mode)
+{
+       struct loop_device *lo = disk->private_data;
+       int err;
+
+       err = mutex_lock_killable(&lo->lo_mutex);
+       if (err)
+               return err;
+
+       if (lo->lo_state == Lo_deleting || lo->lo_state == Lo_rundown)
+               err = -ENXIO;
+       mutex_unlock(&lo->lo_mutex);
+       return err;
+}
+
 static void lo_release(struct gendisk *disk)
 {
        struct loop_device *lo = disk->private_data;
+       bool need_clear = false;
 
        if (disk_openers(disk) > 0)
                return;
+       /*
+        * Clear the backing device information if this is the last close of
+        * a device that's been marked for auto clear, or on which LOOP_CLR_FD
+        * has been called.
+        */
 
        mutex_lock(&lo->lo_mutex);
-       if (lo->lo_state == Lo_bound && (lo->lo_flags & LO_FLAGS_AUTOCLEAR)) {
+       if (lo->lo_state == Lo_bound && (lo->lo_flags & LO_FLAGS_AUTOCLEAR))
                lo->lo_state = Lo_rundown;
-               mutex_unlock(&lo->lo_mutex);
-               /*
-                * In autoclear mode, stop the loop thread
-                * and remove configuration after last close.
-                */
-               __loop_clr_fd(lo, true);
-               return;
-       }
+
+       need_clear = (lo->lo_state == Lo_rundown);
        mutex_unlock(&lo->lo_mutex);
+
+       if (need_clear)
+               __loop_clr_fd(lo);
 }
 
 static void lo_free_disk(struct gendisk *disk)
 
 static const struct block_device_operations lo_fops = {
        .owner =        THIS_MODULE,
+       .open =         lo_open,
        .release =      lo_release,
        .ioctl =        lo_ioctl,
 #ifdef CONFIG_COMPAT