Subject: port-amiga/9729: Can't use media with sector size greater than 512 bytes
To: None <netbsd-bugs@netbsd.org>
From: John Darrow <John.P.Darrow@wheaton.edu>
List: netbsd-bugs
Date: 04/05/2000 14:58:19
Date: Wed, 26 May 1999 22:59:45 +0200
From: TetiSoft@apg.lahn.de (=?ISO-8859-1?Q?Detlef_W=FCrkner?=)
To: gnats-bugs@gnats.netbsd.org
Subject: Can't use media with sector size greater than 512 bytes
>Number: 9729
>Category: port-amiga
>Synopsis: media with sector size > 512 don't work.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-amiga-maintainer
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Fri Mar 31 00:16:43 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Detlef Wuerkner
>Release: Sat May 8 21:10:58 UTC 1999
>Organization:
>Environment:
Amiga 4000, CyberStorm MkII/060/SCSI, 640MB MO-drive, NetBSD1.4/amiga
System: NetBSD mobile 1.4 NetBSD 1.4 (GENERIC) #50: Sun May 9 17:10:33 MEST 1999 is@jocelyn:/usr/obj/kernel/GENERIC amiga
>Description:
Partitions on media with physical sektor size greater than
the normal 512 bytes can't be found by NetBSD 1.4/amiga
(error message "partition block with bad id" at boot time).
Some other changes are suggested for successfull usage of a file
system on such media.
>How-To-Repeat:
Of course you need media with physical sector size greater than
512 bytes, for example 3,5" 640MB MO-media (2048 bytes/sector).
Partition it on an amiga with the latest HDToolBox (40.4) and
boot NetBSD (from another drive). The error message
"sdx: partition block with bad id" appears while booting,
and "disklabel sdx" doesn't show the partitions.
>Fix:
The reason for the problem is the fact that NetBSD counts blocks
in DEV_BSIZE units (always 512?), but AmigaOS counts blocks in
physical units.
In /usr/src/sys/dev/scsipi/sd.c, routine sdstart() adjusts the
block numbers, it changes from DEV_BSIZE units to physical units:
blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
As long as media with sector sizes of 512 bytes are used, this
doesn't matter (divide by 1), but for successfull usage of media
with greater sector sizes (e.g. 640MB MO-media with
2048 bytes/sector) we must multiply block numbers with
(lp->d_secsize / DEV_BSIZE) to keep "unchanged" physical block
numbers.
Several other problem reports dealt with the adjustment from
physical to DEV_BSIZE units in sd.c, especially the PR's
number 495, 3460, 3790, 3791 and 3792, all years old. Since
nothing changed until now, I suggest the following changes to
/usr/src/sys/arch/amiga/amiga/disksubr.c, the disksubr.c-
routines of other architectures may need similar changes.
If in future sd.c is changed, disksubr.c only needs a change
of a #define-line.
In /usr/src/sys/arch/amiga/amiga/disksubr.c, before reading the
RDSK- and PART-blocks the block number has to be multiplied with
(physical block size / DEV_BSIZE).
Since the block numbers now may be greater by powers of two,
and bounds_check_with_label() is called from sd.c before
adjusting the block number, bounds_check_with_label() must be
adopted. The current version did a check for the B_RAW flag,
that relied on a patch of sd.c suggested in problem report 495
but not included in the source tree. The bounds_check_with_label()
functions of some other architectures also contain this
currently unnecessary check for B_RAW.
Also, the block size of AmigaDOS-partitions must be changed from
constant 512 to max(512, lp->d_secsize) to force reading of at
least the physical block size and for e.g. correct checksumming
routines in adosfs. A problem report which enables adosfs to
handle AmigaDOS-partitions with sector size > 512 will follow.
OK, and here's the diff:
*** bffsc:src/sys/arch/amiga/amiga/disksubr.c.orig Wed Apr 28 22:44:34 1999
--- bffsc:src/sys/arch/amiga/amiga/disksubr.c Wed May 26 21:56:51 1999
***************
*** 42,49 ****
--- 42,61 ----
#include <sys/disk.h>
#include <amiga/amiga/adosglue.h>
/*
+ * In /usr/src/sys/dev/scsipi/sd.c, routine sdstart() adjusts the
+ * block numbers, it changes from DEV_BSIZE units to physical units:
+ * blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
+ * As long as media with sector sizes of 512 bytes are used, this
+ * doesn't matter (divide by 1), but for successfull usage of media with
+ * greater sector sizes (e.g. 640MB MO-media with 2048 bytes/sector)
+ * we must multiply block numbers with (lp->d_secsize / DEV_BSIZE)
+ * to keep "unchanged" physical block numbers.
+ */
+ #define SD_C_ADJUSTS_NR
+
+ /*
* bitmap id's
*/
#define RDBLOCK_BID 1
#define PARTBLOCK_BID 2
***************
*** 152,159 ****
--- 164,174 ----
bp->b_blkno = nextb;
bp->b_cylin = bp->b_blkno / lp->d_secpercyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
+ #ifdef SD_C_ADJUSTS_NR
+ bp->b_blkno *= (lp->d_secsize / DEV_BSIZE);
+ #endif
strat(bp);
if (biowait(bp)) {
msg = "rdb scan I/O error";
***************
*** 243,250 ****
--- 258,268 ----
bp->b_blkno = nextb;
bp->b_cylin = bp->b_blkno / lp->d_secpercyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
+ #ifdef SD_C_ADJUSTS_NR
+ bp->b_blkno *= (lp->d_secsize / DEV_BSIZE);
+ #endif
strat(bp);
if (biowait(bp)) {
msg = "partition scan I/O error";
***************
*** 368,385 ****
/*
* Save reserved blocks at begin in cpg and
* adjust size by reserved blocks at end
*/
! pp->p_fsize = 512;
pp->p_frag = pbp->e.secperblk;
pp->p_cpg = pbp->e.resvblocks;
pp->p_size -= pbp->e.prefac;
} else if (pbp->e.tabsize > 22 && ISFSARCH_NETBSD(adt)) {
pp->p_fsize = pbp->e.fsize;
pp->p_frag = pbp->e.frag;
pp->p_cpg = pbp->e.cpg;
} else {
! pp->p_fsize = 1024;
pp->p_frag = 8;
pp->p_cpg = 0;
}
--- 386,415 ----
/*
* Save reserved blocks at begin in cpg and
* adjust size by reserved blocks at end
*/
!
! /*
! * file system block size must be at least
! * physical block size and at least 512
! */
! pp->p_fsize = max(512, lp->d_secsize);
!
pp->p_frag = pbp->e.secperblk;
pp->p_cpg = pbp->e.resvblocks;
pp->p_size -= pbp->e.prefac;
} else if (pbp->e.tabsize > 22 && ISFSARCH_NETBSD(adt)) {
pp->p_fsize = pbp->e.fsize;
pp->p_frag = pbp->e.frag;
pp->p_cpg = pbp->e.cpg;
} else {
!
! /*
! * file system block size must be at least
! * physical block size and at least 1024
! */
! pp->p_fsize = max(1024, lp->d_secsize);
!
pp->p_frag = 8;
pp->p_cpg = 0;
}
***************
*** 483,498 ****
struct partition *pp;
long maxsz, sz;
pp = &lp->d_partitions[DISKPART(bp->b_dev)];
! if (bp->b_flags & B_RAW) {
! maxsz = pp->p_size * (lp->d_secsize / DEV_BSIZE);
! sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
! } else {
! maxsz = pp->p_size;
! sz = (bp->b_bcount + lp->d_secsize - 1) / lp->d_secsize;
! }
!
if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
if (bp->b_blkno == maxsz) {
/*
* trying to get one block beyond return EOF.
--- 513,531 ----
struct partition *pp;
long maxsz, sz;
pp = &lp->d_partitions[DISKPART(bp->b_dev)];
! /*
! * This routine is called before sd.c adjusts block numbers
! * and must take this into account
! */
! #ifdef SD_C_ADJUSTS_NR
! maxsz = pp->p_size * (lp->d_secsize / DEV_BSIZE);
! sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
! #else
! maxsz = pp->p_size;
! sz = (bp->b_bcount + lp->d_secsize - 1) / lp->d_secsize;
! #endif
if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
if (bp->b_blkno == maxsz) {
/*
* trying to get one block beyond return EOF.
Ciao, Detlef
--
_ // TetiSoft@apg.lahn.de
\X/ Detlef Wuerkner, Giessen, Germany
>Release-Note:
>Audit-Trail:
>Unformatted: