]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
genhd: Make put_disk() safe for disks that have not been registered
authorBen Hutchings <ben@decadent.org.uk>
Mon, 27 Aug 2012 23:56:53 +0000 (20:56 -0300)
committerJiri Kosina <jkosina@suse.cz>
Mon, 3 Sep 2012 13:55:19 +0000 (15:55 +0200)
Since commit 523e1d3 ('block: make gendisk hold a reference to its
queue'), add_disk() adds a reference to disk->queue, which is then
dropped by disk_release().  But if a disk is destroyed without being
registered through add_disk() (or if add_disk() fails at the first
hurdle) then we have a reference imbalance.

Use the GENHD_FL_UP flag to tell whether this extra reference has been
added.  Remove the incomplete workaround from the floppy driver.

Cc: stable@vger.kernel.org
Acked-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
block/genhd.c
drivers/block/floppy.c

index d839723303c856ae221bdf54ec1de93544698d95..633751dbb9a9ff01dd85a0ca2c468f22ce339043 100644 (file)
@@ -587,8 +587,6 @@ void add_disk(struct gendisk *disk)
        WARN_ON(disk->minors && !(disk->major || disk->first_minor));
        WARN_ON(!disk->minors && !(disk->flags & GENHD_FL_EXT_DEVT));
 
-       disk->flags |= GENHD_FL_UP;
-
        retval = blk_alloc_devt(&disk->part0, &devt);
        if (retval) {
                WARN_ON(1);
@@ -596,6 +594,8 @@ void add_disk(struct gendisk *disk)
        }
        disk_to_dev(disk)->devt = devt;
 
+       disk->flags |= GENHD_FL_UP;
+
        /* ->major and ->first_minor aren't supposed to be
         * dereferenced from here on, but set them just in case.
         */
@@ -1105,7 +1105,7 @@ static void disk_release(struct device *dev)
        disk_replace_part_tbl(disk, NULL);
        free_part_stats(&disk->part0);
        free_part_info(&disk->part0);
-       if (disk->queue)
+       if (disk->queue && disk->flags & GENHD_FL_UP)
                blk_put_queue(disk->queue);
        kfree(disk);
 }
index 1e09e998904f6b0bd59a934a7bc00f4827b176aa..32551f254054b19f359c4e7df7b5fefc53f588e9 100644 (file)
@@ -4322,14 +4322,8 @@ out_unreg_blkdev:
 out_put_disk:
        while (dr--) {
                del_timer_sync(&motor_off_timer[dr]);
-               if (disks[dr]->queue) {
+               if (disks[dr]->queue)
                        blk_cleanup_queue(disks[dr]->queue);
-                       /*
-                        * put_disk() is not paired with add_disk() and
-                        * will put queue reference one extra time. fix it.
-                        */
-                       disks[dr]->queue = NULL;
-               }
                put_disk(disks[dr]);
        }
        destroy_workqueue(floppy_wq);
@@ -4558,14 +4552,6 @@ static void __exit floppy_module_exit(void)
                }
                blk_cleanup_queue(disks[drive]->queue);
 
-               /*
-                * These disks have not called add_disk().  Don't put down
-                * queue reference in put_disk().
-                */
-               if (!(allowed_drive_mask & (1 << drive)) ||
-                   fdc_state[FDC(drive)].version == FDC_NONE)
-                       disks[drive]->queue = NULL;
-
                put_disk(disks[drive]);
        }