Please find attached a patch against mainline kernel v3.2 which works. I git bisected the bug down to the exact revision that caused the problem and then modified a revert of that change compiles against the wheezy kernel and it verified that it avoids the problem.
The change relates to failing scanning block drives related to whether they are partition-able or removable. I intend to try and dig into exactly which part of the change causes the problems and produce a more refined patch over the next week or two. I verified the bug occurs exactly after this change : d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 is the first bad commit commit d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 Author: Tejun Heo <t...@kernel.org> Date: Tue Aug 23 20:01:04 2011 +0200 block: add GENHD_FL_NO_PART_SCAN There are cases where suppressing partition scan is useful - e.g. for lo devices and pseudo SATA devices which advertise to be a disk but get upset on partition scan (some port multiplier control devices show such behavior). This patch adds GENHD_FL_NO_PART_SCAN which suppresses partition scan regardless of the number of possible partitions. disk_partitionable() is renamed to disk_part_scan_enabled() as suppressing partition scan doesn't imply the device can't be partitioned using BLKPG_ADD/DEL_PARTITION calls from userland. show_partition() now directly tests disk_max_parts() to maintain backward-compatibility. -v2: Updated to make it clear that only partition scan is suppressed not partitioning itself as suggested by Kay Sievers. Signed-off-by: Tejun Heo <t...@kernel.org> Cc: Kay Sievers <kay.siev...@vrfy.org> Signed-off-by: Jens Axboe <jax...@fusionio.com> :040000 040000 05decd4a5722a2a030f7ae6c45f8d87830e08535 a442a00c3630f2077a40fb73b8d42d9dffe7c088 M block :040000 040000 b310f91da334e2c0ee045dbec568e546b1088f3c f83dbd8ae782e8abcffb701dab31ad52cd5e3d4c M fs :040000 040000 aa8618099f709f83f86b6b6cabc56bf14578538b 81e14f1a38d9af64148236b31c0f23350608ba8c M include git bisect start # bad: [8a9c594422ecad912d6470888acdee9a1236ad68] drivers/block/loop.c: emit uevent on auto release git bisect bad 8a9c594422ecad912d6470888acdee9a1236ad68 # good: [02f8c6aee8df3cdc935e9bdd4f2d020306035dbe] Linux 3.0 git bisect good 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe # good: [0003230e8200699860f0b10af524dc47bf8aecad] Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 git bisect good 0003230e8200699860f0b10af524dc47bf8aecad # good: [206d440f64030b6425841bf7cb38e26a5ea0c382] xfs: Fix build breakage in xfs_iops.c when CONFIG_FS_POSIX_ACL is not set git bisect good 206d440f64030b6425841bf7cb38e26a5ea0c382 # skip: [c11abbbaa3252875c5740a6880b9a1a6f1e2a870] Merge branch 'slub/lockless' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6 git bisect skip c11abbbaa3252875c5740a6880b9a1a6f1e2a870 # good: [322a8b034003c0d46d39af85bf24fee27b902f48] Linux 3.1-rc1 git bisect good 322a8b034003c0d46d39af85bf24fee27b902f48 # good: [5eedf5415cd57f8db8642a5db4cf8e5507390030] nbd: replace some printk with dev_warn() and dev_info() git bisect good 5eedf5415cd57f8db8642a5db4cf8e5507390030 # bad: [e8b177cedc39b092e423b8cbc687dbf096a1de47] Merge branch 'for-3.2/core' into for-3.2/drivers git bisect bad e8b177cedc39b092e423b8cbc687dbf096a1de47 # good: [dfaa2ef68e80c378e610e3c8c536f1c239e8d3ef] loop: add discard support for loop devices git bisect good dfaa2ef68e80c378e610e3c8c536f1c239e8d3ef # bad: [d27769ec3df1a8de9ca450d2dcd72d1ab259ba32] block: add GENHD_FL_NO_PART_SCAN git bisect bad d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 git diff d27769ec3df1a8de9ca450d2dcd72d1ab259ba32~ d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 diff --git a/block/genhd.c b/block/genhd.c index 5cb51c5..2429ecb 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -536,7 +536,7 @@ void register_disk(struct gendisk *disk) disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); /* No minors to use for partitions */ - if (!disk_partitionable(disk)) + if (!disk_part_scan_enabled(disk)) goto exit; /* No such device (e.g., media were just removed) */ @@ -841,7 +841,7 @@ static int show_partition(struct seq_file *seqf, void *v) char buf[BDEVNAME_SIZE]; /* Don't show non-partitionable removeable devices or empty devices */ - if (!get_capacity(sgp) || (!disk_partitionable(sgp) && + if (!get_capacity(sgp) || (!disk_max_parts(sgp) && (sgp->flags & GENHD_FL_REMOVABLE))) return 0; if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) diff --git a/block/ioctl.c b/block/ioctl.c index 1124cd2..5c74efc 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -101,7 +101,7 @@ static int blkdev_reread_part(struct block_device *bdev) struct gendisk *disk = bdev->bd_disk; int res; - if (!disk_partitionable(disk) || bdev != bdev->bd_contains) + if (!disk_part_scan_enabled(disk) || bdev != bdev->bd_contains) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/fs/block_dev.c b/fs/block_dev.c index ff77262..0bed0d4 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -971,7 +971,7 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty) if (!bdev->bd_disk) return; - if (disk_partitionable(bdev->bd_disk)) + if (disk_part_scan_enabled(bdev->bd_disk)) bdev->bd_invalidated = 1; } diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 02fa469..6d18f35 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -128,6 +128,7 @@ struct hd_struct { #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_NATIVE_CAPACITY 128 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 +#define GENHD_FL_NO_PART_SCAN 512 enum { DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ @@ -234,9 +235,10 @@ static inline int disk_max_parts(struct gendisk *disk) return disk->minors; } -static inline bool disk_partitionable(struct gendisk *disk) +static inline bool disk_part_scan_enabled(struct gendisk *disk) { - return disk_max_parts(disk) > 1; + return disk_max_parts(disk) > 1 && + !(disk->flags & GENHD_FL_NO_PART_SCAN); } static inline dev_t disk_devt(struct gendisk *disk)
From d307a67863bf14f1785f0faa39ef2ad496758e4a Mon Sep 17 00:00:00 2001 From: Andrew Worsley <amwors...@gmail.com> Date: Sat, 26 Jul 2014 06:46:53 +1000 Subject: [PATCH] Revert "block: add GENHD_FL_NO_PART_SCAN" This reverts commit d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 but keeps the definition of GENHD_FL_NO_PART_SCAN used by drivers/block/loop.c Fix debian bug report #752881 which results in errors like then when access a PCI bus based bluRay drive ... Jun 7 14:08:36 azza kernel: [569395.478041] end_request: I/O error, dev sr1, sector 0 Jun 7 14:08:36 azza kernel: [569395.481744] sr 6:0:0:0: [sr1] Unhandled sense code Jun 7 14:08:36 azza kernel: [569395.481746] sr 6:0:0:0: [sr1] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE Jun 7 14:08:36 azza kernel: [569395.481748] sr 6:0:0:0: [sr1] Sense Key : Blank Check [current] Jun 7 14:08:36 azza kernel: [569395.481751] sr 6:0:0:0: [sr1] Add. Sense: No additional sense information Jun 7 14:08:36 azza kernel: [569395.481754] sr 6:0:0:0: [sr1] CDB: Read(10): 28 00 00 00 00 00 00 00 01 00 ... --- block/genhd.c | 4 ++-- block/ioctl.c | 2 +- fs/block_dev.c | 2 +- include/linux/genhd.h | 7 +++---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 02e9fca..d261b73 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -536,7 +536,7 @@ void register_disk(struct gendisk *disk) disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); /* No minors to use for partitions */ - if (!disk_part_scan_enabled(disk)) + if (!disk_partitionable(disk)) goto exit; /* No such device (e.g., media were just removed) */ @@ -847,7 +847,7 @@ static int show_partition(struct seq_file *seqf, void *v) char buf[BDEVNAME_SIZE]; /* Don't show non-partitionable removeable devices or empty devices */ - if (!get_capacity(sgp) || (!disk_max_parts(sgp) && + if (!get_capacity(sgp) || (!disk_partitionable(sgp) && (sgp->flags & GENHD_FL_REMOVABLE))) return 0; if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) diff --git a/block/ioctl.c b/block/ioctl.c index ca939fc..5554403 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -102,7 +102,7 @@ static int blkdev_reread_part(struct block_device *bdev) struct gendisk *disk = bdev->bd_disk; int res; - if (!disk_part_scan_enabled(disk) || bdev != bdev->bd_contains) + if (!disk_partitionable(disk) || bdev != bdev->bd_contains) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/fs/block_dev.c b/fs/block_dev.c index b07f1da..1c44b8d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -971,7 +971,7 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty) if (!bdev->bd_disk) return; - if (disk_part_scan_enabled(bdev->bd_disk)) + if (disk_partitionable(bdev->bd_disk)) bdev->bd_invalidated = 1; } diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 6d18f35..886f8ea 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -128,7 +128,7 @@ struct hd_struct { #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_NATIVE_CAPACITY 128 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 -#define GENHD_FL_NO_PART_SCAN 512 +#define GENHD_FL_NO_PART_SCAN 512 enum { DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ @@ -235,10 +235,9 @@ static inline int disk_max_parts(struct gendisk *disk) return disk->minors; } -static inline bool disk_part_scan_enabled(struct gendisk *disk) +static inline bool disk_partitionable(struct gendisk *disk) { - return disk_max_parts(disk) > 1 && - !(disk->flags & GENHD_FL_NO_PART_SCAN); + return disk_max_parts(disk) > 1; } static inline dev_t disk_devt(struct gendisk *disk) -- 1.7.10.4