diff options
author | kaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk> | 2003-02-21 13:31:42 +0000 |
---|---|---|
committer | kaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk> | 2003-02-21 13:31:42 +0000 |
commit | 04c216516f74b40e7207741ee4db629fc4c031b2 (patch) | |
tree | 9932b452dface790bf463c0642ff2136c767dacb | |
parent | b772c635b961040f38d69fc098cc330eafbaf01f (diff) | |
download | xen-04c216516f74b40e7207741ee4db629fc4c031b2.tar.gz xen-04c216516f74b40e7207741ee4db629fc4c031b2.tar.bz2 xen-04c216516f74b40e7207741ee4db629fc4c031b2.zip |
bitkeeper revision 1.82 (3e562a3eivWgqJ6O9wH-OFGq-YzJ5w)
.del-msdos.c~f31e5a4d337da875:
Delete: xenolinux-2.4.16-sparse/fs/partitions/msdos.c
.del-check.c~ebcaa3de1bfb8ad8:
Delete: xenolinux-2.4.16-sparse/fs/partitions/check.c
-rw-r--r-- | .rootkeys | 2 | ||||
-rw-r--r-- | xenolinux-2.4.16-sparse/fs/partitions/check.c | 443 | ||||
-rw-r--r-- | xenolinux-2.4.16-sparse/fs/partitions/msdos.c | 642 |
3 files changed, 0 insertions, 1087 deletions
@@ -329,8 +329,6 @@ 3ddb79bcJfHdwrPsjqgI33_OsGdVCg xenolinux-2.4.16-sparse/drivers/block/rd.c 3ddb79bcpVu-IbnqwQqpRqsEbLpsuw xenolinux-2.4.16-sparse/drivers/char/tty_io.c 3e15d5273gfR2fbcYe05kqBSAvCX_w xenolinux-2.4.16-sparse/fs/exec.c -3e4a8cb7kqfJTMeOpPcYxqxv7N18DA xenolinux-2.4.16-sparse/fs/partitions/check.c -3e4a8cb7p079Xxly4uNcouacMSjJLw xenolinux-2.4.16-sparse/fs/partitions/msdos.c 3ddb79b8VFtfWSCrXKPN2K21zd_vtw xenolinux-2.4.16-sparse/include/asm-xeno/a.out.h 3ddb79b8Zzi13p3OAPV25QgiC3THAQ xenolinux-2.4.16-sparse/include/asm-xeno/apic.h 3ddb79baZDlsdV_m6C5CXnWMl15p1g xenolinux-2.4.16-sparse/include/asm-xeno/apicdef.h diff --git a/xenolinux-2.4.16-sparse/fs/partitions/check.c b/xenolinux-2.4.16-sparse/fs/partitions/check.c deleted file mode 100644 index e564544ec6..0000000000 --- a/xenolinux-2.4.16-sparse/fs/partitions/check.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Code extracted from drivers/block/genhd.c - * Copyright (C) 1991-1998 Linus Torvalds - * Re-organised Feb 1998 Russell King - * - * We now have independent partition support from the - * block drivers, which allows all the partition code to - * be grouped in one location, and it to be mostly self - * contained. - * - * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl} - */ - -#include <linux/config.h> -#include <linux/fs.h> -#include <linux/genhd.h> -#include <linux/kernel.h> -#include <linux/major.h> -#include <linux/blk.h> -#include <linux/init.h> -#include <linux/raid/md.h> - -#include "check.h" - -#include "acorn.h" -#include "amiga.h" -#include "atari.h" -#include "ldm.h" -#include "mac.h" -#include "msdos.h" -#include "osf.h" -#include "sgi.h" -#include "sun.h" -#include "ibm.h" -#include "ultrix.h" - -extern int *blk_size[]; - -#define CHECK_DEBUG 0 - -int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ - -static int (*check_part[])(struct gendisk *hd, struct block_device *bdev, unsigned long first_sect, int first_minor) = { -#ifdef CONFIG_ACORN_PARTITION - acorn_partition, -#endif -#ifdef CONFIG_LDM_PARTITION - ldm_partition, /* this must come before msdos */ -#endif -#ifdef CONFIG_MSDOS_PARTITION - msdos_partition, -#endif -#ifdef CONFIG_OSF_PARTITION - osf_partition, -#endif -#ifdef CONFIG_SUN_PARTITION - sun_partition, -#endif -#ifdef CONFIG_AMIGA_PARTITION - amiga_partition, -#endif -#ifdef CONFIG_ATARI_PARTITION - atari_partition, -#endif -#ifdef CONFIG_MAC_PARTITION - mac_partition, -#endif -#ifdef CONFIG_SGI_PARTITION - sgi_partition, -#endif -#ifdef CONFIG_ULTRIX_PARTITION - ultrix_partition, -#endif -#ifdef CONFIG_IBM_PARTITION - ibm_partition, -#endif - NULL -}; - -/* - * This is ucking fugly but its probably the best thing for 2.4.x - * Take it as a clear reminder than we should put the device name - * generation in the object kdev_t points to in 2.5. - */ - -#ifdef CONFIG_ARCH_S390 -int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL; -EXPORT_SYMBOL(genhd_dasd_name); -#endif - -/* - * disk_name() is used by partition check code and the md driver. - * It formats the devicename of the indicated disk into - * the supplied buffer (of size at least 32), and returns - * a pointer to that same buffer (for convenience). - */ - -char *disk_name (struct gendisk *hd, int minor, char *buf) -{ - const char *maj = hd->major_name; - unsigned int unit = (minor >> hd->minor_shift); - unsigned int part = (minor & ((1 << hd->minor_shift) -1 )); - - if ((unit < hd->nr_real) && hd->part[minor].de) { - int pos; - - pos = devfs_generate_path (hd->part[minor].de, buf, 64); - if (pos >= 0) - return buf + pos; - } - -#ifdef CONFIG_ARCH_S390 - if (genhd_dasd_name - && genhd_dasd_name (buf, unit, part, hd) == 0) - return buf; -#endif - /* - * IDE devices use multiple major numbers, but the drives - * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}.. - * This requires special handling here. - */ - switch (hd->major) { - case IDE9_MAJOR: - unit += 2; - case IDE8_MAJOR: - unit += 2; - case IDE7_MAJOR: - unit += 2; - case IDE6_MAJOR: - unit += 2; - case IDE5_MAJOR: - unit += 2; - case IDE4_MAJOR: - unit += 2; - case IDE3_MAJOR: - unit += 2; - case IDE2_MAJOR: - unit += 2; - case IDE1_MAJOR: - unit += 2; - case IDE0_MAJOR: - maj = "hd"; - break; - case MD_MAJOR: - sprintf(buf, "%s%d", maj, unit); - return buf; - } - if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) { - unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16; - if (unit+'a' > 'z') { - unit -= 26; - sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26); - if (part) - sprintf(buf + 4, "%d", part); - return buf; - } - } - if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) { - int ctlr = hd->major - COMPAQ_SMART2_MAJOR; - if (part == 0) - sprintf(buf, "%s/c%dd%d", maj, ctlr, unit); - else - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); - return buf; - } - if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) { - int ctlr = hd->major - COMPAQ_CISS_MAJOR; - if (part == 0) - sprintf(buf, "%s/c%dd%d", maj, ctlr, unit); - else - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); - return buf; - } - if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) { - int ctlr = hd->major - DAC960_MAJOR; - if (part == 0) - sprintf(buf, "%s/c%dd%d", maj, ctlr, unit); - else - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); - return buf; - } - if (hd->major == ATARAID_MAJOR) { - int disk = minor >> hd->minor_shift; - int part = minor & (( 1 << hd->minor_shift) - 1); - if (part == 0) - sprintf(buf, "%s/d%d", maj, disk); - else - sprintf(buf, "%s/d%dp%d", maj, disk, part); - return buf; - } - if (part) - sprintf(buf, "%s%c%d", maj, unit+'a', part); - else - sprintf(buf, "%s%c", maj, unit+'a'); - return buf; -} - -/* - * Add a partitions details to the devices partition description. - */ -void add_gd_partition(struct gendisk *hd, int minor, int start, int size) -{ -#ifndef CONFIG_DEVFS_FS - char buf[40]; -#endif - - hd->part[minor].start_sect = start; - hd->part[minor].nr_sects = size; -#ifdef CONFIG_DEVFS_FS - printk(" p%d", (minor & ((1 << hd->minor_shift) - 1))); -#else - if ((hd->major >= COMPAQ_SMART2_MAJOR+0 && hd->major <= COMPAQ_SMART2_MAJOR+7) || - (hd->major >= COMPAQ_CISS_MAJOR+0 && hd->major <= COMPAQ_CISS_MAJOR+7)) - printk(" p%d", (minor & ((1 << hd->minor_shift) - 1))); - else - printk(" %s", disk_name(hd, minor, buf)); -#endif -} - -static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor) -{ - devfs_handle_t de = NULL; - static int first_time = 1; - unsigned long first_sector; - struct block_device *bdev; - char buf[64]; - int i; - - if (CHECK_DEBUG) printk (KERN_ALERT "check.c::check_partition\n"); - - if (first_time) - printk(KERN_INFO "Partition check:\n"); - first_time = 0; - first_sector = hd->part[MINOR(dev)].start_sect; - - /* - * This is a kludge to allow the partition check to be - * skipped for specific drives (e.g. IDE CD-ROM drives) - */ - if ((int)first_sector == -1) { - hd->part[MINOR(dev)].start_sect = 0; - return; - } - - if (hd->de_arr) - de = hd->de_arr[MINOR(dev) >> hd->minor_shift]; - i = devfs_generate_path (de, buf, sizeof buf); - if (i >= 0) - printk(KERN_INFO " /dev/%s:", buf + i); - else - printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf)); - bdev = bdget(kdev_t_to_nr(dev)); - bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9; - bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev)); - for (i = 0; check_part[i]; i++) { - int res; - res = check_part[i](hd, bdev, first_sector, first_part_minor); - if (res) { - if (res < 0 && warn_no_part) - printk(" unable to read partition table\n"); - goto setup_devfs; - } - } - - printk(" unknown partition table\n"); -setup_devfs: - invalidate_bdev(bdev, 1); - truncate_inode_pages(bdev->bd_inode->i_mapping, 0); - bdput(bdev); - i = first_part_minor - 1; - devfs_register_partitions (hd, i, hd->sizes ? 0 : 1); -} - -#ifdef CONFIG_DEVFS_FS -static void devfs_register_partition (struct gendisk *dev, int minor, int part) -{ - int devnum = minor >> dev->minor_shift; - devfs_handle_t dir; - unsigned int devfs_flags = DEVFS_FL_DEFAULT; - char devname[16]; - - if (dev->part[minor + part].de) return; - dir = devfs_get_parent (dev->part[minor].de); - if (!dir) return; - if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) ) - devfs_flags |= DEVFS_FL_REMOVABLE; - sprintf (devname, "part%d", part); - dev->part[minor + part].de = - devfs_register (dir, devname, devfs_flags, - dev->major, minor + part, - S_IFBLK | S_IRUSR | S_IWUSR, - dev->fops, NULL); -} - -static struct unique_numspace disc_numspace = UNIQUE_NUMBERSPACE_INITIALISER; - -static void devfs_register_disc (struct gendisk *dev, int minor) -{ - int pos = 0; - int devnum = minor >> dev->minor_shift; - devfs_handle_t dir, slave; - unsigned int devfs_flags = DEVFS_FL_DEFAULT; - char dirname[64], symlink[16]; - static devfs_handle_t devfs_handle; - - if (dev->part[minor].de) return; - if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) ) - devfs_flags |= DEVFS_FL_REMOVABLE; - if (dev->de_arr) { - dir = dev->de_arr[devnum]; - if (!dir) /* Aware driver wants to block disc management */ - return; - pos = devfs_generate_path (dir, dirname + 3, sizeof dirname-3); - if (pos < 0) return; - strncpy (dirname + pos, "../", 3); - } - else { - /* Unaware driver: construct "real" directory */ - sprintf (dirname, "../%s/disc%d", dev->major_name, devnum); - dir = devfs_mk_dir (NULL, dirname + 3, NULL); - } - if (!devfs_handle) - devfs_handle = devfs_mk_dir (NULL, "discs", NULL); - dev->part[minor].number = devfs_alloc_unique_number (&disc_numspace); - sprintf (symlink, "disc%d", dev->part[minor].number); - devfs_mk_symlink (devfs_handle, symlink, DEVFS_FL_DEFAULT, - dirname + pos, &slave, NULL); - dev->part[minor].de = - devfs_register (dir, "disc", devfs_flags, dev->major, minor, - S_IFBLK | S_IRUSR | S_IWUSR, dev->fops, NULL); - devfs_auto_unregister (dev->part[minor].de, slave); - if (!dev->de_arr) - devfs_auto_unregister (slave, dir); -} -#endif /* CONFIG_DEVFS_FS */ - -void devfs_register_partitions (struct gendisk *dev, int minor, int unregister) -{ -#ifdef CONFIG_DEVFS_FS - int part; - - if (!unregister) - devfs_register_disc (dev, minor); - for (part = 1; part < dev->max_p; part++) { - if ( unregister || (dev->part[part + minor].nr_sects < 1) ) { - devfs_unregister (dev->part[part + minor].de); - dev->part[part + minor].de = NULL; - continue; - } - devfs_register_partition (dev, minor, part); - } - if (unregister) { - devfs_unregister (dev->part[minor].de); - dev->part[minor].de = NULL; - devfs_dealloc_unique_number (&disc_numspace, - dev->part[minor].number); - } -#endif /* CONFIG_DEVFS_FS */ -} - -/* - * This function will re-read the partition tables for a given device, - * and set things back up again. There are some important caveats, - * however. You must ensure that no one is using the device, and no one - * can start using the device while this function is being executed. - * - * Much of the cleanup from the old partition tables should have already been - * done - */ - -void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors, - struct block_device_operations *ops, long size) -{ - if (CHECK_DEBUG) - { - if (gdev != NULL) - printk (KERN_ALERT - "check.c::register_disk gdev:%p dev:%d min:%u ops:%p sz:%ld\n", - gdev, dev, minors, ops, size); - } - - if (!gdev) - return; - - grok_partitions(gdev, MINOR(dev)>>gdev->minor_shift, minors, size); -} - -void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size) -{ - int i; - int first_minor = drive << dev->minor_shift; - int end_minor = first_minor + dev->max_p; - - if (CHECK_DEBUG) printk (KERN_ALERT "check.c::grok_partitions\n"); - - if(!dev->sizes) - blk_size[dev->major] = NULL; - - dev->part[first_minor].nr_sects = size; - /* No such device or no minors to use for partitions */ - if (!size || minors == 1) - return; - - if (dev->sizes) { - dev->sizes[first_minor] = size >> (BLOCK_SIZE_BITS - 9); - for (i = first_minor + 1; i < end_minor; i++) - dev->sizes[i] = 0; - } - blk_size[dev->major] = dev->sizes; - check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor); - - /* - * We need to set the sizes array before we will be able to access - * any of the partitions on this device. - */ - if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */ - for (i = first_minor; i < end_minor; i++) - dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); - } -} - -unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Sector *p) -{ - struct address_space *mapping = bdev->bd_inode->i_mapping; - int sect = PAGE_CACHE_SIZE / 512; - struct page *page; - - page = read_cache_page(mapping, n/sect, - (filler_t *)mapping->a_ops->readpage, NULL); - if (!IS_ERR(page)) { - wait_on_page(page); - if (!Page_Uptodate(page)) - goto fail; - if (PageError(page)) - goto fail; - p->v = page; - return (unsigned char *)page_address(page) + 512 * (n % sect); -fail: - page_cache_release(page); - } - p->v = NULL; - return NULL; -} diff --git a/xenolinux-2.4.16-sparse/fs/partitions/msdos.c b/xenolinux-2.4.16-sparse/fs/partitions/msdos.c deleted file mode 100644 index 34a086024e..0000000000 --- a/xenolinux-2.4.16-sparse/fs/partitions/msdos.c +++ /dev/null @@ -1,642 +0,0 @@ -/* - * fs/partitions/msdos.c - * - * Code extracted from drivers/block/genhd.c - * Copyright (C) 1991-1998 Linus Torvalds - * - * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug - * in the early extended-partition checks and added DM partitions - * - * Support for DiskManager v6.0x added by Mark Lord, - * with information provided by OnTrack. This now works for linux fdisk - * and LILO, as well as loadlin and bootln. Note that disks other than - * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). - * - * More flexible handling of extended partitions - aeb, 950831 - * - * Check partition table on IDE disks for common CHS translations - * - * Re-organised Feb 1998 Russell King - */ - -#include <linux/config.h> -#include <linux/fs.h> -#include <linux/genhd.h> -#include <linux/kernel.h> -#include <linux/major.h> -#include <linux/string.h> -#include <linux/blk.h> - -#ifdef CONFIG_BLK_DEV_IDE -#include <linux/ide.h> /* IDE xlate */ -#endif /* CONFIG_BLK_DEV_IDE */ - -#define MSDOS_DEBUG 0 - -#include <asm/system.h> - -#include "check.h" -#include "msdos.h" - -#if CONFIG_BLK_DEV_MD -extern void md_autodetect_dev(kdev_t dev); -#endif - -/* - * Many architectures don't like unaligned accesses, which is - * frequently the case with the nr_sects and start_sect partition - * table entries. - */ -#include <asm/unaligned.h> - -#define SYS_IND(p) (get_unaligned(&p->sys_ind)) -#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \ - get_unaligned(&p->nr_sects); \ - le32_to_cpu(__a); \ - }) - -#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \ - get_unaligned(&p->start_sect); \ - le32_to_cpu(__a); \ - }) - -static inline int is_extended_partition(struct partition *p) -{ - return (SYS_IND(p) == DOS_EXTENDED_PARTITION || - SYS_IND(p) == WIN98_EXTENDED_PARTITION || - SYS_IND(p) == LINUX_EXTENDED_PARTITION); -} - -/* - * partition_name() formats the short partition name into the supplied - * buffer, and returns a pointer to that buffer. - * Used by several partition types which makes conditional inclusion messy, - * use __attribute__ ((unused)) instead. - */ -static char __attribute__ ((unused)) - *partition_name (struct gendisk *hd, int minor, char *buf) -{ -#ifdef CONFIG_DEVFS_FS - sprintf(buf, "p%d", (minor & ((1 << hd->minor_shift) - 1))); - return buf; -#else - return disk_name(hd, minor, buf); -#endif -} - -#define MSDOS_LABEL_MAGIC1 0x55 -#define MSDOS_LABEL_MAGIC2 0xAA - -static inline int -msdos_magic_present(unsigned char *p) -{ - return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); -} - -/* - * Create devices for each logical partition in an extended partition. - * The logical partitions form a linked list, with each entry being - * a partition table with two entries. The first entry - * is the real data partition (with a start relative to the partition - * table start). The second is a pointer to the next logical partition - * (with a start relative to the entire extended partition). - * We do not create a Linux partition for the partition tables, but - * only for the actual data partitions. - */ - -static void extended_partition(struct gendisk *hd, struct block_device *bdev, - int minor, unsigned long first_size, int *current_minor) -{ - struct partition *p; - Sector sect; - unsigned char *data; - unsigned long first_sector, this_sector, this_size; - int mask = (1 << hd->minor_shift) - 1; - int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512; - int loopct = 0; /* number of links followed - without finding a data partition */ - int i; - - this_sector = first_sector = hd->part[minor].start_sect; - this_size = first_size; - - while (1) { - if (++loopct > 100) - return; - if ((*current_minor & mask) == 0) - return; - data = read_dev_sector(bdev, this_sector, §); - if (!data) - return; - - if (!msdos_magic_present(data + 510)) - goto done; - - p = (struct partition *) (data + 0x1be); - - /* - * Usually, the first entry is the real data partition, - * the 2nd entry is the next extended partition, or empty, - * and the 3rd and 4th entries are unused. - * However, DRDOS sometimes has the extended partition as - * the first entry (when the data partition is empty), - * and OS/2 seems to use all four entries. - */ - - /* - * First process the data partition(s) - */ - for (i=0; i<4; i++, p++) { - unsigned long offs, size, next; - if (!NR_SECTS(p) || is_extended_partition(p)) - continue; - - /* Check the 3rd and 4th entries - - these sometimes contain random garbage */ - offs = START_SECT(p)*sector_size; - size = NR_SECTS(p)*sector_size; - next = this_sector + offs; - if (i >= 2) { - if (offs + size > this_size) - continue; - if (next < first_sector) - continue; - if (next + size > first_sector + first_size) - continue; - } - - add_gd_partition(hd, *current_minor, next, size); -#if CONFIG_BLK_DEV_MD - if (SYS_IND(p) == LINUX_RAID_PARTITION) { - md_autodetect_dev(MKDEV(hd->major,*current_minor)); - } -#endif - - (*current_minor)++; - loopct = 0; - if ((*current_minor & mask) == 0) - goto done; - } - /* - * Next, process the (first) extended partition, if present. - * (So far, there seems to be no reason to make - * extended_partition() recursive and allow a tree - * of extended partitions.) - * It should be a link to the next logical partition. - * Create a minor for this just long enough to get the next - * partition table. The minor will be reused for the next - * data partition. - */ - p -= 4; - for (i=0; i<4; i++, p++) - if (NR_SECTS(p) && is_extended_partition(p)) - break; - if (i == 4) - goto done; /* nothing left to do */ - - this_sector = first_sector + START_SECT(p) * sector_size; - this_size = NR_SECTS(p) * sector_size; - minor = *current_minor; - put_dev_sector(sect); - } -done: - put_dev_sector(sect); -} - -/* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also - indicates linux swap. Be careful before believing this is Solaris. */ - -static void -solaris_x86_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor) -{ - -#ifdef CONFIG_SOLARIS_X86_PARTITION - long offset = hd->part[minor].start_sect; - Sector sect; - struct solaris_x86_vtoc *v; - struct solaris_x86_slice *s; - int mask = (1 << hd->minor_shift) - 1; - int i; - char buf[40]; - - v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, §); - if (!v) - return; - if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) { - put_dev_sector(sect); - return; - } - printk(" %s: <solaris:", partition_name(hd, minor, buf)); - if (le32_to_cpu(v->v_version) != 1) { - printk(" cannot handle version %d vtoc>\n", - le32_to_cpu(v->v_version)); - put_dev_sector(sect); - return; - } - for (i=0; i<SOLARIS_X86_NUMSLICE; i++) { - if ((*current_minor & mask) == 0) - break; - s = &v->v_slice[i]; - - if (s->s_size == 0) - continue; - printk(" [s%d]", i); - /* solaris partitions are relative to current MS-DOS - * one but add_gd_partition starts relative to sector - * zero of the disk. Therefore, must add the offset - * of the current partition */ - add_gd_partition(hd, *current_minor, - le32_to_cpu(s->s_start)+offset, - le32_to_cpu(s->s_size)); - (*current_minor)++; - } - put_dev_sector(sect); - printk(" >\n"); -#endif -} - -#ifdef CONFIG_BSD_DISKLABEL -static void -check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p, - int minor, int *current_minor) -{ - struct hd_struct *lin_p; - /* check relative position of partitions. */ - for (lin_p = hd->part + 1 + minor; - lin_p - hd->part - minor < *current_minor; lin_p++) { - /* no relationship -> try again */ - if (lin_p->start_sect + lin_p->nr_sects <= le32_to_cpu(bsd_p->p_offset) || - lin_p->start_sect >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size)) - continue; - /* equal -> no need to add */ - if (lin_p->start_sect == le32_to_cpu(bsd_p->p_offset) && - lin_p->nr_sects == le32_to_cpu(bsd_p->p_size)) - return; - /* bsd living within dos partition */ - if (lin_p->start_sect <= le32_to_cpu(bsd_p->p_offset) && lin_p->start_sect - + lin_p->nr_sects >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size)) { -#ifdef DEBUG_BSD_DISKLABEL - printk("w: %d %ld+%ld,%d+%d", - lin_p - hd->part, - lin_p->start_sect, lin_p->nr_sects, - le32_to_cpu(bsd_p->p_offset), - le32_to_cpu(bsd_p->p_size)); -#endif - break; - } - /* ouch: bsd and linux overlap. Don't even try for that partition */ -#ifdef DEBUG_BSD_DISKLABEL - printk("???: %d %ld+%ld,%d+%d", - lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects, - le32_to_cpu(bsd_p->p_offset), le32_to_cpu(bsd_p->p_size)); -#endif - printk("???"); - return; - } /* if the bsd partition is not currently known to linux, we end - * up here - */ - add_gd_partition(hd, *current_minor, le32_to_cpu(bsd_p->p_offset), - le32_to_cpu(bsd_p->p_size)); - (*current_minor)++; -} - -/* - * Create devices for BSD partitions listed in a disklabel, under a - * dos-like partition. See extended_partition() for more information. - */ -static void do_bsd_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor, char *name, int max_partitions) -{ - long offset = hd->part[minor].start_sect; - Sector sect; - struct bsd_disklabel *l; - struct bsd_partition *p; - int mask = (1 << hd->minor_shift) - 1; - char buf[40]; - - l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, §); - if (!l) - return; - if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) { - put_dev_sector(sect); - return; - } - printk(" %s: <%s", partition_name(hd, minor, buf), name); - - if (le16_to_cpu(l->d_npartitions) < max_partitions) - max_partitions = le16_to_cpu(l->d_npartitions); - for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { - if ((*current_minor & mask) == 0) - break; - if (p->p_fstype == BSD_FS_UNUSED) - continue; - check_and_add_bsd_partition(hd, p, minor, current_minor); - } - put_dev_sector(sect); - printk(" >\n"); -} -#endif - -static void bsd_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor) -{ -#ifdef CONFIG_BSD_DISKLABEL - do_bsd_partition(hd, bdev, minor, current_minor, "bsd", - BSD_MAXPARTITIONS); -#endif -} - -static void netbsd_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor) -{ -#ifdef CONFIG_BSD_DISKLABEL - do_bsd_partition(hd, bdev, minor, current_minor, "netbsd", - BSD_MAXPARTITIONS); -#endif -} - -static void openbsd_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor) -{ -#ifdef CONFIG_BSD_DISKLABEL - do_bsd_partition(hd, bdev, minor, current_minor, - "openbsd", OPENBSD_MAXPARTITIONS); -#endif -} - -/* - * Create devices for Unixware partitions listed in a disklabel, under a - * dos-like partition. See extended_partition() for more information. - */ -static void unixware_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor) -{ -#ifdef CONFIG_UNIXWARE_DISKLABEL - long offset = hd->part[minor].start_sect; - Sector sect; - struct unixware_disklabel *l; - struct unixware_slice *p; - int mask = (1 << hd->minor_shift) - 1; - char buf[40]; - - l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, §); - if (!l) - return; - if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || - le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) { - put_dev_sector(sect); - return; - } - printk(" %s: <unixware:", partition_name(hd, minor, buf)); - p = &l->vtoc.v_slice[1]; - /* I omit the 0th slice as it is the same as whole disk. */ - while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { - if ((*current_minor & mask) == 0) - break; - - if (p->s_label != UNIXWARE_FS_UNUSED) { - add_gd_partition(hd, *current_minor, START_SECT(p), - NR_SECTS(p)); - (*current_minor)++; - } - p++; - } - put_dev_sector(sect); - printk(" >\n"); -#endif -} - -/* - * Minix 2.0.0/2.0.2 subpartition support. - * Anand Krishnamurthy <anandk@wiproge.med.ge.com> - * Rajeev V. Pillai <rajeevvp@yahoo.com> - */ -static void minix_partition(struct gendisk *hd, struct block_device *bdev, - int minor, int *current_minor) -{ -#ifdef CONFIG_MINIX_SUBPARTITION - long offset = hd->part[minor].start_sect; - Sector sect; - unsigned char *data; - struct partition *p; - int mask = (1 << hd->minor_shift) - 1; - int i; - char buf[40]; - - data = read_dev_sector(bdev, offset, §); - if (!data) - return; - - p = (struct partition *)(data + 0x1be); - - /* The first sector of a Minix partition can have either - * a secondary MBR describing its subpartitions, or - * the normal boot sector. */ - if (msdos_magic_present (data + 510) && - SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ - - printk(" %s: <minix:", partition_name(hd, minor, buf)); - for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) { - if ((*current_minor & mask) == 0) - break; - /* add each partition in use */ - if (SYS_IND(p) == MINIX_PARTITION) { - add_gd_partition(hd, *current_minor, - START_SECT(p), NR_SECTS(p)); - (*current_minor)++; - } - } - printk(" >\n"); - } - put_dev_sector(sect); -#endif /* CONFIG_MINIX_SUBPARTITION */ -} - -static struct { - unsigned char id; - void (*parse)(struct gendisk *, struct block_device *, int, int *); -} subtypes[] = { - {BSD_PARTITION, bsd_partition}, - {NETBSD_PARTITION, netbsd_partition}, - {OPENBSD_PARTITION, openbsd_partition}, - {MINIX_PARTITION, minix_partition}, - {UNIXWARE_PARTITION, unixware_partition}, - {SOLARIS_X86_PARTITION, solaris_x86_partition}, - {0, NULL}, -}; -/* - * Look for various forms of IDE disk geometry translation - */ -static int handle_ide_mess(struct block_device *bdev) -{ -#ifdef CONFIG_BLK_DEV_IDE - Sector sect; - unsigned char *data; - kdev_t dev = to_kdev_t(bdev->bd_dev); - unsigned int sig; - int heads = 0; - struct partition *p; - int i; - - if (MSDOS_DEBUG) - printk (KERN_ALERT "handle_ide_mess ------------\n"); - - /* - * The i386 partition handling programs very often - * make partitions end on cylinder boundaries. - * There is no need to do so, and Linux fdisk doesnt always - * do this, and Windows NT on Alpha doesnt do this either, - * but still, this helps to guess #heads. - */ - data = read_dev_sector(bdev, 0, §); - if (!data) - return -1; - if (!msdos_magic_present(data + 510)) { - put_dev_sector(sect); - return 0; - } - sig = le16_to_cpu(*(unsigned short *)(data + 2)); - p = (struct partition *) (data + 0x1be); - for (i = 0; i < 4; i++) { - struct partition *q = &p[i]; - if (NR_SECTS(q)) { - if ((q->sector & 63) == 1 && - (q->end_sector & 63) == 63) - heads = q->end_head + 1; - break; - } - } - if (SYS_IND(p) == EZD_PARTITION) { - /* - * Accesses to sector 0 must go to sector 1 instead. - */ - if (ide_xlate_1024(dev, -1, heads, " [EZD]")) - goto reread; - } else if (SYS_IND(p) == DM6_PARTITION) { - - /* - * Everything on the disk is offset by 63 sectors, - * including a "new" MBR with its own partition table. - */ - if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]")) - goto reread; - } else if (sig <= 0x1ae && - data[sig] == 0xAA && data[sig+1] == 0x55 && - (data[sig+2] & 1)) { - /* DM6 signature in MBR, courtesy of OnTrack */ - (void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]"); - } else if (SYS_IND(p) == DM6_AUX1PARTITION || - SYS_IND(p) == DM6_AUX3PARTITION) { - /* - * DM6 on other than the first (boot) drive - */ - (void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]"); - } else { - (void) ide_xlate_1024(dev, 2, heads, " [PTBL]"); - } - put_dev_sector(sect); - - if (MSDOS_DEBUG) - printk (KERN_ALERT "handle_ide_mess -------- %d\n", heads); - return 1; - -reread: - put_dev_sector(sect); - /* Flush the cache */ - invalidate_bdev(bdev, 1); - truncate_inode_pages(bdev->bd_inode->i_mapping, 0); -#endif /* CONFIG_BLK_DEV_IDE */ - return 1; -} - -int msdos_partition(struct gendisk *hd, struct block_device *bdev, - unsigned long first_sector, int first_part_minor) -{ - int i, minor = first_part_minor; - Sector sect; - struct partition *p; - unsigned char *data; - int mask = (1 << hd->minor_shift) - 1; - int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512; - int current_minor = first_part_minor; - int err; - - if (MSDOS_DEBUG) printk (KERN_ALERT "msdos.c::msdos_partition\n"); - err = handle_ide_mess(bdev); - if (err <= 0) - return err; - data = read_dev_sector(bdev, 0, §); - if (!data) - return -1; - if (!msdos_magic_present(data + 510)) { - put_dev_sector(sect); - return 0; - } - p = (struct partition *) (data + 0x1be); - - /* - * Look for partitions in two passes: - * First find the primary and DOS-type extended partitions. - * On the second pass look inside *BSD, Unixware and Solaris partitions. - */ - - current_minor += 4; - for (i=1 ; i<=4 ; minor++,i++,p++) { - if (!NR_SECTS(p)) - continue; - add_gd_partition(hd, minor, - first_sector+START_SECT(p)*sector_size, - NR_SECTS(p)*sector_size); -#if CONFIG_BLK_DEV_MD - if (SYS_IND(p) == LINUX_RAID_PARTITION) { - md_autodetect_dev(MKDEV(hd->major,minor)); - } -#endif - if (is_extended_partition(p)) { - unsigned long size = hd->part[minor].nr_sects; - printk(" <"); - /* prevent someone doing mkfs or mkswap on an - extended partition, but leave room for LILO */ - if (size > 2) - hd->part[minor].nr_sects = 2; - extended_partition(hd, bdev, minor, size, ¤t_minor); - printk(" >"); - } - } - - /* - * Check for old-style Disk Manager partition table - */ - if (msdos_magic_present(data + 0xfc)) { - p = (struct partition *) (0x1be + data); - for (i = 4 ; i < 16 ; i++, current_minor++) { - p--; - if ((current_minor & mask) == 0) - break; - if (!(START_SECT(p) && NR_SECTS(p))) - continue; - add_gd_partition(hd, current_minor, START_SECT(p), NR_SECTS(p)); - } - } - printk("\n"); - - /* second pass - output for each on a separate line */ - minor -= 4; - p = (struct partition *) (0x1be + data); - for (i=1 ; i<=4 ; minor++,i++,p++) { - unsigned char id = SYS_IND(p); - int n; - - if (!NR_SECTS(p)) - continue; - - for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++) - ; - - if (subtypes[n].parse) - subtypes[n].parse(hd, bdev, minor, ¤t_minor); - } - put_dev_sector(sect); - return 1; -} |