[kernel/f16] Do not call drivers when invalidating partitions for -ENOMEDIUM

Dave Jones davej at fedoraproject.org
Tue Feb 21 01:06:53 UTC 2012


commit 15609ef4c4488afd6f62cff8c105045ea832bc9b
Author: Dave Jones <davej at redhat.com>
Date:   Mon Feb 20 20:06:42 2012 -0500

    Do not call drivers when invalidating partitions for -ENOMEDIUM

 kernel.spec                            |    9 ++-
 scsi-fix-sd_revalidate_disk-oops.patch |  116 ++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 2 deletions(-)
---
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 <davej at redhat.com> 3.2.7-1
+- Do not call drivers when invalidating partitions for -ENOMEDIUM
+
 * Mon Feb 20 2012 Dave Jones <davej at redhat.com>
 - 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;
+ 		}


More information about the scm-commits mailing list