patch-2_6_7-vs1_9_1_12
[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 #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) || defined(CONFIG_NEC98_PARTITION)
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 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         printk(" >\n");
250 }
251 #endif
252
253 static void
254 parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
255                 u32 offset, u32 size, int origin)
256 {
257 #ifdef CONFIG_BSD_DISKLABEL
258         parse_bsd(state, bdev, offset, size, origin,
259                         "bsd", BSD_MAXPARTITIONS);
260 #endif
261 }
262
263 static void
264 parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
265                 u32 offset, u32 size, int origin)
266 {
267 #ifdef CONFIG_BSD_DISKLABEL
268         parse_bsd(state, bdev, offset, size, origin,
269                         "netbsd", BSD_MAXPARTITIONS);
270 #endif
271 }
272
273 static void
274 parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
275                 u32 offset, u32 size, int origin)
276 {
277 #ifdef CONFIG_BSD_DISKLABEL
278         parse_bsd(state, bdev, offset, size, origin,
279                         "openbsd", OPENBSD_MAXPARTITIONS);
280 #endif
281 }
282
283 /*
284  * Create devices for Unixware partitions listed in a disklabel, under a
285  * dos-like partition. See parse_extended() for more information.
286  */
287 static void
288 parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
289                 u32 offset, u32 size, int origin)
290 {
291 #ifdef CONFIG_UNIXWARE_DISKLABEL
292         Sector sect;
293         struct unixware_disklabel *l;
294         struct unixware_slice *p;
295
296         l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, &sect);
297         if (!l)
298                 return;
299         if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
300             le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
301                 put_dev_sector(sect);
302                 return;
303         }
304         printk(" %s%d: <unixware:", state->name, origin);
305         p = &l->vtoc.v_slice[1];
306         /* I omit the 0th slice as it is the same as whole disk. */
307         while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
308                 if (state->next == state->limit)
309                         break;
310
311                 if (p->s_label != UNIXWARE_FS_UNUSED)
312                         put_partition(state, state->next++,
313                                                 START_SECT(p), NR_SECTS(p));
314                 p++;
315         }
316         put_dev_sector(sect);
317         printk(" >\n");
318 #endif
319 }
320
321 /*
322  * Minix 2.0.0/2.0.2 subpartition support.
323  * Anand Krishnamurthy <anandk@wiproge.med.ge.com>
324  * Rajeev V. Pillai    <rajeevvp@yahoo.com>
325  */
326 static void
327 parse_minix(struct parsed_partitions *state, struct block_device *bdev,
328                 u32 offset, u32 size, int origin)
329 {
330 #ifdef CONFIG_MINIX_SUBPARTITION
331         Sector sect;
332         unsigned char *data;
333         struct partition *p;
334         int i;
335
336         data = read_dev_sector(bdev, offset, &sect);
337         if (!data)
338                 return;
339
340         p = (struct partition *)(data + 0x1be);
341
342         /* The first sector of a Minix partition can have either
343          * a secondary MBR describing its subpartitions, or
344          * the normal boot sector. */
345         if (msdos_magic_present (data + 510) &&
346             SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
347
348                 printk(" %s%d: <minix:", state->name, origin);
349                 for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
350                         if (state->next == state->limit)
351                                 break;
352                         /* add each partition in use */
353                         if (SYS_IND(p) == MINIX_PARTITION)
354                                 put_partition(state, state->next++,
355                                               START_SECT(p), NR_SECTS(p));
356                 }
357                 printk(" >\n");
358         }
359         put_dev_sector(sect);
360 #endif /* CONFIG_MINIX_SUBPARTITION */
361 }
362
363 static struct {
364         unsigned char id;
365         void (*parse)(struct parsed_partitions *, struct block_device *,
366                         u32, u32, int);
367 } subtypes[] = {
368         {FREEBSD_PARTITION, parse_freebsd},
369         {NETBSD_PARTITION, parse_netbsd},
370         {OPENBSD_PARTITION, parse_openbsd},
371         {MINIX_PARTITION, parse_minix},
372         {UNIXWARE_PARTITION, parse_unixware},
373         {SOLARIS_X86_PARTITION, parse_solaris_x86},
374         {0, NULL},
375 };
376  
377 int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
378 {
379         int sector_size = bdev_hardsect_size(bdev) / 512;
380         Sector sect;
381         unsigned char *data;
382         struct partition *p;
383         int slot;
384
385         data = read_dev_sector(bdev, 0, &sect);
386         if (!data)
387                 return -1;
388         if (!msdos_magic_present(data + 510)) {
389                 put_dev_sector(sect);
390                 return 0;
391         }
392
393         /*
394          * Now that the 55aa signature is present, this is probably
395          * either the boot sector of a FAT filesystem or a DOS-type
396          * partition table. Reject this in case the boot indicator
397          * is not 0 or 0x80.
398          */
399         p = (struct partition *) (data + 0x1be);
400         for (slot = 1; slot <= 4; slot++, p++) {
401                 if (p->boot_ind != 0 && p->boot_ind != 0x80) {
402                         put_dev_sector(sect);
403                         return 0;
404                 }
405         }
406
407 #ifdef CONFIG_EFI_PARTITION
408         p = (struct partition *) (data + 0x1be);
409         for (slot = 1 ; slot <= 4 ; slot++, p++) {
410                 /* If this is an EFI GPT disk, msdos should ignore it. */
411                 if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
412                         put_dev_sector(sect);
413                         return 0;
414                 }
415         }
416 #endif
417         p = (struct partition *) (data + 0x1be);
418
419         /*
420          * Look for partitions in two passes:
421          * First find the primary and DOS-type extended partitions.
422          * On the second pass look inside *BSD, Unixware and Solaris partitions.
423          */
424
425         state->next = DOS_EXTENDED_PARTITION;
426         for (slot = 1 ; slot < DOS_EXTENDED_PARTITION ; slot++, p++) {
427                 u32 start = START_SECT(p)*sector_size;
428                 u32 size = NR_SECTS(p)*sector_size;
429                 if (!size)
430                         continue;
431                 if (is_extended_partition(p)) {
432                         /* prevent someone doing mkfs or mkswap on an
433                            extended partition, but leave room for LILO */
434                         put_partition(state, slot, start, size == 1 ? 1 : 2);
435                         printk(" <");
436                         parse_extended(state, bdev, start, size);
437                         printk(" >");
438                         continue;
439                 }
440                 put_partition(state, slot, start, size);
441                 if (SYS_IND(p) == LINUX_RAID_PARTITION)
442                         state->parts[slot].flags = 1;
443                 if (SYS_IND(p) == DM6_PARTITION)
444                         printk("[DM]");
445                 if (SYS_IND(p) == EZD_PARTITION)
446                         printk("[EZD]");
447         }
448
449         printk("\n");
450
451         /* second pass - output for each on a separate line */
452         p = (struct partition *) (0x1be + data);
453         for (slot = 1 ; slot < DOS_EXTENDED_PARTITION ; slot++, p++) {
454                 unsigned char id = SYS_IND(p);
455                 int n;
456
457                 if (!NR_SECTS(p))
458                         continue;
459
460                 for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
461                         ;
462
463                 if (!subtypes[n].parse)
464                         continue;
465                 subtypes[n].parse(state, bdev, START_SECT(p)*sector_size,
466                                                 NR_SECTS(p)*sector_size, slot);
467         }
468         put_dev_sector(sect);
469         return 1;
470 }