History

partitions: add ->set_capacity block device method

* Add ->set_capacity block device method and use it in rescan_partitions() to attempt enabling native capacity of the device upon detecting the partition which exceeds device capacity. * Add GENHD_FL_NATIVE_CAPACITY flag to try limit attempts of enabling native capacity during partition scan. Together with the consecutive patch implementing ->set_capacity method in ide-gd device driver this allows automatic disabling of Host Protected Area (HPA) if any partitions overlapping HPA are detected.

Bartlomiej Zolnierkiewicz committed 17 years ago

Commit db429e91 parent 02c33b13 files · +35 −11Browse files

Unified · Split

3 files
  1. fs/partitions/check.c +32 −11
  2. include/linux/blkdev.h +2 −0
  3. include/linux/genhd.h +1 −0
fs/partitions/check.c+32−11
@@ -546,28 +546,49 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) · 545 unmodified lines
546546
547547 /* add partitions */
548548 for (p = 1; p < state->limit; p++) {
549− sector_t size = state->parts[p].size;
550− sector_t from = state->parts[p].from;
549+ sector_t size, from;
550+try_scan:
551+ size = state->parts[p].size;
551552 if (!size)
552553 continue;
554+
555+ from = state->parts[p].from;
553556 if (from >= get_capacity(disk)) {
554557 printk(KERN_WARNING
555558 "%s: p%d ignored, start %llu is behind the end of the disk\n",
556559 disk->disk_name, p, (unsigned long long) from);
557560 continue;
558561 }
562+
559563 if (from + size > get_capacity(disk)) {
560− /*
561− * we can not ignore partitions of broken tables
562− * created by for example camera firmware, but we
563− * limit them to the end of the disk to avoid
564− * creating invalid block devices
565− */
564+ struct block_device_operations *bdops = disk->fops;
565+ unsigned long long capacity;
566+
566567 printk(KERN_WARNING
567− "%s: p%d size %llu exceeds device capacity, "
568− "limited to end of disk\n",
568+ "%s: p%d size %llu exceeds device capacity, ",
569569 disk->disk_name, p, (unsigned long long) size);
570− size = get_capacity(disk) - from;
570+
571+ if (bdops->set_capacity &&
572+ (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) {
573+ printk(KERN_CONT "enabling native capacity\n");
574+ capacity = bdops->set_capacity(disk, ~0ULL);
575+ disk->flags |= GENHD_FL_NATIVE_CAPACITY;
576+ if (capacity > get_capacity(disk)) {
577+ set_capacity(disk, capacity);
578+ check_disk_size_change(disk, bdev);
579+ bdev->bd_invalidated = 0;
580+ }
581+ goto try_scan;
582+ } else {
583+ /*
584+ * we can not ignore partitions of broken tables
585+ * created by for example camera firmware, but
586+ * we limit them to the end of the disk to avoid
587+ * creating invalid block devices
588+ */
589+ printk(KERN_CONT "limited to end of disk\n");
590+ size = get_capacity(disk) - from;
591+ }
571592 }
572593 part = add_partition(disk, p, from, size,
573594 state->parts[p].flags);
include/linux/blkdev.h+2−0
@@ -1106,6 +1106,8 @@ struct block_device_operations { · 1105 unmodified lines
11061106 int (*direct_access) (struct block_device *, sector_t,
11071107 void **, unsigned long *);
11081108 int (*media_changed) (struct gendisk *);
1109+ unsigned long long (*set_capacity) (struct gendisk *,
1110+ unsigned long long);
11091111 int (*revalidate_disk) (struct gendisk *);
11101112 int (*getgeo)(struct block_device *, struct hd_geometry *);
11111113 struct module *owner;
include/linux/genhd.h+1−0
@@ -113,6 +113,7 @@ struct hd_struct { · 112 unmodified lines
113113 #define GENHD_FL_UP 16
114114 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32
115115 #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */
116+#define GENHD_FL_NATIVE_CAPACITY 128
116117
117118 #define BLK_SCSI_MAX_CMDS (256)
118119 #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t