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

Reply via email to