|
@@ -1097,9 +1097,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
|
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
|
|
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
+ /* I/O need to be drained during transfer transition */
|
|
|
|
+ blk_mq_freeze_queue(lo->lo_queue);
|
|
|
|
+
|
|
err = loop_release_xfer(lo);
|
|
err = loop_release_xfer(lo);
|
|
if (err)
|
|
if (err)
|
|
- return err;
|
|
|
|
|
|
+ goto exit;
|
|
|
|
|
|
if (info->lo_encrypt_type) {
|
|
if (info->lo_encrypt_type) {
|
|
unsigned int type = info->lo_encrypt_type;
|
|
unsigned int type = info->lo_encrypt_type;
|
|
@@ -1114,12 +1117,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
|
|
|
|
|
err = loop_init_xfer(lo, xfer, info);
|
|
err = loop_init_xfer(lo, xfer, info);
|
|
if (err)
|
|
if (err)
|
|
- return err;
|
|
|
|
|
|
+ goto exit;
|
|
|
|
|
|
if (lo->lo_offset != info->lo_offset ||
|
|
if (lo->lo_offset != info->lo_offset ||
|
|
lo->lo_sizelimit != info->lo_sizelimit)
|
|
lo->lo_sizelimit != info->lo_sizelimit)
|
|
- if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
|
|
|
|
- return -EFBIG;
|
|
|
|
|
|
+ if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
|
|
|
|
+ err = -EFBIG;
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
|
|
loop_config_discard(lo);
|
|
loop_config_discard(lo);
|
|
|
|
|
|
@@ -1156,7 +1161,9 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
|
/* update dio if lo_offset or transfer is changed */
|
|
/* update dio if lo_offset or transfer is changed */
|
|
__loop_update_dio(lo, lo->use_dio);
|
|
__loop_update_dio(lo, lo->use_dio);
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ exit:
|
|
|
|
+ blk_mq_unfreeze_queue(lo->lo_queue);
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|