From: Omar Sandoval <osandov@xxxxxx> In both of these error cases, we need to make sure to unfreeze the queue before we return. Fixes: ecdd09597a57 ("block/loop: fix race between I/O and set_status") Fixes: f2c6df7dbf9a ("loop: support 4k physical blocksize") Signed-off-by: Omar Sandoval <osandov@xxxxxx> --- drivers/block/loop.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 39fa7f48e0c7..6c7609b3305d 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1125,11 +1125,15 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) if (info->lo_encrypt_type) { unsigned int type = info->lo_encrypt_type; - if (type >= MAX_LO_CRYPT) - return -EINVAL; + if (type >= MAX_LO_CRYPT) { + err = -EINVAL; + goto exit; + } xfer = xfer_funcs[type]; - if (xfer == NULL) - return -EINVAL; + if (xfer == NULL) { + err = -EINVAL; + goto exit; + } } else xfer = NULL; @@ -1142,10 +1146,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) if (lo_logical_blocksize != 512 && lo_logical_blocksize != 1024 && lo_logical_blocksize != 2048 && - lo_logical_blocksize != 4096) - return -EINVAL; - if (lo_logical_blocksize > lo->lo_blocksize) - return -EINVAL; + lo_logical_blocksize != 4096) { + err = -EINVAL; + goto exit; + } + if (lo_logical_blocksize > lo->lo_blocksize) { + err = -EINVAL; + goto exit; + } } else { lo_logical_blocksize = lo->lo_logical_blocksize; } -- 2.14.1