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