lo->transfer = xfer->transfer;
        lo->ioctl = xfer->ioctl;
 
-       if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) !=
-            (info->lo_flags & LO_FLAGS_AUTOCLEAR))
-               lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
+       lo->lo_flags = info->lo_flags;
 
        lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
        lo->lo_init[0] = info->lo_init[0];
        int err;
        struct block_device *bdev;
        kuid_t uid = current_uid();
+       int prev_lo_flags;
        bool partscan = false;
        bool size_changed = false;
 
                goto out_unfreeze;
        }
 
+       prev_lo_flags = lo->lo_flags;
+
        err = loop_set_status_from_info(lo, info);
        if (err)
                goto out_unfreeze;
 
+       /* Mask out flags that can't be set using LOOP_SET_STATUS. */
+       lo->lo_flags &= ~LOOP_SET_STATUS_SETTABLE_FLAGS;
+       /* For those flags, use the previous values instead */
+       lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_SETTABLE_FLAGS;
+       /* For flags that can't be cleared, use previous values too */
+       lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_CLEARABLE_FLAGS;
+
        if (size_changed) {
                loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit,
                                           lo->lo_backing_file);
 out_unfreeze:
        blk_mq_unfreeze_queue(lo->lo_queue);
 
-       if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
-            !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
-               lo->lo_flags |= LO_FLAGS_PARTSCAN;
+       if (!err && (lo->lo_flags & LO_FLAGS_PARTSCAN) &&
+            !(prev_lo_flags & LO_FLAGS_PARTSCAN)) {
                lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
                bdev = lo->lo_device;
                partscan = true;
 
        LO_FLAGS_DIRECT_IO      = 16,
 };
 
+/* LO_FLAGS that can be set using LOOP_SET_STATUS(64) */
+#define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN)
+
+/* LO_FLAGS that can be cleared using LOOP_SET_STATUS(64) */
+#define LOOP_SET_STATUS_CLEARABLE_FLAGS (LO_FLAGS_AUTOCLEAR)
+
 #include <asm/posix_types.h>   /* for __kernel_old_dev_t */
 #include <linux/types.h>       /* for __u64 */
 
        int                lo_offset;
        int                lo_encrypt_type;
        int                lo_encrypt_key_size;         /* ioctl w/o */
-       int                lo_flags;                    /* ioctl r/o */
+       int                lo_flags;
        char               lo_name[LO_NAME_SIZE];
        unsigned char      lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
        unsigned long      lo_init[2];
        __u32              lo_number;                   /* ioctl r/o */
        __u32              lo_encrypt_type;
        __u32              lo_encrypt_key_size;         /* ioctl w/o */
-       __u32              lo_flags;                    /* ioctl r/o */
+       __u32              lo_flags;
        __u8               lo_file_name[LO_NAME_SIZE];
        __u8               lo_crypt_name[LO_NAME_SIZE];
        __u8               lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */