Commit d18d7682c18b617f523df6beea5ea0bd396ed0bd

Authored by Fabio Massimo Di Nitto
Committed by David S. Miller
1 parent 66efc5a7e3

[PARTITION]: Add whole_disk attribute.

Some partitioning systems create special partitions that
span the entire disk.  One example are Sun partitions, and
this whole-disk partition exists to tell the firmware the
extent of the entire device so it can load the boot block
and do other things.

Such partitions should not be treated as normal partitions,
because all the other partitions overlap this whole-disk one.
So we'd see multiple instances of the same UUID etc. which
we do not want.  udev and friends can thus search for this
'whole_disk' attribute and use it to decide to ignore the
partition.

Signed-off-by: Fabio Massimo Di Nitto <fabbione@ubuntu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 6 changed files with 26 additions and 8 deletions Side-by-side Diff

... ... @@ -61,7 +61,7 @@
61 61 }
62 62 }
63 63 /* all seems OK */
64   - add_partition(disk, part, start, length);
  64 + add_partition(disk, part, start, length, ADDPART_FLAG_NONE);
65 65 mutex_unlock(&bdev->bd_mutex);
66 66 return 0;
67 67 case BLKPG_DEL_PARTITION:
fs/partitions/check.c
... ... @@ -365,7 +365,7 @@
365 365 kobject_put(&p->kobj);
366 366 }
367 367  
368   -void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
  368 +void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags)
369 369 {
370 370 struct hd_struct *p;
371 371  
... ... @@ -390,6 +390,15 @@
390 390 if (!disk->part_uevent_suppress)
391 391 kobject_uevent(&p->kobj, KOBJ_ADD);
392 392 sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
  393 + if (flags & ADDPART_FLAG_WHOLEDISK) {
  394 + static struct attribute addpartattr = {
  395 + .name = "whole_disk",
  396 + .mode = S_IRUSR | S_IRGRP | S_IROTH,
  397 + .owner = THIS_MODULE,
  398 + };
  399 +
  400 + sysfs_create_file(&p->kobj, &addpartattr);
  401 + }
393 402 partition_sysfs_add_subdir(p);
394 403 disk->part[part-1] = p;
395 404 }
396 405  
... ... @@ -543,9 +552,9 @@
543 552 printk(" %s: p%d exceeds device capacity\n",
544 553 disk->disk_name, p);
545 554 }
546   - add_partition(disk, p, from, size);
  555 + add_partition(disk, p, from, size, state->parts[p].flags);
547 556 #ifdef CONFIG_BLK_DEV_MD
548   - if (state->parts[p].flags)
  557 + if (state->parts[p].flags & ADDPART_FLAG_RAID)
549 558 md_autodetect_dev(bdev->bd_dev+p);
550 559 #endif
551 560 }
fs/partitions/msdos.c
... ... @@ -155,7 +155,7 @@
155 155  
156 156 put_partition(state, state->next, next, size);
157 157 if (SYS_IND(p) == LINUX_RAID_PARTITION)
158   - state->parts[state->next].flags = 1;
  158 + state->parts[state->next].flags = ADDPART_FLAG_RAID;
159 159 loopct = 0;
160 160 if (++state->next == state->limit)
161 161 goto done;
... ... @@ -72,7 +72,7 @@
72 72 if (blocks) {
73 73 put_partition(state, slot, start, blocks);
74 74 if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION)
75   - state->parts[slot].flags = 1;
  75 + state->parts[slot].flags = ADDPART_FLAG_RAID;
76 76 }
77 77 slot++;
78 78 }
... ... @@ -80,8 +80,11 @@
80 80 num_sectors = be32_to_cpu(p->num_sectors);
81 81 if (num_sectors) {
82 82 put_partition(state, slot, st_sector, num_sectors);
  83 + state->parts[slot].flags = 0;
83 84 if (label->infos[i].id == LINUX_RAID_PARTITION)
84   - state->parts[slot].flags = 1;
  85 + state->parts[slot].flags |= ADDPART_FLAG_RAID;
  86 + if (label->infos[i].id == SUN_WHOLE_DISK)
  87 + state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK;
85 88 }
86 89 slot++;
87 90 }
include/linux/genhd.h
... ... @@ -20,6 +20,8 @@
20 20 LINUX_EXTENDED_PARTITION = 0x85,
21 21 WIN98_EXTENDED_PARTITION = 0x0f,
22 22  
  23 + SUN_WHOLE_DISK = DOS_EXTENDED_PARTITION,
  24 +
23 25 LINUX_SWAP_PARTITION = 0x82,
24 26 LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */
25 27  
26 28  
... ... @@ -400,10 +402,14 @@
400 402  
401 403 #ifdef __KERNEL__
402 404  
  405 +#define ADDPART_FLAG_NONE 0
  406 +#define ADDPART_FLAG_RAID 1
  407 +#define ADDPART_FLAG_WHOLEDISK 2
  408 +
403 409 char *disk_name (struct gendisk *hd, int part, char *buf);
404 410  
405 411 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
406   -extern void add_partition(struct gendisk *, int, sector_t, sector_t);
  412 +extern void add_partition(struct gendisk *, int, sector_t, sector_t, int);
407 413 extern void delete_partition(struct gendisk *, int);
408 414  
409 415 extern struct gendisk *alloc_disk_node(int minors, int node_id);