Skip to content

Commit

Permalink
[PARTITION]: Add whole_disk attribute.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Fabio Massimo Di Nitto authored and David S. Miller committed Feb 11, 2007
1 parent 66efc5a commit d18d768
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 8 deletions.
2 changes: 1 addition & 1 deletion block/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
}
}
/* all seems OK */
add_partition(disk, part, start, length);
add_partition(disk, part, start, length, ADDPART_FLAG_NONE);
mutex_unlock(&bdev->bd_mutex);
return 0;
case BLKPG_DEL_PARTITION:
Expand Down
15 changes: 12 additions & 3 deletions fs/partitions/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ void delete_partition(struct gendisk *disk, int part)
kobject_put(&p->kobj);
}

void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags)
{
struct hd_struct *p;

Expand All @@ -390,6 +390,15 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
if (!disk->part_uevent_suppress)
kobject_uevent(&p->kobj, KOBJ_ADD);
sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
if (flags & ADDPART_FLAG_WHOLEDISK) {
static struct attribute addpartattr = {
.name = "whole_disk",
.mode = S_IRUSR | S_IRGRP | S_IROTH,
.owner = THIS_MODULE,
};

sysfs_create_file(&p->kobj, &addpartattr);
}
partition_sysfs_add_subdir(p);
disk->part[part-1] = p;
}
Expand Down Expand Up @@ -543,9 +552,9 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
printk(" %s: p%d exceeds device capacity\n",
disk->disk_name, p);
}
add_partition(disk, p, from, size);
add_partition(disk, p, from, size, state->parts[p].flags);
#ifdef CONFIG_BLK_DEV_MD
if (state->parts[p].flags)
if (state->parts[p].flags & ADDPART_FLAG_RAID)
md_autodetect_dev(bdev->bd_dev+p);
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion fs/partitions/msdos.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,

put_partition(state, state->next, next, size);
if (SYS_IND(p) == LINUX_RAID_PARTITION)
state->parts[state->next].flags = 1;
state->parts[state->next].flags = ADDPART_FLAG_RAID;
loopct = 0;
if (++state->next == state->limit)
goto done;
Expand Down
2 changes: 1 addition & 1 deletion fs/partitions/sgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int sgi_partition(struct parsed_partitions *state, struct block_device *bdev)
if (blocks) {
put_partition(state, slot, start, blocks);
if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION)
state->parts[slot].flags = 1;
state->parts[slot].flags = ADDPART_FLAG_RAID;
}
slot++;
}
Expand Down
5 changes: 4 additions & 1 deletion fs/partitions/sun.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev)
num_sectors = be32_to_cpu(p->num_sectors);
if (num_sectors) {
put_partition(state, slot, st_sector, num_sectors);
state->parts[slot].flags = 0;
if (label->infos[i].id == LINUX_RAID_PARTITION)
state->parts[slot].flags = 1;
state->parts[slot].flags |= ADDPART_FLAG_RAID;
if (label->infos[i].id == SUN_WHOLE_DISK)
state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK;
}
slot++;
}
Expand Down
8 changes: 7 additions & 1 deletion include/linux/genhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ enum {
LINUX_EXTENDED_PARTITION = 0x85,
WIN98_EXTENDED_PARTITION = 0x0f,

SUN_WHOLE_DISK = DOS_EXTENDED_PARTITION,

LINUX_SWAP_PARTITION = 0x82,
LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */

Expand Down Expand Up @@ -400,10 +402,14 @@ struct unixware_disklabel {

#ifdef __KERNEL__

#define ADDPART_FLAG_NONE 0
#define ADDPART_FLAG_RAID 1
#define ADDPART_FLAG_WHOLEDISK 2

char *disk_name (struct gendisk *hd, int part, char *buf);

extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
extern void add_partition(struct gendisk *, int, sector_t, sector_t);
extern void add_partition(struct gendisk *, int, sector_t, sector_t, int);
extern void delete_partition(struct gendisk *, int);

extern struct gendisk *alloc_disk_node(int minors, int node_id);
Expand Down

0 comments on commit d18d768

Please sign in to comment.