From: Omar Sandoval <osan...@fb.com>

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")
Tested-by: Milan Broz <gmazyl...@gmail.com>
Reviewed-by: Milan Broz <gmazyl...@gmail.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Signed-off-by: Omar Sandoval <osan...@fb.com>
---
 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 ef8334949b42..26548e07bc31 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;
 
@@ -1144,10 +1148,14 @@ loop_set_status(struct loop_device *lo, const struct 
loop_info64 *info)
                if (LO_INFO_BLOCKSIZE(info) != 512 &&
                    LO_INFO_BLOCKSIZE(info) != 1024 &&
                    LO_INFO_BLOCKSIZE(info) != 2048 &&
-                   LO_INFO_BLOCKSIZE(info) != 4096)
-                       return -EINVAL;
-               if (LO_INFO_BLOCKSIZE(info) > lo->lo_blocksize)
-                       return -EINVAL;
+                   LO_INFO_BLOCKSIZE(info) != 4096) {
+                       err = -EINVAL;
+                       goto exit;
+               }
+               if (LO_INFO_BLOCKSIZE(info) > lo->lo_blocksize) {
+                       err = -EINVAL;
+                       goto exit;
+               }
        }
 
        if (lo->lo_offset != info->lo_offset ||
-- 
2.14.1

Reply via email to