Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / fs / partitions / msdos.c
1 /*
2  *  fs/partitions/msdos.c
3  *
4  *  Code extracted from drivers/block/genhd.c
5  *  Copyright (C) 1991-1998  Linus Torvalds
6  *
7  *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
8  *  in the early extended-partition checks and added DM partitions
9  *
10  *  Support for DiskManager v6.0x added by Mark Lord,
11  *  with information provided by OnTrack.  This now works for linux fdisk
12  *  and LILO, as well as loadlin and bootln.  Note that disks other than
13  *  /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
14  *
15  *  More flexible handling of extended partitions - aeb, 950831
16  *
17  *  Check partition table on IDE disks for common CHS translations
18  *
19  *  Re-organised Feb 1998 Russell King
20  */
21
22 #include <linux/config.h>
23
24 #include "check.h"
25 #include "msdos.h"
26 #include "efi.h"
27
28 /*
29  * Many architectures don't like unaligned accesses, while
30  * the nr_sects and start_sect partition table entries are
31  * at a 2 (mod 4) address.
32  */
33 #include <asm/unaligned.h>
34
35 #define SYS_IND(p)      (get_unaligned(&p->sys_ind))
36 #define NR_SECTS(p)     ({ __typeof__(p->nr_sects) __a =        \
37                                 get_unaligned(&p->nr_sects);    \
38                                 le32_to_cpu(__a); \
39                         })
40
41 #define START_SECT(p)   ({ __typeof__(p->start_sect) __a =      \
42                                 get_unaligned(&p->start_sect);  \
43                                 le32_to_cpu(__a); \
44                         })
45
46 static inline int is_extended_partition(struct partition *p)
47 {
48         return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
49                 SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
50                 SYS_IND(p) == LINUX_EXTENDED_PARTITION);
51 }
52
53 #define MSDOS_LABEL_MAGIC1      0x55
54 #define MSDOS_LABEL_MAGIC2      0xAA
55
56 static inline int
57 msdos_magic_present(unsigned char *p)
58 {
59         return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2);
60 }
61
62 /*
63  * Create devices for each logical partition in an extended partition.
64  * The logical partitions form a linked list, with each entry being
65  * a partition table with two entries.  The first entry
66  * is the real data partition (with a start relative to the partition
67  * table start).  The second is a pointer to the next logical partition
68  * (with a start relative to the entire extended partition).
69  * We do not create a Linux partition for the partition tables, but
70  * only for the actual data partitions.
71  */
72
73 static void
74 parse_extended(struct parsed_partitions *state, struct block_device *bdev,
75                         u32 first_sector, u32 first_size)
76 {
77         struct partition *p;
78         Sector sect;
79         unsigned char *data;
80         u32 this_sector, this_size;
81         int sector_size = bdev_hardsect_size(bdev) / 512;
82         int loopct = 0;         /* number of links followed
83                                    without finding a data partition */
84         int i;
85
86         this_sector = first_sector;
87         this_size = first_size;
88
89         while (1) {
90                 if (++loopct > 100)
91                         return;
92                 if (state->next == state->limit)
93                         return;
94                 data = read_dev_sector(bdev, this_sector, &sect);
95                 if (!data)
96                         return;
97
98                 if (!msdos_magic_present(data + 510))
99                         goto done; 
100
101                 p = (struct partition *) (data + 0x1be);
102
103                 /*
104                  * Usually, the first entry is the real data partition,
105                  * the 2nd entry is the next extended partition, or empty,
106                  * and the 3rd and 4th entries are unused.
107                  * However, DRDOS sometimes has the extended partition as
108                  * the first entry (when the data partition is empty),
109                  * and OS/2 seems to use all four entries.
110                  */
111
112                 /* 
113                  * First process the data partition(s)
114                  */
115                 for (i=0; i<4; i++, p++) {
116                         u32 offs, size, next;
117
118                         if (SYS_IND(p) == 0)
119                                 continue;
120                         if (!NR_SECTS(p) || is_extended_partition(p))
121                                 continue;
122
123                         /* Check the 3rd and 4th entries -
124                            these sometimes contain random garbage */
125                         offs = START_SECT(p)*sector_size;
126                         size = NR_SECTS(p)*sector_size;
127                         next = this_sector + offs;
128                         if (i >= 2) {
129                                 if (offs + size > this_size)
130                                         continue;
131                                 if (next < first_sector)
132                                         continue;
133                                 if (next + size > first_sector + first_size)
134                                         continue;
135                         }
136
137                         put_partition(state, state->next, next, size);
138                         if (SYS_IND(p) == LINUX_RAID_PARTITION)
139                                 state->parts[state->next].flags = 1;
140                         loopct = 0;
141                         if (++state->next == state->limit)
142                                 goto done;
143                 }
144                 /*
145                  * Next, process the (first) extended partition, if present.
146                  * (So far, there seems to be no reason to make
147                  *  parse_extended()  recursive and allow a tree
148                  *  of extended partitions.)
149                  * It should be a link to the next logical partition.
150                  */
151                 p -= 4;
152                 for (i=0; i<4; i++, p++)
153                         if (NR_SECTS(p) && is_extended_partition(p))
154                                 break;
155                 if (i == 4)
156                         goto done;       /* nothing left to do */
157
158                 this_sector = first_sector + START_SECT(p) * sector_size;
159                 this_size = NR_SECTS(p) * sector_size;
160                 put_dev_sector(sect);
161         }
162 done:
163         put_dev_sector(sect);
164 }
165
166 /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also
167    indicates linux swap.  Be careful before believing this is Solaris. */
168
169 static void
170 parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
171                         u32 offset, u32 size, int origin)
172 {
173 #ifdef CONFIG_SOLARIS_X86_PARTITION
174         Sector sect;
175         struct solaris_x86_vtoc *v;
176         int i;
177
178         v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, &sect);
179         if (!v)
180                 return;
181         if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) {
182                 put_dev_sector(sect);
183                 return;
184         }
185         printk(" %s%d: <solaris:", state->name, origin);
186         if (le32_to_cpu(v->v_version) != 1) {
187                 printk("  cannot handle version %d vtoc>\n",
188                         le32_to_cpu(v->v_version));
189                 put_dev_sector(sect);
190                 return;
191         }
192         for (i=0; i<SOLARIS_X86_NUMSLICE && state->next<state->limit; i++) {
193                 struct solaris_x86_slice *s = &v->v_slice[i];
194                 if (s->s_size == 0)
195                         continue;
196                 printk(" [s%d]", i);
197                 /* solaris partitions are relative to current MS-DOS
198                  * one; must add the offset of the current partition */
199                 put_partition(state, state->next++,
200                                  le32_to_cpu(s->s_start)+offset,
201                                  le32_to_cpu(s->s_size));
202         }
203         put_dev_sector(sect);
204         printk(" >\n");
205 #endif
206 }
207
208 #if defined(CONFIG_BSD_DISKLABEL) || defined(CONFIG_NEC98_PARTITION)
209 /* 
210  * Create devices for BSD partitions listed in a disklabel, under a
211  * dos-like partition. See parse_extended() for more information.
212  */
213 void
214 parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
215                 u32 offset, u32 size, int origin, char *flavour,
216                 int max_partitions)
217 {
218         Sector sect;
219         struct bsd_disklabel *l;
220         struct bsd_partition *p;
221
222         l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, &sect);
223         if (!l)
224                 return;
225         if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) {
226                 put_dev_sector(sect);
227                 return;
228         }
229         printk(" %s%d: <%s:", state->name, origin, flavour);
230
231         if (le16_to_cpu(l->d_npartitions) < max_partitions)
232                 max_partitions = le16_to_cpu(l->d_npartitions);
233         for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
234                 u32 bsd_start, bsd_size;
235
236                 if (state->next == state->limit)
237                         break;
238                 if (p->p_fstype == BSD_FS_UNUSED) 
239                         continue;
240                 bsd_start = le32_to_cpu(p->p_offset);
241                 bsd_size = le32_to_cpu(p->p_size);
242                 if (offset == bsd_start && size == bsd_size)
243                         /* full parent partition, we have it already */
244                         continue;
245                 if (offset > bsd_start || offset+size < bsd_start+bsd_size) {
246                         printk("bad subpartition - ignored\n");
247                         continue;
248                 }
249                 put_partition(state, state->next++, bsd_start, bsd_size);
250         }
251         put_dev_sector(sect);
252         if (le16_to_cpu(l->d_npartitions) > max_partitions)
253                 printk(" (ignored %d more)",
254                        le16_to_cpu(l->d_npartitions) - max_partitions);
255         printk(" >\n");
256 }
257 #endif
258
259 static void
260 parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
261                 u32 offset, u32 size, int origin)
262 {
263 #ifdef CONFIG_BSD_DISKLABEL
264         parse_bsd(state, bdev, offset, size, origin,
265                         "bsd", BSD_MAXPARTITIONS);
266 #endif
267 }
268
269 static void
270 parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
271                 u32 offset, u32 size, int origin)
272 {
273 #ifdef CONFIG_BSD_DISKLABEL
274         parse_bsd(state, bdev, offset, size, origin,
275                         "netbsd", BSD_MAXPARTITIONS);
276 #endif
277 }
278
279 static void
280 parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
281                 u32 offset, u32 size, int origin)
282 {
283 #ifdef CONFIG_BSD_DISKLABEL
284         parse_bsd(state, bdev, offset, size, origin,
285                         "openbsd", OPENBSD_MAXPARTITIONS);
286 #endif
287 }
288
289 /*
290  * Create devices for Unixware partitions listed in a disklabel, under a
291  * dos-like partition. See parse_extended() for more information.
292  */
293 static void
294 parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
295                 u32 offset, u32 size, int origin)
296 {
297 #ifdef CONFIG_UNIXWARE_DISKLABEL
298         Sector sect;
299         struct unixware_disklabel *l;
300         struct unixware_slice *p;
301
302         l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, &sect);
303         if (!l)
304                 return;
305         if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
306             le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
307                 put_dev_sector(sect);
308                 return;
309         }
310         printk(" %s%d: <unixware:", state->name, origin);
311         p = &l->vtoc.v_slice[1];
312         /* I omit the 0th slice as it is the same as whole disk. */
313         while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
314                 if (state->next == state->limit)
315                         break;
316
317                 if (p->s_label != UNIXWARE_FS_UNUSED)
318                         put_partition(state, state->next++,
319                                                 START_SECT(p), NR_SECTS(p));
320                 p++;
321         }
322         put_dev_sector(sect);
323         printk(" >\n");
324 #endif
325 }
326
327 /*
328  * Minix 2.0.0/2.0.2 subpartition support.
329  * Anand Krishnamurthy <anandk@wiproge.med.ge.com>
330  * Rajeev V. Pillai    <rajeevvp@yahoo.com>
331  */
332 static void
333 parse_minix(struct parsed_partitions *state, struct block_device *bdev,
334                 u32 offset, u32 size, int origin)
335 {
336 #ifdef CONFIG_MINIX_SUBPARTITION
337         Sector sect;
338         unsigned char *data;
339         struct partition *p;
340         int i;
341
342         data = read_dev_sector(bdev, offset, &sect);
343         if (!data)
344                 return;
345
346         p = (struct partition *)(data + 0x1be);
347
348         /* The first sector of a Minix partition can have either
349          * a secondary MBR describing its subpartitions, or
350          * the normal boot sector. */
351         if (msdos_magic_present (data + 510) &&
352             SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
353
354                 printk(" %s%d: <minix:", state->name, origin);
355                 for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
356                         if (state->next == state->limit)
357                                 break;
358                         /* add each partition in use */
359                         if (SYS_IND(p) == MINIX_PARTITION)
360                                 put_partition(state, state->next++,
361                                               START_SECT(p), NR_SECTS(p));
362                 }
363                 printk(" >\n");
364         }
365         put_dev_sector(sect);
366 #endif /* CONFIG_MINIX_SUBPARTITION */
367 }
368
369 static struct {
370         unsigned char id;
371         void (*parse)(struct parsed_partitions *, struct block_device *,
372                         u32, u32, int);
373 } subtypes[] = {
374         {FREEBSD_PARTITION, parse_freebsd},
375         {NETBSD_PARTITION, parse_netbsd},
376         {OPENBSD_PARTITION, parse_openbsd},
377         {MINIX_PARTITION, parse_minix},
378         {UNIXWARE_PARTITION, parse_unixware},
379         {SOLARIS_X86_PARTITION, parse_solaris_x86},
380         {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
381         {0, NULL},
382 };
383  
384 int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
385 {
386         int sector_size = bdev_hardsect_size(bdev) / 512;
387         Sector sect;
388         unsigned char *data;
389         struct partition *p;
390         int slot;
391
392         data = read_dev_sector(bdev, 0, &sect);
393         if (!data)
394                 return -1;
395         if (!msdos_magic_present(data + 510)) {
396                 put_dev_sector(sect);
397                 return 0;
398         }
399
400         /*
401          * Now that the 55aa signature is present, this is probably
402          * either the boot sector of a FAT filesystem or a DOS-type
403          * partition table. Reject this in case the boot indicator
404          * is not 0 or 0x80.
405          */
406         p = (struct partition *) (data + 0x1be);
407         for (slot = 1; slot <= 4; slot++, p++) {
408                 if (p->boot_ind != 0 && p->boot_ind != 0x80) {
409                         put_dev_sector(sect);
410                         return 0;
411                 }
412         }
413
414 #ifdef CONFIG_EFI_PARTITION
415         p = (struct partition *) (data + 0x1be);
416         for (slot = 1 ; slot <= 4 ; slot++, p++) {
417                 /* If this is an EFI GPT disk, msdos should ignore it. */
418                 if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
419                         put_dev_sector(sect);
420                         return 0;
421                 }
422         }
423 #endif
424         p = (struct partition *) (data + 0x1be);
425
426         /*
427          * Look for partitions in two passes:
428          * First find the primary and DOS-type extended partitions.
429          * On the second pass look inside *BSD, Unixware and Solaris partitions.
430          */
431
432         state->next = 5;
433         for (slot = 1 ; slot <= 4 ; slot++, p++) {
434                 u32 start = START_SECT(p)*sector_size;
435                 u32 size = NR_SECTS(p)*sector_size;
436                 if (SYS_IND(p) == 0)
437                         continue;
438                 if (!size)
439                         continue;
440                 if (is_extended_partition(p)) {
441                         /* prevent someone doing mkfs or mkswap on an
442                            extended partition, but leave room for LILO */
443                         put_partition(state, slot, start, size == 1 ? 1 : 2);
444                         printk(" <");
445                         parse_extended(state, bdev, start, size);
446                         printk(" >");
447                         continue;
448                 }
449                 put_partition(state, slot, start, size);
450                 if (SYS_IND(p) == LINUX_RAID_PARTITION)
451                         state->parts[slot].flags = 1;
452                 if (SYS_IND(p) == DM6_PARTITION)
453                         printk("[DM]");
454                 if (SYS_IND(p) == EZD_PARTITION)
455                         printk("[EZD]");
456         }
457
458         printk("\n");
459
460         /* second pass - output for each on a separate line */
461         p = (struct partition *) (0x1be + data);
462         for (slot = 1 ; slot <= 4 ; slot++, p++) {
463                 unsigned char id = SYS_IND(p);
464                 int n;
465
466                 if (!NR_SECTS(p))
467                         continue;
468
469                 for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
470                         ;
471
472                 if (!subtypes[n].parse)
473                         continue;
474                 subtypes[n].parse(state, bdev, START_SECT(p)*sector_size,
475                                                 NR_SECTS(p)*sector_size, slot);
476         }
477         put_dev_sector(sect);
478         return 1;
479 }