Commit b13b24e7 authored by Joanne Dow's avatar Joanne Dow Committed by Linus Torvalds

[PATCH] Amiga partition reading fix

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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 33982f7f
...@@ -31,6 +31,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -31,6 +31,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev)
struct RigidDiskBlock *rdb; struct RigidDiskBlock *rdb;
struct PartitionBlock *pb; struct PartitionBlock *pb;
int start_sect, nr_sects, blk, part, res = 0; int start_sect, nr_sects, blk, part, res = 0;
int blksize = 1; /* Multiplier for disk block size */
int slot = 1; int slot = 1;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
...@@ -65,10 +66,14 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -65,10 +66,14 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev)
bdevname(bdev, b), blk); 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); blk = be32_to_cpu(rdb->rdb_PartitionList);
put_dev_sector(sect); put_dev_sector(sect);
for (part = 1; blk>0 && part<=16; part++, 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); data = read_dev_sector(bdev, blk, &sect);
if (!data) { if (!data) {
if (warn_no_part) if (warn_no_part)
...@@ -88,13 +93,32 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -88,13 +93,32 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev)
nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
be32_to_cpu(pb->pb_Environment[9])) * be32_to_cpu(pb->pb_Environment[9])) *
be32_to_cpu(pb->pb_Environment[3]) * 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) if (!nr_sects)
continue; continue;
start_sect = be32_to_cpu(pb->pb_Environment[9]) * start_sect = be32_to_cpu(pb->pb_Environment[9]) *
be32_to_cpu(pb->pb_Environment[3]) * 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); 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; res = 1;
} }
printk("\n"); printk("\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment