Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6] / 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                         if (!NR_SECTS(p) || is_extended_partition(p))
118                                 continue;
119
120                         /* Check the 3rd and 4th entries -
121                            these sometimes contain random garbage */
122                         offs = START_SECT(p)*sector_size;
123                         size = NR_SECTS(p)*sector_size;
124                         next = this_sector + offs;
125                         if (i >= 2) {
126                                 if (offs + size > this_size)
127                                         continue;
128                                 if (next < first_sector)
129                                         continue;
130                                 if (next + size > first_sector + first_size)
131                                         continue;
132                         }
133
134                         put_partition(state, state->next, next, size);
135                         if (SYS_IND(p) == LINUX_RAID_PARTITION)
136                                 state->parts[state->next].flags = 1;
137                         loopct = 0;
138                         if (++state->next == state->limit)
139                                 goto done;
140                 }
141                 /*
142                  * Next, process the (first) extended partition, if present.
143                  * (So far, there seems to be no reason to make
144                  *  parse_extended()  recursive and allow a tree
145                  *  of extended partitions.)
146                  * It should be a link to the next logical partition.
147                  */
148                 p -= 4;
149                 for (i=0; i<4; i++, p++)
150                         if (NR_SECTS(p) && is_extended_partition(p))
151                                 break;
152                 if (i == 4)
153                         goto done;       /* nothing left to do */
154
155                 this_sector = first_sector + START_SECT(p) * sector_size;
156                 this_size = NR_SECTS(p) * sector_size;
157                 put_dev_sector(sect);
158         }
159 done:
160         put_dev_sector(sect);
161 }
162
163 /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also
164    indicates linux swap.  Be careful before believing this is Solaris. */
165
166 static void
167 parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
168                         u32 offset, u32 size, int origin)
169 {
170 #ifdef CONFIG_SOLARIS_X86_PARTITION
171         Sector sect;
172         struct solaris_x86_vtoc *v;
173         int i;
174
175         v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, &sect);
176         if (!v)
177                 return;
178         if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) {
179                 put_dev_sector(sect);
180                 return;
181         }
182         printk(" %s%d: <solaris:", state->name, origin);
183         if (le32_to_cpu(v->v_version) != 1) {
184                 printk("  cannot handle version %d vtoc>\n",
185                         le32_to_cpu(v->v_version));
186                 put_dev_sector(sect);
187                 return;
188         }
189         for (i=0; i<SOLARIS_X86_NUMSLICE && state->next<state->limit; i++) {
190                 struct solaris_x86_slice *s = &v->v_slice[i];
191                 if (s->s_size == 0)
192                         continue;
193                 printk(" [s%d]", i);
194                 /* solaris partitions are relative to current MS-DOS
195                  * one; must add the offset of the current partition */
196                 put_partition(state, state->next++,
197                                  le32_to_cpu(s->s_start)+offset,
198                                  le32_to_cpu(s->s_size));
199         }
200         put_dev_sector(sect);
201         printk(" >\n");
202 #endif
203 }
204
205 #if defined(CONFIG_BSD_DISKLABEL)
206 /* 
207  * Create devices for BSD partitions listed in a disklabel, under a
208  * dos-like partition. See parse_extended() for more information.
209  */
210 static void
211 parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
212                 u32 offset, u32 size, int origin, char *flavour,
213                 int max_partitions)
214 {
215         Sector sect;
216         struct bsd_disklabel *l;
217         struct bsd_partition *p;
218
219         l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, &sect);
220         if (!l)
221                 return;
222         if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) {
223                 put_dev_sector(sect);
224                 return;
225         }
226         printk(" %s%d: <%s:", state->name, origin, flavour);
227
228         if (le16_to_cpu(l->d_npartitions) < max_partitions)
229                 max_partitions = le16_to_cpu(l->d_npartitions);
230         for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
231                 u32 bsd_start, bsd_size;
232
233                 if (state->next == state->limit)
234                         break;
235                 if (p->p_fstype == BSD_FS_UNUSED) 
236                         continue;
237                 bsd_start = le32_to_cpu(p->p_offset);
238                 bsd_size = le32_to_cpu(p->p_size);
239                 if (offset == bsd_start && size == bsd_size)
240                         /* full parent partition, we have it already */
241                         continue;
242                 if (offset > bsd_start || offset+size < bsd_start+bsd_size) {
243                         printk("bad subpartition - ignored\n");
244                         continue;
245                 }
246                 put_partition(state, state->next++, bsd_start, bsd_size);
247         }
248         put_dev_sector(sect);
249         if (le16_to_cpu(l->d_npartitions) > max_partitions)
250                 printk(" (ignored %d more)",
251                        le16_to_cpu(l->d_npartitions) - max_partitions);
252         printk(" >\n");
253 }
254 #endif
255
256 static void
257 parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
258                 u32 offset, u32 size, int origin)
259 {
260 #ifdef CONFIG_BSD_DISKLABEL
261         parse_bsd(state, bdev, offset, size, origin,
262                         "bsd", BSD_MAXPARTITIONS);
263 #endif
264 }
265
266 static void
267 parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
268                 u32 offset, u32 size, int origin)
269 {
270 #ifdef CONFIG_BSD_DISKLABEL
271         parse_bsd(state, bdev, offset, size, origin,
272                         "netbsd", BSD_MAXPARTITIONS);
273 #endif
274 }
275
276 static void
277 parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
278                 u32 offset, u32 size, int origin)
279 {
280 #ifdef CONFIG_BSD_DISKLABEL
281         parse_bsd(state, bdev, offset, size, origin,
282                         "openbsd", OPENBSD_MAXPARTITIONS);
283 #endif
284 }
285
286 /*
287  * Create devices for Unixware partitions listed in a disklabel, under a
288  * dos-like partition. See parse_extended() for more information.
289  */
290 static void
291 parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
292                 u32 offset, u32 size, int origin)
293 {
294 #ifdef CONFIG_UNIXWARE_DISKLABEL
295         Sector sect;
296         struct unixware_disklabel *l;
297         struct unixware_slice *p;
298
299         l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, &sect);
300         if (!l)
301                 return;
302         if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
303             le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
304                 put_dev_sector(sect);
305                 return;
306         }
307         printk(" %s%d: <unixware:", state->name, origin);
308         p = &l->vtoc.v_slice[1];
309         /* I omit the 0th slice as it is the same as whole disk. */
310         while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
311                 if (state->next == state->limit)
312                         break;
313
314                 if (p->s_label != UNIXWARE_FS_UNUSED)
315                         put_partition(state, state->next++,
316                                                 START_SECT(p), NR_SECTS(p));
317                 p++;
318         }
319         put_dev_sector(sect);
320         printk(" >\n");
321 #endif
322 }
323
324 /*
325  * Minix 2.0.0/2.0.2 subpartition support.
326  * Anand Krishnamurthy <anandk@wiproge.med.ge.com>
327  * Rajeev V. Pillai    <rajeevvp@yahoo.com>
328  */
329 static void
330 parse_minix(struct parsed_partitions *state, struct block_device *bdev,
331                 u32 offset, u32 size, int origin)
332 {
333 #ifdef CONFIG_MINIX_SUBPARTITION
334         Sector sect;
335         unsigned char *data;
336         struct partition *p;
337         int i;
338
339         data = read_dev_sector(bdev, offset, &sect);
340         if (!data)
341                 return;
342
343         p = (struct partition *)(data + 0x1be);
344
345         /* The first sector of a Minix partition can have either
346          * a secondary MBR describing its subpartitions, or
347          * the normal boot sector. */
348         if (msdos_magic_present (data + 510) &&
349             SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
350
351                 printk(" %s%d: <minix:", state->name, origin);
352                 for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
353                         if (state->next == state->limit)
354                                 break;
355                         /* add each partition in use */
356                         if (SYS_IND(p) == MINIX_PARTITION)
357                                 put_partition(state, state->next++,
358                                               START_SECT(p), NR_SECTS(p));
359                 }
360                 printk(" >\n");
361         }
362         put_dev_sector(sect);
363 #endif /* CONFIG_MINIX_SUBPARTITION */
364 }
365
366 static struct {
367         unsigned char id;
368         void (*parse)(struct parsed_partitions *, struct block_device *,
369                         u32, u32, int);
370 } subtypes[] = {
371         {FREEBSD_PARTITION, parse_freebsd},
372         {NETBSD_PARTITION, parse_netbsd},
373         {OPENBSD_PARTITION, parse_openbsd},
374         {MINIX_PARTITION, parse_minix},
375         {UNIXWARE_PARTITION, parse_unixware},
376         {SOLARIS_X86_PARTITION, parse_solaris_x86},
377         {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
378         {0, NULL},
379 };
380  
381 int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
382 {
383         int sector_size = bdev_hardsect_size(bdev) / 512;
384         Sector sect;
385         unsigned char *data;
386         struct partition *p;
387         int slot;
388
389         data = read_dev_sector(bdev, 0, &sect);
390         if (!data)
391                 return -1;
392         if (!msdos_magic_present(data + 510)) {
393                 put_dev_sector(sect);
394                 return 0;
395         }
396
397         /*
398          * Now that the 55aa signature is present, this is probably
399          * either the boot sector of a FAT filesystem or a DOS-type
400          * partition table. Reject this in case the boot indicator
401          * is not 0 or 0x80.
402          */
403         p = (struct partition *) (data + 0x1be);
404         for (slot = 1; slot <= 4; slot++, p++) {
405                 if (p->boot_ind != 0 && p->boot_ind != 0x80) {
406                         put_dev_sector(sect);
407                         return 0;
408                 }
409         }
410
411 #ifdef CONFIG_EFI_PARTITION
412         p = (struct partition *) (data + 0x1be);
413         for (slot = 1 ; slot <= 4 ; slot++, p++) {
414                 /* If this is an EFI GPT disk, msdos should ignore it. */
415                 if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
416                         put_dev_sector(sect);
417                         return 0;
418                 }
419         }
420 #endif
421         p = (struct partition *) (data + 0x1be);
422
423         /*
424          * Look for partitions in two passes:
425          * First find the primary and DOS-type extended partitions.
426          * On the second pass look inside *BSD, Unixware and Solaris partitions.
427          */
428
429         state->next = 5;
430         for (slot = 1 ; slot <= 4 ; slot++, p++) {
431                 u32 start = START_SECT(p)*sector_size;
432                 u32 size = NR_SECTS(p)*sector_size;
433                 if (!size)
434                         continue;
435                 if (is_extended_partition(p)) {
436                         /* prevent someone doing mkfs or mkswap on an
437                            extended partition, but leave room for LILO */
438                         put_partition(state, slot, start, size == 1 ? 1 : 2);
439                         printk(" <");
440                         parse_extended(state, bdev, start, size);
441                         printk(" >");
442                         continue;
443                 }
444                 put_partition(state, slot, start, size);
445                 if (SYS_IND(p) == LINUX_RAID_PARTITION)
446                         state->parts[slot].flags = 1;
447                 if (SYS_IND(p) == DM6_PARTITION)
448                         printk("[DM]");
449                 if (SYS_IND(p) == EZD_PARTITION)
450                         printk("[EZD]");
451         }
452
453         printk("\n");
454
455         /* second pass - output for each on a separate line */
456         p = (struct partition *) (0x1be + data);
457         for (slot = 1 ; slot <= 4 ; slot++, p++) {
458                 unsigned char id = SYS_IND(p);
459                 int n;
460
461                 if (!NR_SECTS(p))
462                         continue;
463
464                 for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
465                         ;
466
467                 if (!subtypes[n].parse)
468                         continue;
469                 subtypes[n].parse(state, bdev, START_SECT(p)*sector_size,
470                                                 NR_SECTS(p)*sector_size, slot);
471         }
472         put_dev_sector(sect);
473         return 1;
474 }