summaryrefslogtreecommitdiffstats
path: root/fs/partitions
diff options
context:
space:
mode:
Diffstat (limited to 'fs/partitions')
-rw-r--r--fs/partitions/check.c15
-rw-r--r--fs/partitions/msdos.c5
-rw-r--r--fs/partitions/sun.c62
-rw-r--r--fs/partitions/sun.h1
4 files changed, 58 insertions, 25 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 98e0b85a9bb..722e12e5acc 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -372,20 +372,21 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
{
struct hd_struct *p;
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (!p)
return;
- memset(p, 0, sizeof(*p));
p->start_sect = start;
p->nr_sects = len;
p->partno = part;
p->policy = disk->policy;
- if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1]))
- snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part);
+ if (isdigit(disk->kobj.k_name[strlen(disk->kobj.k_name)-1]))
+ kobject_set_name(&p->kobj, "%sp%d",
+ kobject_name(&disk->kobj), part);
else
- snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part);
+ kobject_set_name(&p->kobj, "%s%d",
+ kobject_name(&disk->kobj),part);
p->kobj.parent = &disk->kobj;
p->kobj.ktype = &ktype_part;
kobject_init(&p->kobj);
@@ -478,9 +479,9 @@ void register_disk(struct gendisk *disk)
struct hd_struct *p;
int err;
- strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN);
+ kobject_set_name(&disk->kobj, "%s", disk->disk_name);
/* ewww... some of these buggers have / in name... */
- s = strchr(disk->kobj.name, '/');
+ s = strchr(disk->kobj.k_name, '/');
if (s)
*s = '!';
if ((err = kobject_add(&disk->kobj)))
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 4ccec4cd136..5567ec0d03a 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -203,6 +203,7 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
Sector sect;
struct solaris_x86_vtoc *v;
int i;
+ short max_nparts;
v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, &sect);
if (!v)
@@ -218,7 +219,9 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
put_dev_sector(sect);
return;
}
- for (i=0; i<SOLARIS_X86_NUMSLICE && state->next<state->limit; i++) {
+ /* Ensure we can handle previous case of VTOC with 8 entries gracefully */
+ max_nparts = le16_to_cpu (v->v_nparts) > 8 ? SOLARIS_X86_NUMSLICE : 8;
+ for (i=0; i<max_nparts && state->next<state->limit; i++) {
struct solaris_x86_slice *s = &v->v_slice[i];
if (s->s_size == 0)
continue;
diff --git a/fs/partitions/sun.c b/fs/partitions/sun.c
index 123f8b46c8b..794118da4ef 100644
--- a/fs/partitions/sun.c
+++ b/fs/partitions/sun.c
@@ -19,34 +19,47 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev)
Sector sect;
struct sun_disklabel {
unsigned char info[128]; /* Informative text string */
- unsigned char spare0[14];
- struct sun_info {
- unsigned char spare1;
- unsigned char id;
- unsigned char spare2;
- unsigned char flags;
- } infos[8];
- unsigned char spare[246]; /* Boot information etc. */
+ struct sun_vtoc {
+ __be32 version; /* Layout version */
+ char volume[8]; /* Volume name */
+ __be16 nparts; /* Number of partitions */
+ struct sun_info { /* Partition hdrs, sec 2 */
+ __be16 id;
+ __be16 flags;
+ } infos[8];
+ __be16 padding; /* Alignment padding */
+ __be32 bootinfo[3]; /* Info needed by mboot */
+ __be32 sanity; /* To verify vtoc sanity */
+ __be32 reserved[10]; /* Free space */
+ __be32 timestamp[8]; /* Partition timestamp */
+ } vtoc;
+ __be32 write_reinstruct; /* sectors to skip, writes */
+ __be32 read_reinstruct; /* sectors to skip, reads */
+ unsigned char spare[148]; /* Padding */
__be16 rspeed; /* Disk rotational speed */
__be16 pcylcount; /* Physical cylinder count */
__be16 sparecyl; /* extra sects per cylinder */
- unsigned char spare2[4]; /* More magic... */
+ __be16 obs1; /* gap1 */
+ __be16 obs2; /* gap2 */
__be16 ilfact; /* Interleave factor */
__be16 ncyl; /* Data cylinder count */
__be16 nacyl; /* Alt. cylinder count */
__be16 ntrks; /* Tracks per cylinder */
__be16 nsect; /* Sectors per track */
- unsigned char spare3[4]; /* Even more magic... */
+ __be16 obs3; /* bhead - Label head offset */
+ __be16 obs4; /* ppart - Physical Partition */
struct sun_partition {
__be32 start_cylinder;
__be32 num_sectors;
} partitions[8];
__be16 magic; /* Magic number */
__be16 csum; /* Label xor'd checksum */
- } * label;
+ } * label;
struct sun_partition *p;
unsigned long spc;
char b[BDEVNAME_SIZE];
+ int use_vtoc;
+ int nparts;
label = (struct sun_disklabel *)read_dev_sector(bdev, 0, &sect);
if (!label)
@@ -70,9 +83,22 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev)
return 0;
}
- /* All Sun disks have 8 partition entries */
+ /* Check to see if we can use the VTOC table */
+ use_vtoc = ((be32_to_cpu(label->vtoc.sanity) == SUN_VTOC_SANITY) &&
+ (be32_to_cpu(label->vtoc.version) == 1) &&
+ (be16_to_cpu(label->vtoc.nparts) <= 8));
+
+ /* Use 8 partition entries if not specified in validated VTOC */
+ nparts = (use_vtoc) ? be16_to_cpu(label->vtoc.nparts) : 8;
+
+ /*
+ * So that old Linux-Sun partitions continue to work,
+ * alow the VTOC to be used under the additional condition ...
+ */
+ use_vtoc = use_vtoc || !(label->vtoc.sanity |
+ label->vtoc.version | label->vtoc.nparts);
spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
- for (i = 0; i < 8; i++, p++) {
+ for (i = 0; i < nparts; i++, p++) {
unsigned long st_sector;
unsigned int num_sectors;
@@ -81,10 +107,12 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev)
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 |= ADDPART_FLAG_RAID;
- if (label->infos[i].id == SUN_WHOLE_DISK)
- state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK;
+ if (use_vtoc) {
+ if (be16_to_cpu(label->vtoc.infos[i].id) == LINUX_RAID_PARTITION)
+ state->parts[slot].flags |= ADDPART_FLAG_RAID;
+ else if (be16_to_cpu(label->vtoc.infos[i].id) == SUN_WHOLE_DISK)
+ state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK;
+ }
}
slot++;
}
diff --git a/fs/partitions/sun.h b/fs/partitions/sun.h
index b1b19fda7b2..7f864d1f86d 100644
--- a/fs/partitions/sun.h
+++ b/fs/partitions/sun.h
@@ -3,5 +3,6 @@
*/
#define SUN_LABEL_MAGIC 0xDABE
+#define SUN_VTOC_SANITY 0x600DDEEE
int sun_partition(struct parsed_partitions *state, struct block_device *bdev);