Commit 6022736
block: make gendisk hold a reference to its queue
commit f992ae8 upstream.
The following command sequence triggers an oops.
# mount /dev/sdb1 /mnt
# echo 1 > /sys/class/scsi_device/0\:0\:1\:0/device/delete
# umount /mnt
general protection fault: 0000 [#1] PREEMPT SMP
CPU 2
Modules linked in:
Pid: 791, comm: umount Not tainted 3.1.0-rc3-work+ torvalds#8 Bochs Bochs
RIP: 0010:[<ffffffff810d0879>] [<ffffffff810d0879>] __lock_acquire+0x389/0x1d60
...
Call Trace:
[<ffffffff810d2845>] lock_acquire+0x95/0x140
[<ffffffff81aed87b>] _raw_spin_lock+0x3b/0x50
[<ffffffff811573bc>] bdi_lock_two+0x5c/0x70
[<ffffffff811c2f6c>] bdev_inode_switch_bdi+0x4c/0xf0
[<ffffffff811c3fcb>] __blkdev_put+0x11b/0x1d0
[<ffffffff811c4010>] __blkdev_put+0x160/0x1d0
[<ffffffff811c40df>] blkdev_put+0x5f/0x190
[<ffffffff8118f18d>] kill_block_super+0x4d/0x80
[<ffffffff8118f4a5>] deactivate_locked_super+0x45/0x70
[<ffffffff8119003a>] deactivate_super+0x4a/0x70
[<ffffffff811ac4ad>] mntput_no_expire+0xed/0x130
[<ffffffff811acf2e>] sys_umount+0x7e/0x3a0
[<ffffffff81aeeeab>] system_call_fastpath+0x16/0x1b
This is because bdev holds on to disk but disk doesn't pin the
associated queue. If a SCSI device is removed while the device is
still open, the sdev puts the base reference to the queue on release.
When the bdev is finally released, the associated queue is already
gone along with the bdi and bdev_inode_switch_bdi() ends up
dereferencing already freed bdi.
Even if it were not for this bug, disk not holding onto the associated
queue is very unusual and error-prone.
Fix it by making add_disk() take an extra reference to its queue and
put it on disk_release() and ensuring that disk and its fops owner are
put in that order after all accesses to the disk and queue are
complete.
Signed-off-by: Tejun Heo <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>1 parent 819bac2 commit 6022736
2 files changed
+16
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
611 | 611 | | |
612 | 612 | | |
613 | 613 | | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
614 | 620 | | |
615 | 621 | | |
616 | 622 | | |
| |||
1095 | 1101 | | |
1096 | 1102 | | |
1097 | 1103 | | |
| 1104 | + | |
| 1105 | + | |
1098 | 1106 | | |
1099 | 1107 | | |
1100 | 1108 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1085 | 1085 | | |
1086 | 1086 | | |
1087 | 1087 | | |
| 1088 | + | |
1088 | 1089 | | |
1089 | 1090 | | |
1090 | 1091 | | |
| |||
1110 | 1111 | | |
1111 | 1112 | | |
1112 | 1113 | | |
| 1114 | + | |
1113 | 1115 | | |
1114 | 1116 | | |
1115 | 1117 | | |
| |||
1137 | 1139 | | |
1138 | 1140 | | |
1139 | 1141 | | |
1140 | | - | |
1141 | 1142 | | |
| 1143 | + | |
1142 | 1144 | | |
1143 | 1145 | | |
1144 | 1146 | | |
| |||
1194 | 1196 | | |
1195 | 1197 | | |
1196 | 1198 | | |
1197 | | - | |
1198 | 1199 | | |
| 1200 | + | |
1199 | 1201 | | |
1200 | 1202 | | |
1201 | 1203 | | |
| |||
1215 | 1217 | | |
1216 | 1218 | | |
1217 | 1219 | | |
1218 | | - | |
1219 | 1220 | | |
| 1221 | + | |
1220 | 1222 | | |
1221 | 1223 | | |
1222 | 1224 | | |
| |||
1442 | 1444 | | |
1443 | 1445 | | |
1444 | 1446 | | |
1445 | | - | |
1446 | | - | |
1447 | 1447 | | |
1448 | 1448 | | |
1449 | 1449 | | |
1450 | 1450 | | |
1451 | 1451 | | |
1452 | 1452 | | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
1453 | 1456 | | |
1454 | 1457 | | |
1455 | 1458 | | |
| |||
0 commit comments