[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#752881: Verified bugfix against kernel v3.2



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 <tj@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 <tj@kernel.org>
    Cc: Kay Sievers <kay.sievers@vrfy.org>
    Signed-off-by: Jens Axboe <jaxboe@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 <amworsley@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


Reply to: