summaryrefslogtreecommitdiffstats
path: root/fs/partitions
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-16 01:07:24 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-16 01:07:24 +0000
commit95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch)
tree27a92a942821cde1edda9a1b088718d436b3efe4 /fs/partitions
parent45b27b0a0652331d104c953a5b192d843fff88f8 (diff)
Merge with Linux 2.3.40.
Diffstat (limited to 'fs/partitions')
-rw-r--r--fs/partitions/acorn.c3
-rw-r--r--fs/partitions/check.c39
-rw-r--r--fs/partitions/msdos.c145
3 files changed, 94 insertions, 93 deletions
diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c
index bce1d34aa..34aab5f44 100644
--- a/fs/partitions/acorn.c
+++ b/fs/partitions/acorn.c
@@ -14,9 +14,10 @@
#include <linux/genhd.h>
#include <linux/fs.h>
+#include "check.h"
#include "acorn.h"
-extern void add_gd_partition(struct gendisk *hd, unsigned int minor, unsigned int start, unsigned int size);
+extern void add_gd_partition(struct gendisk *hd, int minor, int start, int size);
static void
adfspart_setgeometry(kdev_t dev, unsigned int secspertrack, unsigned int heads,
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index e3d8ed60b..ec0bd3a4b 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -235,7 +235,7 @@ int get_partition_list(char * page)
}
#endif
-void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
+static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
{
static int first_time = 1;
unsigned long first_sector;
@@ -273,13 +273,27 @@ void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
* Much of the cleanup from the old partition tables should have already been
* done
*/
-void resetup_one_dev(struct gendisk *dev, int drive)
+
+void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors,
+ struct block_device_operations *ops, long size)
+{
+ unsigned first = (unsigned)dev;
+ 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;
blk_size[dev->major] = NULL;
+ dev->part[first_minor].nr_sects = size;
+ /* No Such Agen^Wdevice or no minors to use for partitions */
+ if (!size || minors == 1)
+ return;
check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
/*
@@ -293,31 +307,10 @@ void resetup_one_dev(struct gendisk *dev, int drive)
}
}
-static inline void setup_dev(struct gendisk *dev)
-{
- int i, drive;
- int end_minor = dev->max_nr * dev->max_p;
-
- blk_size[dev->major] = NULL;
- for (i = 0; i < end_minor; i++) {
- dev->part[i].start_sect = 0;
- dev->part[i].nr_sects = 0;
- dev->sizes[i] = 0;
- }
- dev->init(dev);
- for (drive = 0 ; drive < dev->nr_real ; drive++)
- resetup_one_dev(dev, drive);
-}
-
int __init partition_setup(void)
{
- struct gendisk *p;
-
device_init();
- for (p = gendisk_head ; p ; p=p->next)
- setup_dev(p);
-
#ifdef CONFIG_BLK_DEV_RAM
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && mount_initrd) initrd_load();
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index c05d6cf30..8ab3f071a 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -163,25 +163,37 @@ done:
bforget(bh);
}
+static inline struct buffer_head *
+get_partition_table_block(struct gendisk *hd, int minor, int blocknr) {
+ kdev_t dev = MKDEV(hd->major, minor);
+ return bread(dev, blocknr, get_ptable_blocksize(dev));
+}
+
#ifdef CONFIG_SOLARIS_X86_PARTITION
+
+/* 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, kdev_t dev, long offset) {
+solaris_x86_partition(struct gendisk *hd, int minor) {
+ long offset = hd->part[minor].start_sect;
struct buffer_head *bh;
struct solaris_x86_vtoc *v;
struct solaris_x86_slice *s;
int i;
+ char buf[40];
- if(!(bh = bread(dev, 0, get_ptable_blocksize(dev))))
+ if(!(bh = get_partition_table_block(hd, minor, 0)))
return;
v = (struct solaris_x86_vtoc *)(bh->b_data + 512);
if(v->v_sanity != SOLARIS_X86_VTOC_SANE) {
brelse(bh);
return;
}
- printk(" <solaris:");
+ printk(" %s: <solaris:", disk_name(hd, minor, buf));
if(v->v_version != 1) {
- printk(" cannot handle version %ld vtoc>", v->v_version);
+ printk(" cannot handle version %ld vtoc>\n", v->v_version);
brelse(bh);
return;
}
@@ -199,21 +211,21 @@ solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
current_minor++;
}
brelse(bh);
- printk(" >");
+ printk(" >\n");
}
#endif
#ifdef CONFIG_BSD_DISKLABEL
-static void check_and_add_bsd_partition(struct gendisk *hd,
- struct bsd_partition *bsd_p, kdev_t dev)
-{
+static void
+check_and_add_bsd_partition(struct gendisk *hd,
+ struct bsd_partition *bsd_p, int minor) {
struct hd_struct *lin_p;
/* check relative position of partitions. */
- for (lin_p = hd->part + 1 + MINOR(dev);
- lin_p - hd->part - MINOR(dev) < current_minor; lin_p++) {
+ 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 <= bsd_p->p_offset
- || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
+ if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset ||
+ lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
continue;
/* equal -> no need to add */
if (lin_p->start_sect == bsd_p->p_offset &&
@@ -244,26 +256,32 @@ static void check_and_add_bsd_partition(struct gendisk *hd,
add_gd_partition(hd, current_minor, bsd_p->p_offset, 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 bsd_disklabel_partition(struct gendisk *hd, kdev_t dev,
- int max_partitions)
-{
+static void bsd_disklabel_partition(struct gendisk *hd, int minor, int type) {
struct buffer_head *bh;
struct bsd_disklabel *l;
struct bsd_partition *p;
+ int max_partitions;
int mask = (1 << hd->minor_shift) - 1;
+ char buf[40];
- if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+ if (!(bh = get_partition_table_block(hd, minor, 0)))
return;
l = (struct bsd_disklabel *) (bh->b_data+512);
if (l->d_magic != BSD_DISKMAGIC) {
brelse(bh);
return;
}
+ printk(" %s:", disk_name(hd, minor, buf));
+ printk((type == OPENBSD_PARTITION) ? " <openbsd:" :
+ (type == NETBSD_PARTITION) ? " <netbsd:" : " <bsd:");
+ max_partitions = ((type == OPENBSD_PARTITION) ? OPENBSD_MAXPARTITIONS
+ : BSD_MAXPARTITIONS);
if (l->d_npartitions < max_partitions)
max_partitions = l->d_npartitions;
for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
@@ -271,12 +289,13 @@ static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev,
break;
if (p->p_fstype != BSD_FS_UNUSED)
- check_and_add_bsd_partition(hd, p, dev);
+ check_and_add_bsd_partition(hd, p, minor);
}
/* Use bforget(), as we have changed the disk setup */
bforget(bh);
+ printk(" >\n");
}
#endif
@@ -285,14 +304,14 @@ static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev,
* 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, kdev_t dev)
-{
+static void unixware_partition(struct gendisk *hd, int minor) {
struct buffer_head *bh;
struct unixware_disklabel *l;
struct unixware_slice *p;
int mask = (1 << hd->minor_shift) - 1;
+ char buf[40];
- if (!(bh = bread(dev, 14, get_ptable_blocksize(dev))))
+ if (!(bh = get_partition_table_block(hd, minor, 14)))
return;
l = (struct unixware_disklabel *) (bh->b_data+512);
if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
@@ -300,7 +319,7 @@ static void unixware_partition(struct gendisk *hd, kdev_t dev)
brelse(bh);
return;
}
- printk(" <unixware:");
+ printk(" %s: <unixware:", disk_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) {
@@ -308,30 +327,26 @@ static void unixware_partition(struct gendisk *hd, kdev_t dev)
break;
if (p->s_label != UNIXWARE_FS_UNUSED) {
- add_gd_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
+ add_gd_partition(hd, current_minor, START_SECT(p),
+ NR_SECTS(p));
current_minor++;
}
p++;
}
/* Use bforget, as we have changed the disk setup */
bforget(bh);
- printk(" >");
+ printk(" >\n");
}
#endif
-int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor)
-{
+int msdos_partition(struct gendisk *hd, kdev_t dev,
+ unsigned long first_sector, int first_part_minor) {
int i, minor = current_minor = first_part_minor;
struct buffer_head *bh;
struct partition *p;
unsigned char *data;
int mask = (1 << hd->minor_shift) - 1;
int sector_size = get_hardsect_size(dev) / 512;
-#ifdef CONFIG_BSD_DISKLABEL
- /* no bsd disklabel as a default */
- kdev_t bsd_kdev = 0;
- int bsd_maxpart = BSD_MAXPARTITIONS;
-#endif
#ifdef CONFIG_BLK_DEV_IDE
int tested_for_xlate = 0;
@@ -345,7 +360,7 @@ read_mbr:
#ifdef CONFIG_BLK_DEV_IDE
check_table:
#endif
- /* Use bforget(), because we have potentially changed the disk geometry */
+ /* Use bforget(), because we may have changed the disk geometry */
if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
bforget(bh);
return 0;
@@ -410,11 +425,16 @@ check_table:
}
#endif /* CONFIG_BLK_DEV_IDE */
+ /* Look for partitions in two passes:
+ First find the primary partitions, and the DOS-type extended partitions.
+ On the second pass look inside *BSD and Unixware and Solaris partitions. */
+
current_minor += 4; /* first "extra" minor (for extended partitions) */
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);
+ add_gd_partition(hd, minor, first_sector+START_SECT(p)*sector_size,
+ NR_SECTS(p)*sector_size);
if (is_extended_partition(p)) {
printk(" <");
/*
@@ -432,44 +452,8 @@ check_table:
if (hd->part[minor].nr_sects > 2)
hd->part[minor].nr_sects = 2;
}
-#ifdef CONFIG_BSD_DISKLABEL
- /* tag first disklabel for late recognition */
- if (SYS_IND(p) == BSD_PARTITION || SYS_IND(p) == NETBSD_PARTITION) {
- printk("!");
- if (!bsd_kdev)
- bsd_kdev = MKDEV(hd->major, minor);
- } else if (SYS_IND(p) == OPENBSD_PARTITION) {
- printk("!");
- if (!bsd_kdev) {
- bsd_kdev = MKDEV(hd->major, minor);
- bsd_maxpart = OPENBSD_MAXPARTITIONS;
- }
- }
-#endif
-#ifdef CONFIG_UNIXWARE_DISKLABEL
- if (SYS_IND(p) == UNIXWARE_PARTITION)
- unixware_partition(hd, MKDEV(hd->major, minor));
-#endif
-#ifdef CONFIG_SOLARIS_X86_PARTITION
-
- /* james@bpgc.com: Solaris has a nasty indicator: 0x82
- * which also means linux swap. For that reason, all
- * of the prints are done inside the
- * solaris_x86_partition routine */
-
- if(SYS_IND(p) == SOLARIS_X86_PARTITION) {
- solaris_x86_partition(hd, MKDEV(hd->major, minor),
- first_sector+START_SECT(p));
- }
-#endif
- }
-#ifdef CONFIG_BSD_DISKLABEL
- if (bsd_kdev) {
- printk(" <");
- bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart);
- printk(" >");
}
-#endif
+
/*
* Check for old-style Disk Manager partition table
*/
@@ -485,6 +469,29 @@ check_table:
}
}
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++) {
+ if (!NR_SECTS(p))
+ continue;
+#ifdef CONFIG_BSD_DISKLABEL
+ if (SYS_IND(p) == BSD_PARTITION ||
+ SYS_IND(p) == NETBSD_PARTITION ||
+ SYS_IND(p) == OPENBSD_PARTITION)
+ bsd_disklabel_partition(hd, minor, SYS_IND(p));
+#endif
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+ if (SYS_IND(p) == UNIXWARE_PARTITION)
+ unixware_partition(hd, minor);
+#endif
+#ifdef CONFIG_SOLARIS_X86_PARTITION
+ if(SYS_IND(p) == SOLARIS_X86_PARTITION)
+ solaris_x86_partition(hd, minor);
+#endif
+ }
+
bforget(bh);
return 1;
}