diff options
-rw-r--r-- | fs/partitions/sun.c | 62 | ||||
-rw-r--r-- | fs/partitions/sun.h | 1 |
2 files changed, 46 insertions, 17 deletions
diff --git a/fs/partitions/sun.c b/fs/partitions/sun.c index 123f8b46c8ba..794118da4ef3 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) | |||
19 | Sector sect; | 19 | Sector sect; |
20 | struct sun_disklabel { | 20 | struct sun_disklabel { |
21 | unsigned char info[128]; /* Informative text string */ | 21 | unsigned char info[128]; /* Informative text string */ |
22 | unsigned char spare0[14]; | 22 | struct sun_vtoc { |
23 | struct sun_info { | 23 | __be32 version; /* Layout version */ |
24 | unsigned char spare1; | 24 | char volume[8]; /* Volume name */ |
25 | unsigned char id; | 25 | __be16 nparts; /* Number of partitions */ |
26 | unsigned char spare2; | 26 | struct sun_info { /* Partition hdrs, sec 2 */ |
27 | unsigned char flags; | 27 | __be16 id; |
28 | } infos[8]; | 28 | __be16 flags; |
29 | unsigned char spare[246]; /* Boot information etc. */ | 29 | } infos[8]; |
30 | __be16 padding; /* Alignment padding */ | ||
31 | __be32 bootinfo[3]; /* Info needed by mboot */ | ||
32 | __be32 sanity; /* To verify vtoc sanity */ | ||
33 | __be32 reserved[10]; /* Free space */ | ||
34 | __be32 timestamp[8]; /* Partition timestamp */ | ||
35 | } vtoc; | ||
36 | __be32 write_reinstruct; /* sectors to skip, writes */ | ||
37 | __be32 read_reinstruct; /* sectors to skip, reads */ | ||
38 | unsigned char spare[148]; /* Padding */ | ||
30 | __be16 rspeed; /* Disk rotational speed */ | 39 | __be16 rspeed; /* Disk rotational speed */ |
31 | __be16 pcylcount; /* Physical cylinder count */ | 40 | __be16 pcylcount; /* Physical cylinder count */ |
32 | __be16 sparecyl; /* extra sects per cylinder */ | 41 | __be16 sparecyl; /* extra sects per cylinder */ |
33 | unsigned char spare2[4]; /* More magic... */ | 42 | __be16 obs1; /* gap1 */ |
43 | __be16 obs2; /* gap2 */ | ||
34 | __be16 ilfact; /* Interleave factor */ | 44 | __be16 ilfact; /* Interleave factor */ |
35 | __be16 ncyl; /* Data cylinder count */ | 45 | __be16 ncyl; /* Data cylinder count */ |
36 | __be16 nacyl; /* Alt. cylinder count */ | 46 | __be16 nacyl; /* Alt. cylinder count */ |
37 | __be16 ntrks; /* Tracks per cylinder */ | 47 | __be16 ntrks; /* Tracks per cylinder */ |
38 | __be16 nsect; /* Sectors per track */ | 48 | __be16 nsect; /* Sectors per track */ |
39 | unsigned char spare3[4]; /* Even more magic... */ | 49 | __be16 obs3; /* bhead - Label head offset */ |
50 | __be16 obs4; /* ppart - Physical Partition */ | ||
40 | struct sun_partition { | 51 | struct sun_partition { |
41 | __be32 start_cylinder; | 52 | __be32 start_cylinder; |
42 | __be32 num_sectors; | 53 | __be32 num_sectors; |
43 | } partitions[8]; | 54 | } partitions[8]; |
44 | __be16 magic; /* Magic number */ | 55 | __be16 magic; /* Magic number */ |
45 | __be16 csum; /* Label xor'd checksum */ | 56 | __be16 csum; /* Label xor'd checksum */ |
46 | } * label; | 57 | } * label; |
47 | struct sun_partition *p; | 58 | struct sun_partition *p; |
48 | unsigned long spc; | 59 | unsigned long spc; |
49 | char b[BDEVNAME_SIZE]; | 60 | char b[BDEVNAME_SIZE]; |
61 | int use_vtoc; | ||
62 | int nparts; | ||
50 | 63 | ||
51 | label = (struct sun_disklabel *)read_dev_sector(bdev, 0, §); | 64 | label = (struct sun_disklabel *)read_dev_sector(bdev, 0, §); |
52 | if (!label) | 65 | if (!label) |
@@ -70,9 +83,22 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
70 | return 0; | 83 | return 0; |
71 | } | 84 | } |
72 | 85 | ||
73 | /* All Sun disks have 8 partition entries */ | 86 | /* Check to see if we can use the VTOC table */ |
87 | use_vtoc = ((be32_to_cpu(label->vtoc.sanity) == SUN_VTOC_SANITY) && | ||
88 | (be32_to_cpu(label->vtoc.version) == 1) && | ||
89 | (be16_to_cpu(label->vtoc.nparts) <= 8)); | ||
90 | |||
91 | /* Use 8 partition entries if not specified in validated VTOC */ | ||
92 | nparts = (use_vtoc) ? be16_to_cpu(label->vtoc.nparts) : 8; | ||
93 | |||
94 | /* | ||
95 | * So that old Linux-Sun partitions continue to work, | ||
96 | * alow the VTOC to be used under the additional condition ... | ||
97 | */ | ||
98 | use_vtoc = use_vtoc || !(label->vtoc.sanity | | ||
99 | label->vtoc.version | label->vtoc.nparts); | ||
74 | spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); | 100 | spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); |
75 | for (i = 0; i < 8; i++, p++) { | 101 | for (i = 0; i < nparts; i++, p++) { |
76 | unsigned long st_sector; | 102 | unsigned long st_sector; |
77 | unsigned int num_sectors; | 103 | unsigned int num_sectors; |
78 | 104 | ||
@@ -81,10 +107,12 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
81 | if (num_sectors) { | 107 | if (num_sectors) { |
82 | put_partition(state, slot, st_sector, num_sectors); | 108 | put_partition(state, slot, st_sector, num_sectors); |
83 | state->parts[slot].flags = 0; | 109 | state->parts[slot].flags = 0; |
84 | if (label->infos[i].id == LINUX_RAID_PARTITION) | 110 | if (use_vtoc) { |
85 | state->parts[slot].flags |= ADDPART_FLAG_RAID; | 111 | if (be16_to_cpu(label->vtoc.infos[i].id) == LINUX_RAID_PARTITION) |
86 | if (label->infos[i].id == SUN_WHOLE_DISK) | 112 | state->parts[slot].flags |= ADDPART_FLAG_RAID; |
87 | state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK; | 113 | else if (be16_to_cpu(label->vtoc.infos[i].id) == SUN_WHOLE_DISK) |
114 | state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK; | ||
115 | } | ||
88 | } | 116 | } |
89 | slot++; | 117 | slot++; |
90 | } | 118 | } |
diff --git a/fs/partitions/sun.h b/fs/partitions/sun.h index b1b19fda7b22..7f864d1f86d4 100644 --- a/fs/partitions/sun.h +++ b/fs/partitions/sun.h | |||
@@ -3,5 +3,6 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #define SUN_LABEL_MAGIC 0xDABE | 5 | #define SUN_LABEL_MAGIC 0xDABE |
6 | #define SUN_VTOC_SANITY 0x600DDEEE | ||
6 | 7 | ||
7 | int sun_partition(struct parsed_partitions *state, struct block_device *bdev); | 8 | int sun_partition(struct parsed_partitions *state, struct block_device *bdev); |