]> git.proxmox.com Git - mirror_zfs.git/commit
Don't enter zvol's rangelock for read bio with size 0
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Wed, 20 Feb 2019 18:14:36 +0000 (03:14 +0900)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 20 Feb 2019 18:14:36 +0000 (10:14 -0800)
commit9abbee491285303d78704e937a13ddcbb6cd0f79
treebf8573d4e654389623c199bdfdc8830c8dbb269f
parent1e427f2e2b8da17bdddada3926648692bc1ffae0
Don't enter zvol's rangelock for read bio with size 0

The SCST driver (SCSI target driver implementation) and possibly
others may issue read bio's with a length of zero bytes. Although
this is unusual, such bio's issued under certain condition can cause
kernel oops, due to how rangelock is implemented.

rangelock_add_reader() is not made to handle overlap of two (or more)
ranges from read bio's with the same offset when one of them has size
of 0, even though they conceptually overlap. Allowing them to enter
rangelock results in kernel oops by dereferencing invalid pointer,
or assertion failure on AVL tree manipulation with debug enabled
kernel module.

For example, this happens when read bio whose (offset, size) is
(0, 0) enters rangelock followed by another read bio with (0, 4096)
when (0, 0) rangelock is still locked, when there are no pending
write bio's. It can also happen with reverse order, which is (0, N)
followed by (0, 0) when (0, N) is still locked. More details
mentioned in #8379.

Kernel Oops on ->make_request_fn() of ZFS volume
https://github.com/zfsonlinux/zfs/issues/8379

Prevent this by returning bio with size 0 as success without entering
rangelock. This has been done for write bio after checking flusher
bio case (though not for the same reason), but not for read bio.

Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@osnexus.com>
Closes #8379
Closes #8401
module/zfs/zvol.c