diff options
author | Jiri Kosina <jkosina@suse.cz> | 2012-10-26 19:53:52 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-10-26 19:53:52 +0200 |
commit | 4a1996b54f41973520dea7d4b75e41cc241e4930 (patch) | |
tree | c62067562f8ab0c2b72b3691aae28d168ee35ab0 | |
parent | d5e8d57f69a9dcc75d27ea5a54587cf03d1f859d (diff) |
Revert "genhd: Make put_disk() safe for disks that have not been registered"
This reverts commit b33d002f4b6bae912463e5a66387c498aa69b6fe.
Conflicts:
drivers/block/floppy.c
Sasha Levin reports that it's causing NULL ptr dereference in
blk_dequeue_request(), Ben is not willing to work on fixing the
patch any more, and the workaround in floppy driver doesn't hurt.
Reported-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | block/genhd.c | 6 | ||||
-rw-r--r-- | drivers/block/floppy.c | 13 |
2 files changed, 16 insertions, 3 deletions
diff --git a/block/genhd.c b/block/genhd.c index 633751dbb9a9..d839723303c8 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -587,6 +587,8 @@ 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); @@ -594,8 +596,6 @@ 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 && disk->flags & GENHD_FL_UP) + if (disk->queue) blk_put_queue(disk->queue); kfree(disk); } diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 95e528799737..9d900e6aba55 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4337,6 +4337,11 @@ out_put_disk: if (disks[drive]->queue) { del_timer_sync(&motor_off_timer[drive]); blk_cleanup_queue(disks[drive]->queue); + /* + * put_disk() is not paired with add_disk() and + * will put queue reference one extra time. fix it. + */ + disks[drive]->queue = NULL; } put_disk(disks[drive]); } @@ -4565,6 +4570,14 @@ 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]); } |