linux/fs
Tejun Heo 523e1d399c block: make gendisk hold a reference to its queue
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+ #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 <tj@kernel.org>
Cc: stable@kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2011-10-19 14:31:07 +02:00
..
9p
adfs
affs
afs
autofs4
befs
bfs
btrfs Merge branch 'btrfs-3.0' of git://github.com/chrismason/linux 2011-10-13 18:20:40 +12:00
cachefiles
ceph
cifs [CIFS] Fix first time message on mount, ntlmv2 upgrade delayed to 3.2 2011-10-07 20:17:56 -05:00
coda
configfs
cramfs
debugfs
devpts
dlm
ecryptfs
efs
exofs
exportfs
ext2
ext3
ext4 Merge branch 'for-linus' of git://git.kernel.dk/linux-block 2011-09-21 13:20:21 -07:00
fat
freevxfs
fscache
fuse
gfs2
hfs
hfsplus hfsplus: fix filesystem size checks 2011-09-15 09:03:17 -07:00
hostfs
hpfs
hppfs
hugetlbfs
isofs
jbd
jbd2
jffs2
jfs
lockd
logfs
minix
ncpfs
nfs VFS: Fix the remaining automounter semantics regressions 2011-09-26 19:16:46 -07:00
nfs_common
nfsd
nilfs2
nls
notify
ntfs
ocfs2
omfs
openpromfs
partitions
proc teach /proc/$pid/numa_maps about transparent hugepages 2011-09-21 13:15:44 -07:00
pstore
qnx4
quota VFS: Fix the remaining automounter semantics regressions 2011-09-26 19:16:46 -07:00
ramfs
reiserfs
romfs
squashfs
sysfs
sysv
ubifs
udf
ufs
xfs xfs: revert to using a kthread for AIL pushing 2011-10-11 11:02:49 -05:00
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf.c
binfmt_elf_fdpic.c
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
binfmt_som.c
bio-integrity.c
bio.c
block_dev.c block: make gendisk hold a reference to its queue 2011-10-19 14:31:07 +02:00
buffer.c
char_dev.c
compat.c
compat_binfmt_elf.c
compat_ioctl.c
dcache.c
dcookies.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c
exec.c
fcntl.c
fhandle.c
fifo.c
file.c
file_table.c
filesystems.c
fs-writeback.c
fs_struct.c
generic_acl.c
inode.c
internal.h
ioctl.c
ioprio.c
Kconfig
Kconfig.binfmt
libfs.c
locks.c
Makefile
mbcache.c
mpage.c
namei.c vfs: remove LOOKUP_NO_AUTOMOUNT flag 2011-09-27 08:12:33 -07:00
namespace.c VFS: Fix the remaining automounter semantics regressions 2011-09-26 19:16:46 -07:00
no-block.c
open.c
pipe.c
pnode.c
pnode.h
posix_acl.c
read_write.c
read_write.h
readdir.c
select.c
seq_file.c
signalfd.c
splice.c
stack.c
stat.c vfs: remove LOOKUP_NO_AUTOMOUNT flag 2011-09-27 08:12:33 -07:00
statfs.c
super.c
sync.c
timerfd.c
utimes.c
xattr.c
xattr_acl.c