mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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
This commit is contained in:
1 parent
b772c635b9
commit
04c216516f
3 files changed
-1087
No files matched your search
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||