linux-stable/fs/partitions/sgi.c
Fabio Massimo Di Nitto d18d7682c1 [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>
2007-02-10 23:50:00 -08:00

82 lines
2.2 KiB
C

/*
* fs/partitions/sgi.c
*
* Code extracted from drivers/block/genhd.c
*/
#include "check.h"
#include "sgi.h"
struct sgi_disklabel {
__be32 magic_mushroom; /* Big fat spliff... */
__be16 root_part_num; /* Root partition number */
__be16 swap_part_num; /* Swap partition number */
s8 boot_file[16]; /* Name of boot file for ARCS */
u8 _unused0[48]; /* Device parameter useless crapola.. */
struct sgi_volume {
s8 name[8]; /* Name of volume */
__be32 block_num; /* Logical block number */
__be32 num_bytes; /* How big, in bytes */
} volume[15];
struct sgi_partition {
__be32 num_blocks; /* Size in logical blocks */
__be32 first_block; /* First logical block */
__be32 type; /* Type of this partition */
} partitions[16];
__be32 csum; /* Disk label checksum */
__be32 _unused1; /* Padding */
};
int sgi_partition(struct parsed_partitions *state, struct block_device *bdev)
{
int i, csum;
__be32 magic;
int slot = 1;
unsigned int start, blocks;
__be32 *ui, cs;
Sector sect;
struct sgi_disklabel *label;
struct sgi_partition *p;
char b[BDEVNAME_SIZE];
label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, &sect);
if (!label)
return -1;
p = &label->partitions[0];
magic = label->magic_mushroom;
if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
/*printk("Dev %s SGI disklabel: bad magic %08x\n",
bdevname(bdev, b), be32_to_cpu(magic));*/
put_dev_sector(sect);
return 0;
}
ui = ((__be32 *) (label + 1)) - 1;
for(csum = 0; ui >= ((__be32 *) label);) {
cs = *ui--;
csum += be32_to_cpu(cs);
}
if(csum) {
printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n",
bdevname(bdev, b));
put_dev_sector(sect);
return 0;
}
/* All SGI disk labels have 16 partitions, disks under Linux only
* have 15 minor's. Luckily there are always a few zero length
* partitions which we don't care about so we never overflow the
* current_minor.
*/
for(i = 0; i < 16; i++, p++) {
blocks = be32_to_cpu(p->num_blocks);
start = be32_to_cpu(p->first_block);
if (blocks) {
put_partition(state, slot, start, blocks);
if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION)
state->parts[slot].flags = ADDPART_FLAG_RAID;
}
slot++;
}
printk("\n");
put_dev_sector(sect);
return 1;
}