From: Omar Sandoval <[email protected]>
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 <[email protected]>
---
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