diff options
Diffstat (limited to 'fs/partitions')
-rw-r--r-- | fs/partitions/Kconfig | 9 | ||||
-rw-r--r-- | fs/partitions/Makefile | 1 | ||||
-rw-r--r-- | fs/partitions/acorn.c | 2 | ||||
-rw-r--r-- | fs/partitions/check.c | 13 | ||||
-rw-r--r-- | fs/partitions/efi.c | 12 | ||||
-rw-r--r-- | fs/partitions/sysv68.c | 92 | ||||
-rw-r--r-- | fs/partitions/sysv68.h | 1 |
7 files changed, 116 insertions, 14 deletions
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 6e8bb66fe619..7638a1c42a7d 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig @@ -236,3 +236,12 @@ config EFI_PARTITION help Say Y here if you would like to use hard disks under Linux which were partitioned using EFI GPT. + +config SYSV68_PARTITION + bool "SYSV68 partition table support" if PARTITION_ADVANCED + default y if VME + help + Say Y here if you would like to be able to read the hard disk + partition table format used by Motorola Delta machines (using + sysv68). + Otherwise, say N. diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index 67e665fdb7fc..03af8eac51da 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o obj-$(CONFIG_IBM_PARTITION) += ibm.o obj-$(CONFIG_EFI_PARTITION) += efi.o obj-$(CONFIG_KARMA_PARTITION) += karma.o +obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c index 1bc9f372c7d4..e3491328596b 100644 --- a/fs/partitions/acorn.c +++ b/fs/partitions/acorn.c @@ -271,7 +271,7 @@ adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev) extern void xd_set_geometry(struct block_device *, unsigned char, unsigned char, unsigned int); xd_set_geometry(bdev, dr->secspertrack, heads, 1); - invalidate_bdev(bdev, 1); + invalidate_bh_lrus(); truncate_inode_pages(bdev->bd_inode->i_mapping, 0); } #endif diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 8a7d0035ad7a..9a3a058f3553 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -34,6 +34,7 @@ #include "ultrix.h" #include "efi.h" #include "karma.h" +#include "sysv68.h" #ifdef CONFIG_BLK_DEV_MD extern void md_autodetect_dev(dev_t dev); @@ -105,6 +106,9 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) = #ifdef CONFIG_KARMA_PARTITION karma_partition, #endif +#ifdef CONFIG_SYSV68_PARTITION + sysv68_partition, +#endif NULL }; @@ -312,7 +316,7 @@ static struct attribute * default_attrs[] = { NULL, }; -extern struct subsystem block_subsys; +extern struct kset block_subsys; static void part_release(struct kobject *kobj) { @@ -388,7 +392,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, kobject_add(&p->kobj); if (!disk->part_uevent_suppress) kobject_uevent(&p->kobj, KOBJ_ADD); - sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem"); + sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem"); if (flags & ADDPART_FLAG_WHOLEDISK) { static struct attribute addpartattr = { .name = "whole_disk", @@ -444,7 +448,7 @@ static int disk_sysfs_symlinks(struct gendisk *disk) goto err_out_dev_link; } - err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, + err = sysfs_create_link(&disk->kobj, &block_subsys.kobj, "subsystem"); if (err) goto err_out_disk_name_lnk; @@ -569,9 +573,6 @@ unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), NULL); if (!IS_ERR(page)) { - wait_on_page_locked(page); - if (!PageUptodate(page)) - goto fail; if (PageError(page)) goto fail; p->v = page; diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c index 1bea610078b3..e7b07006bc41 100644 --- a/fs/partitions/efi.c +++ b/fs/partitions/efi.c @@ -152,7 +152,7 @@ last_lba(struct block_device *bdev) } static inline int -pmbr_part_valid(struct partition *part, u64 lastlba) +pmbr_part_valid(struct partition *part) { if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT && le32_to_cpu(part->start_sect) == 1UL) @@ -163,7 +163,6 @@ pmbr_part_valid(struct partition *part, u64 lastlba) /** * is_pmbr_valid(): test Protective MBR for validity * @mbr: pointer to a legacy mbr structure - * @lastlba: last_lba for the whole device * * Description: Returns 1 if PMBR is valid, 0 otherwise. * Validity depends on two things: @@ -171,13 +170,13 @@ pmbr_part_valid(struct partition *part, u64 lastlba) * 2) One partition of type 0xEE is found */ static int -is_pmbr_valid(legacy_mbr *mbr, u64 lastlba) +is_pmbr_valid(legacy_mbr *mbr) { int i; if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) return 0; for (i = 0; i < 4; i++) - if (pmbr_part_valid(&mbr->partition_record[i], lastlba)) + if (pmbr_part_valid(&mbr->partition_record[i])) return 1; return 0; } @@ -516,7 +515,7 @@ find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes) int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; gpt_header *pgpt = NULL, *agpt = NULL; gpt_entry *pptes = NULL, *aptes = NULL; - legacy_mbr *legacymbr = NULL; + legacy_mbr *legacymbr; u64 lastlba; if (!bdev || !gpt || !ptes) return 0; @@ -528,9 +527,8 @@ find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes) if (legacymbr) { read_lba(bdev, 0, (u8 *) legacymbr, sizeof (*legacymbr)); - good_pmbr = is_pmbr_valid(legacymbr, lastlba); + good_pmbr = is_pmbr_valid(legacymbr); kfree(legacymbr); - legacymbr=NULL; } if (!good_pmbr) goto fail; diff --git a/fs/partitions/sysv68.c b/fs/partitions/sysv68.c new file mode 100644 index 000000000000..4eba27b78643 --- /dev/null +++ b/fs/partitions/sysv68.c @@ -0,0 +1,92 @@ +/* + * fs/partitions/sysv68.c + * + * Copyright (C) 2007 Philippe De Muyter <phdm@macqel.be> + */ + +#include "check.h" +#include "sysv68.h" + +/* + * Volume ID structure: on first 256-bytes sector of disk + */ + +struct volumeid { + u8 vid_unused[248]; + u8 vid_mac[8]; /* ASCII string "MOTOROLA" */ +}; + +/* + * config block: second 256-bytes sector on disk + */ + +struct dkconfig { + u8 ios_unused0[128]; + __be32 ios_slcblk; /* Slice table block number */ + __be16 ios_slccnt; /* Number of entries in slice table */ + u8 ios_unused1[122]; +}; + +/* + * combined volumeid and dkconfig block + */ + +struct dkblk0 { + struct volumeid dk_vid; + struct dkconfig dk_ios; +}; + +/* + * Slice Table Structure + */ + +struct slice { + __be32 nblocks; /* slice size (in blocks) */ + __be32 blkoff; /* block offset of slice */ +}; + + +int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev) +{ + int i, slices; + int slot = 1; + Sector sect; + unsigned char *data; + struct dkblk0 *b; + struct slice *slice; + + data = read_dev_sector(bdev, 0, §); + if (!data) + return -1; + + b = (struct dkblk0 *)data; + if (memcmp(b->dk_vid.vid_mac, "MOTOROLA", sizeof(b->dk_vid.vid_mac))) { + put_dev_sector(sect); + return 0; + } + slices = be16_to_cpu(b->dk_ios.ios_slccnt); + i = be32_to_cpu(b->dk_ios.ios_slcblk); + put_dev_sector(sect); + + data = read_dev_sector(bdev, i, §); + if (!data) + return -1; + + slices -= 1; /* last slice is the whole disk */ + printk("sysV68: %s(s%u)", state->name, slices); + slice = (struct slice *)data; + for (i = 0; i < slices; i++, slice++) { + if (slot == state->limit) + break; + if (be32_to_cpu(slice->nblocks)) { + put_partition(state, slot, + be32_to_cpu(slice->blkoff), + be32_to_cpu(slice->nblocks)); + printk("(s%u)", i); + } + slot++; + } + printk("\n"); + put_dev_sector(sect); + return 1; +} diff --git a/fs/partitions/sysv68.h b/fs/partitions/sysv68.h new file mode 100644 index 000000000000..fa733f68431b --- /dev/null +++ b/fs/partitions/sysv68.h @@ -0,0 +1 @@ +extern int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev); |