Subject: kern/3792: non-512 bytes/sector media support case 3
To: None <gnats-bugs@gnats.netbsd.org>
From: None <koji@math.human.nagoya-u.ac.jp>
List: netbsd-bugs
Date: 06/25/1997 17:06:53
>Number:         3792
>Category:       kern
>Synopsis:       non-512 bytes/sector media support case 3
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 25 01:50:01 1997
>Last-Modified:
>Originator:     Koji Imada - je4owb/2
>Organization:
Mathematics Group of Graduate School of Human
	Infomatics, Nagoya University, Japan.
>Release:        970622
>Environment:
	
System: NetBSD bimota 1.2E NetBSD 1.2E (BIMOTA) #: Wed Jun 11 02:13:27 JST 1997 koji@ducati:/mnt2/NetBSD/work/src-ufs-mod/sys/arch/i386/compile/BIMOTA i386


>Description:
	Modification required to support non-512 bytes/sector media
	for file system and device drivers.

	This is case 3 of 3 implementation. This changes block io unit
	to natural size of device and adapts file systems(cd9660, ffs,
	msdosfs) and device driver(cd, sd) to support non-512
	bytes/sector media.

	I will send mail to tech-kern about these 3 implementation.

	Also, these obsoletes kern/3460 and kern/3458
>How-To-Repeat:
	Current NetBSD can't handle non-512 bytes/sector media properly.
>Fix:
	Apply following patches
Index: sys/arch/i386/i386/disksubr.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/arch/i386/i386/disksubr.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- disksubr.c	1997/04/01 07:21:40	1.1.1.2
+++ disksubr.c	1997/05/29 17:50:43	1.2
@@ -91,7 +91,7 @@
 	lp->d_partitions[i].p_offset = 0;
 
 	/* get a buffer and initialize it */
-	bp = geteblk((int)lp->d_secsize);
+	bp = geteblk((int)BLKDEV_IOSIZE);
 	bp->b_dev = dev;
 
 	/* do dos partitions in the process of getting disklabel? */
@@ -100,6 +100,12 @@
 	if (osdep && (dp = osdep->dosparts) != NULL) {
 		/* read master boot record */
 		bp->b_blkno = DOSBBSECTOR;
+#if 0
+		if (lp->d_secsize > DEV_BSIZE)
+			bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+		else
+			bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+#endif
 		bp->b_bcount = lp->d_secsize;
 		bp->b_flags = B_BUSY | B_READ;
 		bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl;
@@ -148,8 +154,14 @@
 	
 	/* next, dig out disk label */
 	bp->b_blkno = dospartoff + LABELSECTOR;
+#if 0
+	if (lp->d_secsize > DEV_BSIZE)
+		bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+	else
+		bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+#endif
 	bp->b_cylin = cyl;
-	bp->b_bcount = lp->d_secsize;
+	bp->b_bcount = BLKDEV_IOSIZE;
 	bp->b_flags = B_BUSY | B_READ;
 	(*strat)(bp);
 
@@ -159,7 +171,7 @@
 		goto done;
 	}
 	for (dlp = (struct disklabel *)bp->b_data;
-	    dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
+	    dlp <= (struct disklabel *)(bp->b_data + BLKDEV_IOSIZE - sizeof(*dlp));
 	    dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
 		if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
 			if (msg == NULL)
@@ -186,10 +198,12 @@
 			/* read a bad sector table */
 			bp->b_flags = B_BUSY | B_READ;
 			bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i;
+#if 0
 			if (lp->d_secsize > DEV_BSIZE)
 				bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
 			else
 				bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+#endif
 			bp->b_bcount = lp->d_secsize;
 			bp->b_cylin = lp->d_ncylinders - 1;
 			(*strat)(bp);
@@ -291,7 +305,7 @@
 	int error, dospartoff, cyl, i;
 
 	/* get a buffer and initialize it */
-	bp = geteblk((int)lp->d_secsize);
+	bp = geteblk(BLKDEV_IOSIZE);
 	bp->b_dev = dev;
 
 	/* do dos partitions in the process of getting disklabel? */
@@ -300,6 +314,12 @@
 	if (osdep && (dp = osdep->dosparts) != NULL) {
 		/* read master boot record */
 		bp->b_blkno = DOSBBSECTOR;
+#if 0
+		if (lp->d_secsize > DEV_BSIZE)
+			bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+		else
+			bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+#endif
 		bp->b_bcount = lp->d_secsize;
 		bp->b_flags = B_BUSY | B_READ;
 		bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl;
@@ -333,8 +353,14 @@
 
 	/* next, dig out disk label */
 	bp->b_blkno = dospartoff + LABELSECTOR;
+#if 0
+	if (lp->d_secsize > DEV_BSIZE)
+		bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+	else
+		bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+#endif
 	bp->b_cylin = cyl;
-	bp->b_bcount = lp->d_secsize;
+	bp->b_bcount = BLKDEV_IOSIZE;
 	bp->b_flags = B_BUSY | B_READ;
 	(*strat)(bp);
 
@@ -342,7 +368,7 @@
 	if ((error = biowait(bp)) != 0)
 		goto done;
 	for (dlp = (struct disklabel *)bp->b_data;
-	    dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
+	    dlp <= (struct disklabel *)(bp->b_data + BLKDEV_IOSIZE - sizeof(*dlp));
 	    dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
 		if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
 		    dkcksum(dlp) == 0) {
@@ -374,12 +400,21 @@
 {
 	struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
 	int labelsector = lp->d_partitions[2].p_offset + LABELSECTOR;
-	int sz;
+	int sz, blkno;
+
+#if 1
+	blkno = bp->b_blkno;
+#else
+	if (lp->d_secsize > DEV_BSIZE)
+		blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
+	else
+		blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
+#endif
 
 	sz = howmany(bp->b_bcount, lp->d_secsize);
 
-	if (bp->b_blkno + sz > p->p_size) {
-		sz = p->p_size - bp->b_blkno;
+	if (blkno + sz > p->p_size) {
+		sz = p->p_size - blkno;
 		if (sz == 0) {
 			/* If exactly at end of disk, return EOF. */
 			bp->b_resid = bp->b_bcount;
@@ -391,13 +426,13 @@
 			goto bad;
 		}
 		/* Otherwise, truncate request. */
-		bp->b_bcount = sz << DEV_BSHIFT;
+		bp->b_bcount = sz * lp->d_secsize;
 	}
 
 	/* Overwriting disk label? */
-	if (bp->b_blkno + p->p_offset <= labelsector &&
+	if (blkno + p->p_offset <= labelsector &&
 #if LABELSECTOR != 0
-	    bp->b_blkno + p->p_offset + sz > labelsector &&
+	    blkno + p->p_offset + sz > labelsector &&
 #endif
 	    (bp->b_flags & B_READ) == 0 && !wlabel) {
 		bp->b_error = EROFS;
@@ -405,8 +440,7 @@
 	}
 
 	/* calculate cylinder for disksort to order transfers with */
-	bp->b_cylin = (bp->b_blkno + p->p_offset) /
-	    (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
+	bp->b_cylin = (blkno + p->p_offset) / lp->d_secpercyl;
 	return (1);
 
 bad:
Index: sys/dev/vnd.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/dev/vnd.c,v
retrieving revision 1.1.1.5
retrieving revision 1.4
diff -u -r1.1.1.5 -r1.4
--- vnd.c	1997/06/23 16:24:04	1.1.1.5
+++ vnd.c	1997/06/24 03:11:11	1.4
@@ -94,6 +94,10 @@
 #define b_cylin	b_resid
 
 #define	vndunit(x)	DISKUNIT(x)
+#define VNDPART(dev)	DISKPART(dev)
+#define MAKEVNDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
+
+#define VNDLABELDEV(dev) (MAKEVNDDEV(major(dev), vndunit(dev), RAW_PART))
 
 struct vndxfer {
 	struct buf	*vx_bp;		/* Pointer to parent buffer */
@@ -118,6 +122,9 @@
 struct vnd_softc {
 	int		 sc_flags;	/* flags */
 	size_t		 sc_size;	/* size of vnd */
+	int		 sc_bsize;	/* block size for special file */
+	int		 sc_blksize;	/* number of bytes/dector */
+	int		 sc_bshift;	/* shift constant */
 	struct vnode	*sc_vp;		/* vnode */
 	struct ucred	*sc_cred;	/* credentials */
 	int		 sc_maxactive;	/* max # of active requests */
@@ -129,6 +136,8 @@
 /* sc_flags */
 #define	VNF_ALIVE	0x01
 #define VNF_INITED	0x02
+#define VNF_WLABEL	0x04
+#define VNF_LABELLING	0x08
 #define VNF_WANTED	0x40
 #define VNF_LOCKED	0x80
 
@@ -140,10 +149,11 @@
 
 void	vndclear __P((struct vnd_softc *));
 void	vndstart __P((struct vnd_softc *));
-int	vndsetcred __P((struct vnd_softc *, struct ucred *));
+int	vndsetcred __P((struct vnd_softc *, struct ucred *, struct proc *p));
 void	vndthrottle __P((struct vnd_softc *, struct vnode *));
 void	vndiodone __P((struct buf *));
 void	vndshutdown __P((void));
+void	vndgetdisklabel __P((dev_t dev, struct vnd_softc *vnd));
 
 static	int vndlock __P((struct vnd_softc *));
 static	void vndunlock __P((struct vnd_softc *));
@@ -196,6 +206,15 @@
 	part = DISKPART(dev);
 	pmask = (1 << part);
 
+	/* Check that the partition exists. */
+	if (part != RAW_PART &&
+	    ((sc->sc_flags & VNF_INITED) == 0 ||
+	     part >= sc->sc_dkdev.dk_label->d_npartitions ||
+	     sc->sc_dkdev.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
+		error = ENXIO;
+		goto bad;
+	}
+
 	/* Prevent our unit from being unconfigured while open. */
 	switch (mode) {
 	case S_IFCHR:
@@ -211,6 +230,10 @@
 
 	vndunlock(sc);
 	return (0);
+
+bad:
+	vndunlock(sc);
+	return error;
 }
 
 int
@@ -272,6 +295,7 @@
 	int sz, flags, error;
 
 #ifdef DEBUG
+ 	printf("vndstrategy(%p): bsize %ld\n", bp, vnd->sc_vp->v_mount->mnt_stat.f_iosize);
 	if (vnddebug & VDB_FOLLOW)
 		printf("vndstrategy(%p): unit %d\n", bp, unit);
 #endif
@@ -281,9 +305,28 @@
 		biodone(bp);
 		return;
 	}
+
+	if (VNDPART(bp->b_dev) != RAW_PART &&
+	    bounds_check_with_label(bp, vnd->sc_dkdev.dk_label,
+	    (vnd->sc_flags & (VNF_WLABEL|VNF_LABELLING)) != 0) <= 0) {
+		bp->b_resid = bp->b_bcount;
+		biodone(bp);
+		return;
+	}
+
+#if 1
 	bn = bp->b_blkno;
-	sz = howmany(bp->b_bcount, DEV_BSIZE);
+#else
+	bn = bp->b_blkno / (vnd->sc_dkdev.dk_label->d_secsize / DEV_BSIZE);
+#endif
 	bp->b_resid = bp->b_bcount;
+	sz = howmany(bp->b_bcount, vnd->sc_blksize);
+
+	if (VNDPART(bp->b_dev) != RAW_PART) {
+		bn += vnd->sc_dkdev.dk_label->d_partitions[VNDPART(bp->b_dev)].p_offset;
+	}
+	bn *= vnd->sc_dkdev.dk_label->d_secsize / vnd->sc_blksize;
+
 	if (bn < 0 || bn + sz > vnd->sc_size) {
 		if (bn != vnd->sc_size) {
 			bp->b_error = EINVAL;
@@ -292,8 +335,13 @@
 		biodone(bp);
 		return;
 	}
-	bn = dbtob(bn);
+
+	bn = bn << vnd->sc_bshift;
+#if 1
+	bsize = vnd->sc_bsize;
+#else
  	bsize = vnd->sc_vp->v_mount->mnt_stat.f_iosize;
+#endif
 	addr = bp->b_data;
 	flags = bp->b_flags | B_CALL;
 
@@ -512,6 +560,7 @@
 {
 	int unit = vndunit(dev);
 	struct vnd_softc *sc;
+	int bshift;
 
 #ifdef DEBUG
 	if (vnddebug & VDB_FOLLOW)
@@ -524,8 +573,9 @@
 
 	if ((sc->sc_flags & VNF_INITED) == 0)
 		return (ENXIO);
+	bshift = ffs(sc->sc_dkdev.dk_label->d_secsize)-1;
 
-	return (physio(vndstrategy, NULL, dev, B_READ, minphys, uio));
+	return (physio2(vndstrategy, NULL, dev, B_READ, minphys, uio, bshift));
 }
 
 /* ARGSUSED */
@@ -537,6 +587,7 @@
 {
 	int unit = vndunit(dev);
 	struct vnd_softc *sc;
+	int bshift;
 
 #ifdef DEBUG
 	if (vnddebug & VDB_FOLLOW)
@@ -549,8 +600,9 @@
 
 	if ((sc->sc_flags & VNF_INITED) == 0)
 		return (ENXIO);
+	bshift = ffs(sc->sc_dkdev.dk_label->d_secsize)-1;
 
-	return (physio(vndstrategy, NULL, dev, B_WRITE, minphys, uio));
+	return (physio2(vndstrategy, NULL, dev, B_WRITE, minphys, uio, bshift));
 }
 
 /* ARGSUSED */
@@ -588,6 +640,10 @@
 		if (vnd->sc_flags & VNF_INITED)
 			return (EBUSY);
 
+		if (vio->vnd_size == 0 || vio->vnd_size % DEV_BSIZE != 0 ||
+		    vio->vnd_size > BLKDEV_IOSIZE)
+			vio->vnd_size = DEV_BSIZE;
+
 		if ((error = vndlock(vnd)) != 0)
 			return (error);
 
@@ -602,23 +658,55 @@
 			vndunlock(vnd);
 			return(error);
 		}
-		error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p);
+		if (nd.ni_vp->v_type == VBLK || nd.ni_vp->v_type == VCHR) {
+			struct partinfo dpart;
+
+			dpart.disklab = NULL;
+			dpart.part = NULL;
+			error = VOP_IOCTL(nd.ni_vp, DIOCGPART, (caddr_t)&dpart,
+			    FREAD, NOCRED, p);
+			if (error == 0) {
+				if (dpart.disklab != NULL && dpart.disklab->d_secsize != 0)
+					vattr.va_blocksize = dpart.disklab->d_secsize;
+				else
+					vattr.va_blocksize = DEV_BSIZE;
+				if (dpart.part == NULL)
+					vattr.va_size = 0;
+				else {
+					vattr.va_size = dpart.part->p_size *
+					    dpart.disklab->d_secsize;
+				}
+			}
+		} else {
+			error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p);
+		}
 		if (error) {
 			VOP_UNLOCK(nd.ni_vp);
 			(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
 			vndunlock(vnd);
 			return(error);
 		}
+			
 		VOP_UNLOCK(nd.ni_vp);
 		vnd->sc_vp = nd.ni_vp;
-		vnd->sc_size = btodb(vattr.va_size);	/* note truncation */
-		if ((error = vndsetcred(vnd, p->p_ucred)) != 0) {
+		vnd->sc_blksize = vio->vnd_size;
+		vnd->sc_bshift = ffs(vnd->sc_blksize) - 1;
+		vnd->sc_size = vattr.va_size >> vnd->sc_bshift;	/* note truncation */
+		if (nd.ni_vp->v_type != VBLK && nd.ni_vp->v_type != VCHR) {
+			vnd->sc_bsize = nd.ni_vp->v_mount->mnt_stat.f_iosize;
+		} else {
+			if (vattr.va_blocksize != 0)
+				vnd->sc_bsize = vattr.va_blocksize;
+			else
+				vnd->sc_bsize = DEV_BSIZE;
+		}
+		if ((error = vndsetcred(vnd, p->p_ucred, p)) != 0) {
 			(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
 			vndunlock(vnd);
 			return(error);
 		}
 		vndthrottle(vnd, vnd->sc_vp);
-		vio->vnd_size = dbtob(vnd->sc_size);
+		vio->vnd_size = vnd->sc_size << vnd->sc_bshift;
 		vnd->sc_flags |= VNF_INITED;
 #ifdef DEBUG
 		if (vnddebug & VDB_INIT)
@@ -632,6 +720,8 @@
 		vnd->sc_dkdev.dk_name = vnd->sc_xname;
 		disk_attach(&vnd->sc_dkdev);
 
+		vndgetdisklabel(dev, vnd);
+
 		vndunlock(vnd);
 
 		break;
@@ -673,6 +763,60 @@
 	/*
 	 * XXX Should support disklabels.
 	 */
+	case DIOCGDINFO:
+		if ((vnd->sc_flags & VNF_INITED) == 0)
+			return (ENXIO);
+
+		*(struct disklabel *)data = *(vnd->sc_dkdev.dk_label);
+		return 0;
+
+	case DIOCGPART:
+		if ((vnd->sc_flags & VNF_INITED) == 0)
+			return (ENXIO);
+
+		((struct partinfo *)data)->disklab = vnd->sc_dkdev.dk_label;
+		((struct partinfo *)data)->part =
+		    &vnd->sc_dkdev.dk_label->d_partitions[VNDPART(dev)];
+		return 0;
+
+
+	case DIOCWDINFO:
+	case DIOCSDINFO:
+		if ((vnd->sc_flags & VNF_INITED) == 0)
+			return (ENXIO);
+
+		if ((flag & FWRITE) == 0)
+			return EBADF;
+
+		if ((error = vndlock(vnd)) != 0)
+			return error;
+		vnd->sc_flags |= VNF_LABELLING;
+
+		error = setdisklabel(vnd->sc_dkdev.dk_label,
+		    (struct disklabel *)data, /*vnd->sc_dkdev.dk_openmask : */0,
+		    vnd->sc_dkdev.dk_cpulabel);
+		if (error == 0) {
+			if (cmd == DIOCWDINFO)
+				error = writedisklabel(VNDLABELDEV(dev),
+				    vndstrategy, vnd->sc_dkdev.dk_label,
+				    vnd->sc_dkdev.dk_cpulabel);
+		}
+
+		vnd->sc_flags &= ~VNF_LABELLING;
+		vndunlock(vnd);
+		return error;
+
+	case DIOCWLABEL:
+		if ((vnd->sc_flags & VNF_INITED) == 0)
+			return (ENXIO);
+
+		if ((flag & FWRITE) == 0)
+			return EBADF;
+		if (*(int *)data)
+			vnd->sc_flags |= VNF_WLABEL;
+		else
+			vnd->sc_flags &= ~VNF_WLABEL;
+		return 0;
 
 	default:
 		return(ENOTTY);
@@ -682,15 +826,69 @@
 }
 
 /*
+ * Load the label information on the named device
+ */
+void
+vndgetdisklabel(dev, vnd)
+	dev_t dev;
+	struct vnd_softc *vnd;
+{
+	struct disklabel *lp = vnd->sc_dkdev.dk_label;
+	char *errstring;
+
+	bzero(lp, sizeof(struct disklabel));
+	bzero(vnd->sc_dkdev.dk_cpulabel, sizeof(struct cpu_disklabel));
+
+	lp->d_secsize = vnd->sc_blksize;
+	lp->d_ntracks = 64;
+	lp->d_nsectors = 32;
+	lp->d_ncylinders = vnd->sc_size / (64 * 32);
+	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
+	if (lp->d_secpercyl == 0) {
+		lp->d_secpercyl = 100;
+		/* as long as it's not 0 - readdisklabel divides by it (?) */
+	}
+
+	strncpy(lp->d_typename, "vnode disk", 16);
+	lp->d_type = DTYPE_VND;
+	strncpy(lp->d_packname, "fictitious", 16);
+	lp->d_secperunit = vnd->sc_size;
+	lp->d_rpm = 3600;
+	lp->d_interleave = 1;
+	lp->d_flags = 0;
+
+	lp->d_partitions[RAW_PART].p_offset = 0;
+	lp->d_partitions[RAW_PART].p_size =
+	    lp->d_secperunit;
+	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+	lp->d_npartitions = RAW_PART + 1;
+
+	lp->d_magic = DISKMAGIC;
+	lp->d_magic2 = DISKMAGIC;
+	lp->d_checksum = dkcksum(lp);
+
+	/*
+	 * Call the generic disklabel extraction routine
+	 */
+	errstring = readdisklabel(dev,
+				  vndstrategy, lp, vnd->sc_dkdev.dk_cpulabel);
+	if (errstring) {
+		printf("%s: %s\n", vnd->sc_xname, errstring);
+		return;
+	}
+}
+
+/*
  * Duplicate the current processes' credentials.  Since we are called only
  * as the result of a SET ioctl and only root can do that, any future access
  * to this "disk" is essentially as root.  Note that credentials may change
  * if some other uid can write directly to the mapped file (NFS).
  */
 int
-vndsetcred(vnd, cred)
+vndsetcred(vnd, cred, p)
 	register struct vnd_softc *vnd;
 	struct ucred *cred;
+	struct proc *p;
 {
 	struct uio auio;
 	struct iovec aiov;
@@ -709,6 +907,7 @@
 	auio.uio_rw = UIO_READ;
 	auio.uio_segflg = UIO_SYSSPACE;
 	auio.uio_resid = aiov.iov_len;
+	auio.uio_procp = p;
 	VOP_LOCK(vnd->sc_vp);
 	error = VOP_READ(vnd->sc_vp, &auio, 0, vnd->sc_cred);
 	VOP_UNLOCK(vnd->sc_vp);
Index: sys/isofs/cd9660/cd9660_bmap.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/isofs/cd9660/cd9660_bmap.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- cd9660_bmap.c	1997/04/01 07:13:06	1.1.1.2
+++ cd9660_bmap.c	1997/05/29 17:50:53	1.2
@@ -84,7 +84,11 @@
 	 * Compute the requested block number
 	 */
 	bshift = ip->i_mnt->im_bshift;
+#if 1
+	*ap->a_bnp = (ip->iso_start + lblkno) << ip->i_mnt->im_sshift;
+#else
 	*ap->a_bnp = (ip->iso_start + lblkno) << (bshift - DEV_BSHIFT);
+#endif
 
 	/*
 	 * Determine maximum number of readahead blocks following the
Index: sys/isofs/cd9660/cd9660_extern.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/isofs/cd9660/cd9660_extern.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- cd9660_extern.h	1997/04/01 07:13:14	1.1.1.1
+++ cd9660_extern.h	1997/05/29 17:50:55	1.2
@@ -61,7 +61,12 @@
 	int logical_block_size;
 	int im_bshift;
 	int im_bmask;
-	
+
+#if 1
+	int system_block_size;
+	int im_sshift;
+#endif	
+
 	int volume_space_size;
 	struct netexport im_export;
 	
Index: sys/isofs/cd9660/cd9660_rrip.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/isofs/cd9660/cd9660_rrip.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- cd9660_rrip.c	1997/04/01 07:13:10	1.1.1.2
+++ cd9660_rrip.c	1997/05/29 17:50:56	1.2
@@ -574,7 +574,11 @@
 			if (ana->iso_ce_blk >= ana->imp->volume_space_size
 			    || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
 			    || bread(ana->imp->im_devvp,
+#if 1
+				     ana->iso_ce_blk << ana->imp->im_sshift,
+#else
 				     ana->iso_ce_blk << (ana->imp->im_bshift - DEV_BSHIFT),
+#endif
 				     ana->imp->logical_block_size, NOCRED, &bp))
 				/* what to do now? */
 				break;
Index: sys/isofs/cd9660/cd9660_vfsops.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/isofs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.1.1.3
retrieving revision 1.3
diff -u -r1.1.1.3 -r1.3
--- cd9660_vfsops.c	1997/06/23 16:26:16	1.1.1.3
+++ cd9660_vfsops.c	1997/06/24 03:11:32	1.3
@@ -233,6 +233,13 @@
 	struct iso_primary_descriptor *pri;
 	struct iso_directory_record *rootp;
 	int logical_block_size;
+#if 1
+	struct partinfo dpart;
+	int bsize, sshift;
+	struct ucred *cred;
+
+	cred = p ? p->p_ucred : NOCRED;
+#endif
 	
 	if (!ronly)
 		return EROFS;
@@ -260,10 +267,23 @@
 	 * whichever is greater.  For now, we'll just use a constant.
 	 */
 	iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
+#if 1
+	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
+		bsize = DEV_BSIZE;
+	else
+		bsize = dpart.disklab->d_secsize;
+
+	sshift = ffs(iso_bsize) - ffs(bsize);
+#endif
 	
 	for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
+#if 1
+		if ((error = bread(devvp, iso_blknum << sshift,
+				   iso_bsize, NOCRED, &bp)) != 0)
+#else
 		if ((error = bread(devvp, iso_blknum * btodb(iso_bsize),
 				   iso_bsize, NOCRED, &bp)) != 0)
+#endif
 			goto out;
 		
 		vdp = (struct iso_volume_descriptor *)bp->b_data;
@@ -312,6 +332,10 @@
 	while ((1 << isomp->im_bshift) < isomp->logical_block_size)
 		isomp->im_bshift++;
 	
+#if 1
+	isomp->system_block_size = bsize;
+	isomp->im_sshift = sshift;
+#endif
 	bp->b_flags |= B_AGE;
 	brelse(bp);
 	bp = NULL;
@@ -331,7 +355,11 @@
 	if (!(argp->flags & ISOFSMNT_NORRIP)) {
 		if ((error = bread(isomp->im_devvp,
 				   (isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
+#if 1
+				   isomp->im_sshift,
+#else
 				   (isomp->im_bshift - DEV_BSHIFT),
+#endif
 				   isomp->logical_block_size, NOCRED,
 				   &bp)) != 0)
 		    goto out;
Index: sys/kern/kern_physio.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/kern/kern_physio.c,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -u -r1.1.1.3 -r1.2
--- kern_physio.c	1997/05/23 21:58:02	1.1.1.3
+++ kern_physio.c	1997/05/29 17:50:47	1.2
@@ -78,6 +78,19 @@
 	void (*minphys) __P((struct buf *));
 	struct uio *uio;
 {
+	return physio2(strategy, bp, dev, flags, minphys, uio, DEV_BSHIFT);
+}
+
+int
+physio2(strategy, bp, dev, flags, minphys, uio, bshift)
+	void (*strategy) __P((struct buf *));
+	struct buf *bp;
+	dev_t dev;
+	int flags;
+	void (*minphys) __P((struct buf *));
+	struct uio *uio;
+	int bshift;
+{
 	struct iovec *iovp;
 	struct proc *p = curproc;
 	int error, done, i, nobuf, s, todo;
@@ -143,7 +156,12 @@
 			bp->b_flags = B_BUSY | B_PHYS | B_RAW | flags;
 
 			/* [set up the buffer for a maximum-sized transfer] */
+#if 1
+			bp->b_blkno = uio->uio_offset >> bshift;
+#else
 			bp->b_blkno = btodb(uio->uio_offset);
+#endif
+
 			bp->b_bcount = iovp->iov_len;
 			bp->b_data = iovp->iov_base;
 
Index: sys/scsi/cd.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/scsi/cd.c,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -u -r1.1.1.3 -r1.2
--- cd.c	1997/04/11 07:23:35	1.1.1.3
+++ cd.c	1997/05/29 17:50:50	1.2
@@ -549,13 +549,18 @@
 		 * First, translate the block to absolute and put it in terms
 		 * of the logical blocksize of the device.
 		 */
+#if 1
+		blkno = bp->b_blkno;
+#else
 		blkno =
 		    bp->b_blkno / (cd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+#endif
 		if (CDPART(bp->b_dev) != RAW_PART) {
 		      p = &cd->sc_dk.dk_label->d_partitions[CDPART(bp->b_dev)];
 		      blkno += p->p_offset;
 		}
-		nblks = howmany(bp->b_bcount, cd->sc_dk.dk_label->d_secsize);
+		blkno *= cd->sc_dk.dk_label->d_secsize / cd->params.blksize;
+		nblks = howmany(bp->b_bcount, cd->params.blksize);
 
 		/*
 		 *  Fill out the scsi command.  If the transfer will
@@ -647,8 +652,10 @@
 	struct uio *uio;
 	int ioflag;
 {
+	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
+	int bshift = ffs(cd->sc_dk.dk_label->d_secsize)-1;
 
-	return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio));
+	return (physio2(cdstrategy, NULL, dev, B_READ, cdminphys, uio, bshift));
 }
 
 int
@@ -657,8 +664,10 @@
 	struct uio *uio;
 	int ioflag;
 {
+	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
+	int bshift = ffs(cd->sc_dk.dk_label->d_secsize)-1;
 
-	return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio));
+	return (physio2(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio, bshift));
 }
 
 /*
@@ -942,6 +951,7 @@
 	struct cd_softc *cd;
 {
 	struct disklabel *lp = cd->sc_dk.dk_label;
+	char *errstring;
 
 	bzero(lp, sizeof(struct disklabel));
 	bzero(cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
@@ -962,17 +972,46 @@
 
 	lp->d_partitions[0].p_offset = 0;
 	lp->d_partitions[0].p_size =
-	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
+	    lp->d_secperunit;
 	lp->d_partitions[0].p_fstype = FS_ISO9660;
 	lp->d_partitions[RAW_PART].p_offset = 0;
 	lp->d_partitions[RAW_PART].p_size =
-	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
+	    lp->d_secperunit;
 	lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
 	lp->d_npartitions = RAW_PART + 1;
 
 	lp->d_magic = DISKMAGIC;
 	lp->d_magic2 = DISKMAGIC;
 	lp->d_checksum = dkcksum(lp);
+
+	/*
+	 * Call the generic disklabel extraction routine
+	 */
+	errstring = readdisklabel(MAKECDDEV(0, cd->sc_dev.dv_unit, RAW_PART),
+				  cdstrategy, lp, cd->sc_dk.dk_cpulabel);
+
+#if 0
+	if (errstring) {
+		printf("%s: %s\n", cd->sc_dev.dv_xname, errstring);
+		return;
+	}
+#else
+	if (errstring && strcmp(errstring, "no disk label") == 0) {
+		lp->d_partitions[0].p_offset = 0;
+		lp->d_partitions[0].p_size =
+			lp->d_secperunit;
+		lp->d_partitions[0].p_fstype = FS_ISO9660;
+		lp->d_partitions[RAW_PART].p_offset = 0;
+		lp->d_partitions[RAW_PART].p_size =
+			lp->d_secperunit;
+		lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
+		lp->d_npartitions = RAW_PART + 1;
+
+		lp->d_magic = DISKMAGIC;
+		lp->d_magic2 = DISKMAGIC;
+		lp->d_checksum = dkcksum(lp);
+	}
+#endif
 }
 
 /*
Index: sys/scsi/sd.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/scsi/sd.c,v
retrieving revision 1.1.1.4
retrieving revision 1.3
diff -u -r1.1.1.4 -r1.3
--- sd.c	1997/06/23 16:30:19	1.1.1.4
+++ sd.c	1997/06/24 03:11:50	1.3
@@ -577,13 +577,13 @@
 		 * First, translate the block to absolute and put it in terms
 		 * of the logical blocksize of the device.
 		 */
-		blkno =
-		    bp->b_blkno / (sd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+		blkno = bp->b_blkno;
 		if (SDPART(bp->b_dev) != RAW_PART) {
 		     p = &sd->sc_dk.dk_label->d_partitions[SDPART(bp->b_dev)];
 		     blkno += p->p_offset;
 		}
-		nblks = howmany(bp->b_bcount, sd->sc_dk.dk_label->d_secsize);
+		blkno *= sd->sc_dk.dk_label->d_secsize / sd->params.blksize;
+		nblks = howmany(bp->b_bcount, sd->params.blksize);
 
 		/*
 		 *  Fill out the scsi command.  If the transfer will
@@ -675,8 +675,10 @@
 	struct uio *uio;
 	int ioflag;
 {
+	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)];
+	int bshift = ffs(sd->sc_dk.dk_label->d_secsize)-1;
 
-	return (physio(sdstrategy, NULL, dev, B_READ, sdminphys, uio));
+	return (physio2(sdstrategy, NULL, dev, B_READ, sdminphys, uio, bshift));
 }
 
 int
@@ -685,8 +687,10 @@
 	struct uio *uio;
 	int ioflag;
 {
+	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)];
+	int bshift = ffs(sd->sc_dk.dk_label->d_secsize)-1;
 
-	return (physio(sdstrategy, NULL, dev, B_WRITE, sdminphys, uio));
+	return (physio2(sdstrategy, NULL, dev, B_WRITE, sdminphys, uio, bshift));
 }
 
 /*
@@ -810,7 +814,7 @@
 
 	lp->d_partitions[RAW_PART].p_offset = 0;
 	lp->d_partitions[RAW_PART].p_size =
-	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
+	    lp->d_secperunit;
 	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
 	lp->d_npartitions = RAW_PART + 1;
 
Index: sys/sys/buf.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/sys/buf.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- buf.h	1997/04/14 06:25:49	1.1.1.2
+++ buf.h	1997/05/29 17:50:51	1.2
@@ -187,6 +187,8 @@
 void	minphys __P((struct buf *bp));
 int	physio __P((void (*strategy)(struct buf *), struct buf *bp, dev_t dev,
 		    int flags, void (*minphys)(struct buf *), struct uio *uio));
+int	physio2 __P((void (*strategy)(struct buf *), struct buf *bp, dev_t dev,
+		    int flags, void (*minphys)(struct buf *), struct uio *uio, int bshift));
 void  brelvp __P((struct buf *));
 void  reassignbuf __P((struct buf *, struct vnode *));
 void  bgetvp __P((struct vnode *, struct buf *));
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.1.1.3
retrieving revision 1.4
diff -u -r1.1.1.3 -r1.4
--- ffs_vfsops.c	1997/06/23 16:31:06	1.1.1.3
+++ ffs_vfsops.c	1997/06/24 03:12:02	1.4
@@ -307,7 +307,9 @@
 	struct csum *space;
 	struct buf *bp;
 	struct fs *fs, *newfs;
+#if 1
 	struct partinfo dpart;
+#endif
 	int i, blks, size, error;
 	int32_t *lp;
 
@@ -322,10 +324,15 @@
 	/*
 	 * Step 2: re-read superblock from disk.
 	 */
+#if 1
 	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
 		size = DEV_BSIZE;
 	else
 		size = dpart.disklab->d_secsize;
+#else
+	size = DEV_BSIZE;
+#endif
+
 	error = bread(devvp, (daddr_t)(SBOFF / size), SBSIZE, NOCRED, &bp);
 	if (error)
 		return (error);
@@ -343,6 +350,7 @@
 	 */
 	bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp));
 	newfs->fs_maxcluster = fs->fs_maxcluster;
+	newfs->fs_fsbtosb = fs->fs_fsbtosb;
 	bcopy(newfs, fs, (u_int)fs->fs_sbsize);
 	if (fs->fs_sbsize < SBSIZE)
 		bp->b_flags |= B_INVAL;
@@ -424,10 +432,12 @@
 	struct buf *bp;
 	register struct fs *fs;
 	dev_t dev;
+#if 1
 	struct partinfo dpart;
+#endif
 	caddr_t base, space;
 	int blks;
-	int error, i, size, ronly;
+	int error, i, size, ssize, ronly;
 	int32_t *lp;
 	struct ucred *cred;
 	extern struct vnode *rootvp;
@@ -452,10 +462,14 @@
 	error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
 	if (error)
 		return (error);
+#if 1
 	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
 		size = DEV_BSIZE;
 	else
 		size = dpart.disklab->d_secsize;
+#else
+	size = DEV_BSIZE;
+#endif
 
 	bp = NULL;
 	ump = NULL;
@@ -473,6 +487,21 @@
 		error = EROFS;		/* XXX what should be returned? */
 		goto out;
 	}
+	/* XXX bread assumes b_blkno in DEV_BSIZE unit. Calculate fsbtosb */
+
+	ssize = fs->fs_fsize / fs->fs_nspf;
+	fs->fs_fsbtosb = fs->fs_fsbtodb;
+	if (ssize >= size) {
+		ssize = ssize / size;
+		for (i = 0; ssize > 1; ssize >>= 1)
+			i ++;
+		fs->fs_fsbtosb += i;
+	} else {
+		ssize = size / ssize;
+		for (i = 0; ssize > 1; ssize >>= 1)
+			i ++;
+		fs->fs_fsbtosb -= i;
+	}
 	ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
 	bzero((caddr_t)ump, sizeof *ump);
 	ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
@@ -523,7 +552,7 @@
 	ump->um_dev = dev;
 	ump->um_devvp = devvp;
 	ump->um_nindir = fs->fs_nindir;
-	ump->um_bptrtodb = fs->fs_fsbtodb;
+	ump->um_bptrtodb = fs->fs_fsbtosb;
 	ump->um_seqinc = fs->fs_frag;
 	for (i = 0; i < MAXQUOTAS; i++)
 		ump->um_quotas[i] = NULLVP;
@@ -921,11 +950,12 @@
 	register struct buf *bp;
 	int i, error = 0;
 
-	bp = getblk(mp->um_devvp, SBOFF >> (fs->fs_fshift - fs->fs_fsbtodb),
+	bp = getblk(mp->um_devvp, SBOFF >> (fs->fs_fshift - fs->fs_fsbtosb),
 	    (int)fs->fs_sbsize, 0, 0);
 	bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
 	/* Restore compatibility to old file systems.		   XXX */
 	dfs = (struct fs *)bp->b_data;				/* XXX */
+	dfs->fs_fsbtosb = 0;					/* XXX */
 	if (fs->fs_postblformat == FS_42POSTBLFMT)		/* XXX */
 		dfs->fs_nrpos = -1;				/* XXX */
 	if (fs->fs_inodefmt < FS_44INODEFMT) {			/* XXX */
Index: sys/ufs/ffs/fs.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/ufs/ffs/fs.h,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -r1.1.1.2 -r1.3
--- fs.h	1997/06/23 16:31:07	1.1.1.2
+++ fs.h	1997/06/24 03:12:03	1.3
@@ -228,7 +228,8 @@
 	int32_t	 *fs_maxcluster;	/* max cluster in each cyl group */
 	int32_t	 fs_cpc;		/* cyl per cycle in postbl */
 	int16_t	 fs_opostbl[16][8];	/* old rotation block list head */
-	int32_t	 fs_sparecon[49];	/* reserved for future constants */
+	int32_t  fs_fsbtosb;		/* fsbtodb and dbtofsb shift constant */
+	int32_t	 fs_sparecon[48];	/* reserved for future constants */
 	time_t	 fs_fscktime;		/* last time fsck(8)ed */
 	int32_t	 fs_contigsumsize;	/* size of cluster summary array */ 
 	int32_t	 fs_maxsymlinklen;	/* max length of an internal symlink */
@@ -394,8 +395,8 @@
  * Turn file system block numbers into disk block addresses.
  * This maps file system blocks to device size blocks.
  */
-#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
-#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
+#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtosb)
+#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtosb)
 
 /*
  * Cylinder group macros to locate things in cylinder groups.
>Audit-Trail:
>Unformatted: