ataflop: fix error handling during setup
authorOmar Sandoval <osandov@fb.com>
Thu, 11 Oct 2018 19:20:49 +0000 (12:20 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Nov 2018 19:08:20 +0000 (11:08 -0800)
[ Upstream commit 71327f547ee3a46ec5c39fdbbd268401b2578d0e ]

Move queue allocation next to disk allocation to fix a couple of issues:

- If add_disk() hasn't been called, we should clear disk->queue before
  calling put_disk().
- If we fail to allocate a request queue, we still need to put all of
  the disks, not just the ones that we allocated queues for.

Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/block/ataflop.c

index dfb2c26..822e306 100644 (file)
@@ -1935,6 +1935,11 @@ static int __init atari_floppy_init (void)
                unit[i].disk = alloc_disk(1);
                if (!unit[i].disk)
                        goto Enomem;
+
+               unit[i].disk->queue = blk_init_queue(do_fd_request,
+                                                    &ataflop_lock);
+               if (!unit[i].disk->queue)
+                       goto Enomem;
        }
 
        if (UseTrackbuffer < 0)
@@ -1966,10 +1971,6 @@ static int __init atari_floppy_init (void)
                sprintf(unit[i].disk->disk_name, "fd%d", i);
                unit[i].disk->fops = &floppy_fops;
                unit[i].disk->private_data = &unit[i];
-               unit[i].disk->queue = blk_init_queue(do_fd_request,
-                                       &ataflop_lock);
-               if (!unit[i].disk->queue)
-                       goto Enomem;
                set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
                add_disk(unit[i].disk);
        }
@@ -1984,13 +1985,17 @@ static int __init atari_floppy_init (void)
 
        return 0;
 Enomem:
-       while (i--) {
-               struct request_queue *q = unit[i].disk->queue;
+       do {
+               struct gendisk *disk = unit[i].disk;
 
-               put_disk(unit[i].disk);
-               if (q)
-                       blk_cleanup_queue(q);
-       }
+               if (disk) {
+                       if (disk->queue) {
+                               blk_cleanup_queue(disk->queue);
+                               disk->queue = NULL;
+                       }
+                       put_disk(unit[i].disk);
+               }
+       } while (i--);
 
        unregister_blkdev(FLOPPY_MAJOR, "fd");
        return -ENOMEM;