From: "jdow" 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 --- 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, §); 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"); _