I/O Error Test 7 ================ commit: "bcache: fix ioctl in flash device"
This test needs QEMU+GDB since there's no way to set the variable from the kernel, because it references incorrect memory/pointer. In the original kernel, the ioctl() to a flash-only volume goes from ioctl_dev() down to flash_dev_ioctl() (which always return -ENOTTY always) only if its backing device has io_disable == 0, but gets -EIO if io_disable == 1 (which are both wrong as flash device has no backing device). In the modified kernel, it always go down to flash_dev_ioctl(), thus -ENOTTY in both cases. Original kernel: $ uname -rv 4.15.0-51-generic #55-Ubuntu SMP Wed May 15 14:27:21 UTC 2019 io_disable = 0: # ./ioctl ioctl: Inappropriate ioctl for device io_disable = 1: # ./ioctl ioctl: Input/output error Modified kernel: # uname -rv 4.18.0-23-generic #24+test20190619b1 SMP Wed Jun 19 22:33:22 UTC 2019 io_disable = 0: # ./ioctl ioctl: Inappropriate ioctl for device io_disable = 1: # ./ioctl ioctl: Inappropriate ioctl for device Steps ----- $ sudo -i # ./setup.sh >/dev/null 2>&1 [ 57.607391] bcache: register_bdev() registered backing device dm-0 [ 57.611885] bcache: run_cache_set() invalidating existing data [ 57.625712] bcache: register_cache() registered cache device dm-1 [ 58.605153] bcache: bch_cached_dev_attach() Caching dm-0 as bcache0 on set 08f1756b-081f-4545-a947-927d429f7ef1 # lsblk -e 252 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 1G 0 loop └─fake-loop0 253:0 0 1024M 0 dm └─bcache0 251:0 0 1024M 0 disk loop1 7:1 0 1G 0 loop └─fake-loop1 253:1 0 1024M 0 dm └─bcache0 251:0 0 1024M 0 disk # echo $((128*1024**2)) > /sys/block/dm-1/bcache/set/flash_vol_create # lsblk -e 252 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 1G 0 loop └─fake-loop0 253:0 0 1024M 0 dm └─bcache0 251:0 0 1024M 0 disk loop1 7:1 0 1G 0 loop └─fake-loop1 253:1 0 1024M 0 dm ├─bcache0 251:0 0 1024M 0 disk └─bcache1 251:128 0 128M 0 disk # ls -1d /sys/block/bcache1/bcache/cache/volume* /sys/block/bcache1/bcache/cache/volume1 # cat /sys/module/bcache/sections/.text 0xffffffffc05f4000 # cat ioctl.c #include <sys/ioctl.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> int main() { int fd, rc; fd = open("/dev/bcache1", O_RDWR); if (fd == -1) { perror("open"); return 0; } rc = ioctl(fd, 0xcc00ffee); // our cookie. if (rc == -1) perror("ioctl"); close(fd); return 0; } # gcc -o ioctl ioctl.c # ./ioctl (gdb) add-symbol-file ~/ddeb-4.18.0-23-generic/usr/lib/debug/lib/modules/4.18.0-23-generic/kernel/drivers/md/bcache/bcache.ko 0xffffffffc05f4000 (gdb) b *ioctl_dev +0x13 (gdb) c Thread 4 hit Breakpoint 1, ioctl_dev (b=<optimized out>, mode=134610975, cmd=3422617582, arg=2) at /build/linux-JHFGaE/linux-4.18.0/drivers/md/bcache/super.c:641 ... (gdb) p/x 3422617582 $53 = 0xcc00ffee // our cookie. (gdb) print d.name $54 = "volume1\000\000\000\000" // matches the volume above. See it's an incorrect pointer. No way to set it via any io_disable in sysfs. (gdb) print ((struct cached_dev *)((void *)d - 0x10)).backing_dev_name $75 = "\017\000\000\000\260\373\212s\277\230\377\377\260\373\212s\277\230\377\377 nԇ\377\377\377\377\060qh\211" (gdb) print ((struct cached_dev *)((void *)d - 0x10)).io_disable $76 = 0 With the default value (io_disable = 0): # ./ioctl ioctl: Inappropriate ioctl for device (gdb) c ... repeat. With the forced value (io_disable = 1): (gdb) set ((struct cached_dev *)((void *)d - 0x10)).io_disable = 1 (gdb) c # ./ioctl ioctl: Input/output error -- You received this bug notification because you are a member of Kernel Packages, which is subscribed to linux in Ubuntu. https://bugs.launchpad.net/bugs/1829563 Title: bcache: risk of data loss on I/O errors in backing or caching devices Status in linux package in Ubuntu: Invalid Status in linux source package in Bionic: In Progress Status in linux source package in Cosmic: In Progress Bug description: [Impact] * The bcache code in Bionic lacks several fixes to handle I/O errors in both backing devices and caching devices. * Partial or permanent errors in backing or caching devices, specially in writeback mode, can lead to data loss and/or the application is not notified about failed I/O requests. * The bcache device might remain available for I/O requests even if backing device is offline, so writes are undefined. [Test Case] * Detailed test cases/steps for the behavior of many patches with code logic changes are provided in bug comments. * The patchset has been tested for regressions on each cache mode (writethrough, writeback, writearound, none) with the xfstests test suite (on ext4) and fio (sequential + random read-write). [Regression Potential] * The patchset is relatively large and touches several areas in bcache code, however, synthetic testing of the patches has been performed, and extensive regression/stress tests were run (as mentioned in Test Case section). * Many patches in the patchset are 'Fixes' patches to other patches, and no further 'Fixes' currently exist upstream. [Other Info] * Canonical Field Eng. deploys bcache+writeback extensively (e.g., BootStack, UA cloud, except rare all-flash cases). [Original Bug Description] This is a request for a backport of the following upstream patch from 4.18: "bcache: stop bcache device when backing device is offline" https://github.com/torvalds/linux/commit/0f0709e6bfc3ce4e8e1c0e8573490c45f76cfeee Field engineering uses bcache quite extensively and it would be good to have this in the GA/bionic kernel. To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1829563/+subscriptions -- Mailing list: https://launchpad.net/~kernel-packages Post to : kernel-packages@lists.launchpad.net Unsubscribe : https://launchpad.net/~kernel-packages More help : https://help.launchpad.net/ListHelp