X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fpartitions%2Fmsdos.c;h=8c7af1777819e2b2d5cdeabc49ef87298ca89c19;hb=refs%2Fheads%2Fvserver;hp=3ed5cb52aa3f6901608dcb345f28d726230d9634;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 3ed5cb52a..8c7af1777 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -19,7 +19,6 @@ * Re-organised Feb 1998 Russell King */ -#include #include "check.h" #include "msdos.h" @@ -33,13 +32,11 @@ #include #define SYS_IND(p) (get_unaligned(&p->sys_ind)) -#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \ - get_unaligned(&p->nr_sects); \ +#define NR_SECTS(p) ({ __le32 __a = get_unaligned(&p->nr_sects); \ le32_to_cpu(__a); \ }) -#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \ - get_unaligned(&p->start_sect); \ +#define START_SECT(p) ({ __le32 __a = get_unaligned(&p->start_sect); \ le32_to_cpu(__a); \ }) @@ -59,6 +56,31 @@ msdos_magic_present(unsigned char *p) return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); } +/* Value is EBCDIC 'IBMA' */ +#define AIX_LABEL_MAGIC1 0xC9 +#define AIX_LABEL_MAGIC2 0xC2 +#define AIX_LABEL_MAGIC3 0xD4 +#define AIX_LABEL_MAGIC4 0xC1 +static int aix_magic_present(unsigned char *p, struct block_device *bdev) +{ + Sector sect; + unsigned char *d; + int ret = 0; + + if (p[0] != AIX_LABEL_MAGIC1 && + p[1] != AIX_LABEL_MAGIC2 && + p[2] != AIX_LABEL_MAGIC3 && + p[3] != AIX_LABEL_MAGIC4) + return 0; + d = read_dev_sector(bdev, 7, §); + if (d) { + if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M') + ret = 1; + put_dev_sector(sect); + }; + return ret; +} + /* * Create devices for each logical partition in an extended partition. * The logical partitions form a linked list, with each entry being @@ -202,12 +224,12 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, #endif } -#if defined(CONFIG_BSD_DISKLABEL) || defined(CONFIG_NEC98_PARTITION) +#if defined(CONFIG_BSD_DISKLABEL) /* * Create devices for BSD partitions listed in a disklabel, under a * dos-like partition. See parse_extended() for more information. */ -void +static void parse_bsd(struct parsed_partitions *state, struct block_device *bdev, u32 offset, u32 size, int origin, char *flavour, int max_partitions) @@ -246,6 +268,9 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev, put_partition(state, state->next++, bsd_start, bsd_size); } put_dev_sector(sect); + if (le16_to_cpu(l->d_npartitions) > max_partitions) + printk(" (ignored %d more)", + le16_to_cpu(l->d_npartitions) - max_partitions); printk(" >\n"); } #endif @@ -371,6 +396,7 @@ static struct { {MINIX_PARTITION, parse_minix}, {UNIXWARE_PARTITION, parse_unixware}, {SOLARIS_X86_PARTITION, parse_solaris_x86}, + {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, {0, NULL}, }; @@ -389,8 +415,29 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) put_dev_sector(sect); return 0; } + + if (aix_magic_present(data, bdev)) { + put_dev_sector(sect); + printk( " [AIX]"); + return 0; + } + + /* + * Now that the 55aa signature is present, this is probably + * either the boot sector of a FAT filesystem or a DOS-type + * partition table. Reject this in case the boot indicator + * is not 0 or 0x80. + */ p = (struct partition *) (data + 0x1be); + for (slot = 1; slot <= 4; slot++, p++) { + if (p->boot_ind != 0 && p->boot_ind != 0x80) { + put_dev_sector(sect); + return 0; + } + } + #ifdef CONFIG_EFI_PARTITION + p = (struct partition *) (data + 0x1be); for (slot = 1 ; slot <= 4 ; slot++, p++) { /* If this is an EFI GPT disk, msdos should ignore it. */ if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) { @@ -398,8 +445,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) return 0; } } - p = (struct partition *) (data + 0x1be); #endif + p = (struct partition *) (data + 0x1be); /* * Look for partitions in two passes: