From: "jdow" <jdow@earthlink.net>

I have a large archive of files stored on Amiga volumes.  Many of these
volumes are on Fujitsu magneto-optical disks with 2k sector size.  The
existing partitioning code cannot properly read them since it appears the
OS automatically deblocks the large sectors into logical 512 byte sectors,
something AmigaDOS never did.  I arranged the partitioning code to handle
this situation.

Second I have some rather strange test case disks, including my largest
storage partition, that have somewhat unusual partition values.  As such I
needed additional information in addition to the first and last block
number information.  AmigaDOS reserves N blocks, with N greater than or
equal to 1 and less than the size of the partition, for some boot time
information and signatures.  I have some partitions that use other than the
usual value of 2.

There is one more "fix" that could be put in if someone needs it.  Another
value in the "Rigid Disk Blocks" description of a partition is a "PreAlloc"
value.  It defines a number of blocks at the end of the disk that are not
considered to be a real part of the partition.  This was "important" in the
days of 20 meg and 40 meg hard disks.  It is hardly important and not used
on modern drives without special user intervention.

This partitioning information is known correct.  I wrote the low level
portion of the hard disk partitioning code for AmigaDOS 3.5 and 3.9.  I am
also responsible for one of the more frequently used partitioning tools,
RDPrepX, before that.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/partitions/amiga.c |   30 +++++++++++++++++++++++++++---
 1 files changed, 27 insertions(+), 3 deletions(-)

diff -puN fs/partitions/amiga.c~amiga-partition-reading-fix fs/partitions/amiga.c
--- 25/fs/partitions/amiga.c~amiga-partition-reading-fix	2004-08-25 00:09:29.812191552 -0700
+++ 25-akpm/fs/partitions/amiga.c	2004-08-25 00:09:29.815191096 -0700
@@ -31,6 +31,7 @@ amiga_partition(struct parsed_partitions
 	struct RigidDiskBlock *rdb;
 	struct PartitionBlock *pb;
 	int start_sect, nr_sects, blk, part, res = 0;
+	int blksize = 1;	/* Multiplier for disk block size */
 	int slot = 1;
 	char b[BDEVNAME_SIZE];
 
@@ -65,10 +66,14 @@ amiga_partition(struct parsed_partitions
 			       bdevname(bdev, b), blk);
 	}
 
-	printk(" RDSK");
+	/* blksize is blocks per 512 byte standard block */
+	blksize = be32_to_cpu( rdb->rdb_BlockBytes ) / 512;
+
+	printk(" RDSK (%d)", blksize * 512);	/* Be more informative */
 	blk = be32_to_cpu(rdb->rdb_PartitionList);
 	put_dev_sector(sect);
 	for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) {
+		blk *= blksize;	/* Read in terms partition table understands */
 		data = read_dev_sector(bdev, blk, &sect);
 		if (!data) {
 			if (warn_no_part)
@@ -88,13 +93,32 @@ amiga_partition(struct parsed_partitions
 		nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
 			    be32_to_cpu(pb->pb_Environment[9])) *
 			   be32_to_cpu(pb->pb_Environment[3]) *
-			   be32_to_cpu(pb->pb_Environment[5]);
+			   be32_to_cpu(pb->pb_Environment[5]) *
+			   blksize;
 		if (!nr_sects)
 			continue;
 		start_sect = be32_to_cpu(pb->pb_Environment[9]) *
 			     be32_to_cpu(pb->pb_Environment[3]) *
-			     be32_to_cpu(pb->pb_Environment[5]);
+			     be32_to_cpu(pb->pb_Environment[5]) *
+			     blksize;
 		put_partition(state,slot++,start_sect,nr_sects);
+		{
+			/* Be even more informative to aid mounting */
+			char dostype[4];
+			u32 *dt = (u32 *)dostype;
+			*dt = pb->pb_Environment[16];
+			if (dostype[3] < ' ')
+				printk(" (%c%c%c^%c)",
+					dostype[0], dostype[1],
+					dostype[2], dostype[3] + '@' );
+			else
+				printk(" (%c%c%c%c)",
+					dostype[0], dostype[1],
+					dostype[2], dostype[3]);
+			printk("(res %d spb %d)",
+				be32_to_cpu(pb->pb_Environment[6]),
+				be32_to_cpu(pb->pb_Environment[4]));
+		}
 		res = 1;
 	}
 	printk("\n");
_