[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