diff --git a/kernel.spec b/kernel.spec index 262d3f2..ecc5c2a 100644 --- a/kernel.spec +++ b/kernel.spec @@ -809,7 +809,8 @@ Patch21233: jbd2-clear-BH_Delay-and-BH_Unwritten-in-journal_unmap_buf.patch Patch21234: e1000e-Avoid-wrong-check-on-TX-hang.patch #rhbz 754518 -Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch +#Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch +Patch21235: scsi-fix-sd_revalidate_disk-oops.patch #rhbz 790367 Patch21239: s390x-enable-keys-compat.patch @@ -1534,7 +1535,8 @@ ApplyPatch jbd2-clear-BH_Delay-and-BH_Unwritten-in-journal_unmap_buf.patch ApplyPatch e1000e-Avoid-wrong-check-on-TX-hang.patch #rhbz 754518 -ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch +#ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch +ApplyPatch scsi-fix-sd_revalidate_disk-oops.patch #rhbz 790367 ApplyPatch s390x-enable-keys-compat.patch @@ -2344,6 +2346,9 @@ fi # and build. %changelog +* Mon Feb 20 2012 Dave Jones 3.2.7-1 +- Do not call drivers when invalidating partitions for -ENOMEDIUM + * Mon Feb 20 2012 Dave Jones - Linux 3.2.7 diff --git a/scsi-fix-sd_revalidate_disk-oops.patch b/scsi-fix-sd_revalidate_disk-oops.patch new file mode 100644 index 0000000..defa240 --- /dev/null +++ b/scsi-fix-sd_revalidate_disk-oops.patch @@ -0,0 +1,116 @@ +--- linux-2.6.42.noarch/fs/partitions/check.c~ 2012-02-20 18:32:55.314253719 -0500 ++++ linux-2.6.42.noarch/fs/partitions/check.c 2012-02-20 18:34:46.509859745 -0500 +@@ -539,17 +539,11 @@ static bool disk_unlock_native_capacity( + } + } + +-int rescan_partitions(struct gendisk *disk, struct block_device *bdev) ++static int drop_partitions(struct gendisk *disk, struct block_device *bdev) + { +- struct parsed_partitions *state = NULL; + struct disk_part_iter piter; + struct hd_struct *part; +- int p, highest, res; +-rescan: +- if (state && !IS_ERR(state)) { +- kfree(state); +- state = NULL; +- } ++ int res; + + if (bdev->bd_part_count) + return -EBUSY; +@@ -562,6 +556,24 @@ rescan: + delete_partition(disk, part->partno); + disk_part_iter_exit(&piter); + ++ return 0; ++} ++ ++int rescan_partitions(struct gendisk *disk, struct block_device *bdev) ++{ ++ struct parsed_partitions *state = NULL; ++ struct hd_struct *part; ++ int p, highest, res; ++rescan: ++ if (state && !IS_ERR(state)) { ++ kfree(state); ++ state = NULL; ++ } ++ ++ res = drop_partitions(disk, bdev); ++ if (res) ++ return res; ++ + if (disk->fops->revalidate_disk) + disk->fops->revalidate_disk(disk); + check_disk_size_change(disk, bdev); +@@ -665,6 +677,26 @@ rescan: + return 0; + } + ++int invalidate_partitions(struct gendisk *disk, struct block_device *bdev) ++{ ++ int res; ++ ++ if (!bdev->bd_invalidated) ++ return 0; ++ ++ res = drop_partitions(disk, bdev); ++ if (res) ++ return res; ++ ++ set_capacity(disk, 0); ++ check_disk_size_change(disk, bdev); ++ bdev->bd_invalidated = 0; ++ /* tell userspace that the media / partition table may have changed */ ++ kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); ++ ++ return 0; ++} ++ + unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) + { + struct address_space *mapping = bdev->bd_inode->i_mapping; +--- linux-2.6.42.noarch/include/linux/genhd.h~ 2012-02-20 18:35:02.777802107 -0500 ++++ linux-2.6.42.noarch/include/linux/genhd.h 2012-02-20 18:35:13.873762792 -0500 +@@ -596,6 +596,7 @@ extern char *disk_name (struct gendisk * + + extern int disk_expand_part_tbl(struct gendisk *disk, int target); + extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); ++extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev); + extern struct hd_struct * __must_check add_partition(struct gendisk *disk, + int partno, sector_t start, + sector_t len, int flags, +--- linux-2.6.42.noarch/fs/block_dev.c~ 2012-02-20 18:35:24.890723757 -0500 ++++ linux-2.6.42.noarch/fs/block_dev.c 2012-02-20 18:36:25.166510197 -0500 +@@ -1159,8 +1159,12 @@ static int __blkdev_get(struct block_dev + * The latter is necessary to prevent ghost + * partitions on a removed medium. + */ +- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) +- rescan_partitions(disk, bdev); ++ if (bdev->bd_invalidated) { ++ if (!ret) ++ rescan_partitions(disk, bdev); ++ else if (ret == -ENOMEDIUM) ++ invalidate_partitions(disk, bdev); ++ } + if (ret) + goto out_clear; + } else { +@@ -1190,8 +1194,12 @@ static int __blkdev_get(struct block_dev + if (bdev->bd_disk->fops->open) + ret = bdev->bd_disk->fops->open(bdev, mode); + /* the same as first opener case, read comment there */ +- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) +- rescan_partitions(bdev->bd_disk, bdev); ++ if (bdev->bd_invalidated) { ++ if (!ret) ++ rescan_partitions(bdev->bd_disk, bdev); ++ else if (ret == -ENOMEDIUM) ++ invalidate_partitions(bdev->bd_disk, bdev); ++ } + if (ret) + goto out_unlock_bdev; + }