Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Nov 96 18:50:42 JST
From:      akiyama@kme.mei.co.jp (Shunsuke Akiyama)
To:        joerg_wunsch@uriah.heep.sax.de
Cc:        freebsd-scsi@freebsd.org, peter@taronga.com
Subject:   Re: Drive with 1024 byte logical blocks
Message-ID:  <9611220950.AA29143@kmegate.kme.mei.co.jp>
In-Reply-To: <199611190812.JAA06727@uriah.heep.sax.de> (message from J Wunsch on Tue, 19 Nov 1996 09:12:52 %2B0100 (MET))

next in thread | previous in thread | raw e-mail | index | archive | help
J Wunsch <j@uriah.heep.sax.de> writes:

> Our UFS is not yet up to the task.  I've seen references to 1024-byte
> sectoring inside #ifdef PC98 though i'm afraid that they've simply
> special-cased this one as opposed to walking through every function
> and removing the implicit assumption that all the world's a DEV_BSIZE
> world.

> MO drives (which are hard-sectored) also suffer from this.

Try this attached patch.  This is for 2.2-ALPHA.
I've tested this with 512/1024/2048 byte/sector MO media, but not
tested with "sd".
-- 
Shunsuke Akiyama
Kyushu Matsushita Electric Co., Ltd. Fukuoka, Japan.
akiyama@kme.mei.co.jp

===================================================================
RCS file: sys/scsi/RCS/sd.c,v
retrieving revision 1.95
retrieving revision 1.95.1.1
diff -u -r1.95 -r1.95.1.1
--- sys/scsi/sd.c	1996/09/14 04:31:09	1.95
+++ sys/scsi/sd.c	1996/11/20 13:03:26	1.95.1.1
@@ -315,7 +315,11 @@
 	 * Load the physical device parameters
 	 */
 	sd_get_parms(unit, 0);	/* sets SDEV_MEDIA_LOADED */
-	if (sd->params.secsiz != SECSIZE) {	/* XXX One day... */
+	switch (sd->params.secsiz) {
+	case SECSIZE:
+	case 1024:
+		break;
+	default:
 		printf("sd%ld: Can't deal with %d bytes logical blocks\n",
 		    unit, sd->params.secsiz);
 		Debugger("sd");
@@ -494,6 +498,7 @@
 	struct buf *bp = NULL;
 	struct scsi_rw_big cmd;
 	u_int32_t blkno, nblk;
+	u_int32_t secsize;
 
 	SC_DEBUG(sc_link, SDEV_DB2, ("sdstart "));
 	/*
@@ -530,12 +535,13 @@
 		 * We have a buf, now we know we are going to go through
 		 * With this thing..
 		 */
-		blkno = bp->b_pblkno;
-		if (bp->b_bcount & (SECSIZE - 1))
+		secsize = sd->params.secsiz;
+		blkno = bp->b_pblkno / (secsize / DEV_BSIZE);
+		if (bp->b_bcount & (secsize - 1))
 		{
 		    goto bad;
 		}
-		nblk = bp->b_bcount >> 9;
+		nblk = (bp->b_bcount + (secsize - 1)) / secsize;
 
 		/*
 		 *  Fill out the scsi command
@@ -632,6 +638,7 @@
 	struct scsi_read_capacity scsi_cmd;
 	u_int32_t size;
 	struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
+	struct scsi_data *sd;
 
 	/*
 	 * make up a scsi command and ask the scsi driver to do
@@ -656,10 +663,9 @@
 		printf("sd%d: could not get size\n", unit);
 		return (0);
 	} else {
-		size = rdcap.addr_0 + 1;
-		size += rdcap.addr_1 << 8;
-		size += rdcap.addr_2 << 16;
-		size += rdcap.addr_3 << 24;
+		size = scsi_4btou(&scsi_cmd.addr_3) + 1;
+		sd = sc_link->sd;
+		sd->params.secsiz = scsi_4btou(&scsi_cmd.length_3);
 	}
 	return (size);
 }
===================================================================
RCS file: sys/kern/RCS/subr_diskslice.c,v
retrieving revision 1.30
retrieving revision 1.30.1.1
diff -u -r1.30 -r1.30.1.1
--- sys/kern/subr_diskslice.c	1996/10/29 13:15:30	1.30
+++ sys/kern/subr_diskslice.c	1996/11/16 13:32:06	1.30.1.1
@@ -119,6 +119,7 @@
 	struct partition *pp;
 	struct diskslice *sp;
 	long	sz;
+	long	scale;
 
 	if (bp->b_blkno < 0) {
 		Debugger("Slice code got negative blocknumber");
@@ -130,15 +131,17 @@
 	lp = sp->ds_label;
 	sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
 	if (lp == NULL) {
+		scale = 1;
 		blkno = bp->b_blkno;
 		labelsect = -LABELSECTOR - 1;
 		maxsz = sp->ds_size;
 	} else {
-		labelsect = lp->d_partitions[LABEL_PART].p_offset;
+		scale = lp->d_secsize / DEV_BSIZE;
+		labelsect = lp->d_partitions[LABEL_PART].p_offset * scale;
 if (labelsect != 0) Debugger("labelsect != 0 in dscheck()");
 		pp = &lp->d_partitions[dkpart(bp->b_dev)];
-		blkno = pp->p_offset + bp->b_blkno;
-		maxsz = pp->p_size;
+		blkno = pp->p_offset * scale + bp->b_blkno;
+		maxsz = pp->p_size * scale;
 		if (sp->ds_bad != NULL && ds_debug) {
 			daddr_t	newblkno;
 
@@ -151,9 +154,9 @@
 
 	/* overwriting disk label ? */
 	/* XXX should also protect bootstrap in first 8K */
-	if (blkno <= LABELSECTOR + labelsect &&
+	if (blkno <= LABELSECTOR * scale + labelsect &&
 #if LABELSECTOR != 0
-	    bp->b_blkno + sz > LABELSECTOR + labelsect &&
+	    bp->b_blkno + sz > LABELSECTOR * scale + labelsect &&
 #endif
 	    (bp->b_flags & B_READ) == 0 && sp->ds_wlabel == 0) {
 		bp->b_error = EROFS;
@@ -186,7 +189,7 @@
 	}
 
 	/* calculate cylinder for disksort to order transfers with */
-	bp->b_pblkno = blkno + sp->ds_offset;
+	bp->b_pblkno = blkno + sp->ds_offset * scale;
 	if (lp == NULL)
 		bp->b_cylinder = 0;	/* XXX always 0 would be better */
 	else
@@ -197,9 +200,9 @@
 	 * offsets in the label to keep the in-core label coherent with
 	 * the on-disk one.
 	 */
-	if (blkno <= LABELSECTOR + labelsect
+	if (blkno <= LABELSECTOR * scale + labelsect
 #if LABELSECTOR != 0
-	    && bp->b_blkno + sz > LABELSECTOR + labelsect
+	    && bp->b_blkno + sz > LABELSECTOR * scale + labelsect
 #endif
 	    && sp->ds_offset != 0) {
 		struct iodone_chain *ic;
@@ -208,8 +211,8 @@
 		ic->ic_prev_flags = bp->b_flags;
 		ic->ic_prev_iodone = bp->b_iodone;
 		ic->ic_prev_iodone_chain = bp->b_iodone_chain;
-		ic->ic_args[0].ia_long = (LABELSECTOR + labelsect - blkno)
-					 << DEV_BSHIFT;
+		ic->ic_args[0].ia_long =
+		  (LABELSECTOR * scale + labelsect - blkno) << DEV_BSHIFT;
 		ic->ic_args[1].ia_ptr = sp;
 		bp->b_flags |= B_CALL;
 		bp->b_iodone = dsiodone;
@@ -798,7 +801,8 @@
 	lp = ssp->dss_slices[slice].ds_label;
 	if (lp == NULL)
 		return (-1);
-	return ((int)lp->d_partitions[part].p_size);
+	return ((int)lp->d_partitions[part].p_size
+		* (lp->d_secsize / DEV_BSIZE));
 }
 
 static void
===================================================================
RCS file: sys/ufs/ffs/RCS/ffs_vfsops.c,v
retrieving revision 1.41
retrieving revision 1.41.1.1
diff -u -r1.41 -r1.41.1.1
--- sys/ufs/ffs/ffs_vfsops.c	1996/09/07 17:34:57	1.41
+++ sys/ufs/ffs/ffs_vfsops.c	1996/10/13 07:52:26	1.41.1.1
@@ -145,7 +145,7 @@
 
 	struct ufs_args args;
 	struct ufsmount *ump = 0;
-	register struct fs *fs;
+	register struct fs *fs = NULL;
 	int flags;
 
 	/*
@@ -327,6 +327,14 @@
 	 */
 	(void)VFS_STATFS(mp, &mp->mnt_stat, p);
 
+	if (fs == NULL) {
+		/* root mount */
+		ump = VFSTOUFS(mp);
+		fs = ump->um_fs;
+	}
+	/* set sector size */
+	mp->mnt_stat.f_spare[0] = fs->fs_fsize / fs->fs_nspf;
+
 	goto success;
 
 
@@ -535,6 +543,8 @@
 		fs->fs_fmod = 1;
 		fs->fs_clean = 0;
 	}
+	for (fs->fs_fsbtodb = 0, i = fs->fs_fsize / DEV_BSIZE; i > 1; i >>= 1)
+		fs->fs_fsbtodb++;
 	blks = howmany(fs->fs_cssize, fs->fs_fsize);
 	base = space = malloc((u_long)fs->fs_cssize, M_UFSMNT,
 	    M_WAITOK);
===================================================================
RCS file: sys/ufs/mfs/RCS/mfs_vfsops.c,v
retrieving revision 1.22
retrieving revision 1.22.1.1
diff -u -r1.22 -r1.22.1.1
--- sys/ufs/mfs/mfs_vfsops.c	1996/06/12 03:37:57	1.22
+++ sys/ufs/mfs/mfs_vfsops.c	1996/08/14 14:59:08	1.22.1.1
@@ -230,7 +230,7 @@
 	struct vnode *devvp;
 	struct mfs_args args;
 	struct ufsmount *ump;
-	register struct fs *fs;
+	register struct fs *fs = NULL;
 	register struct mfsnode *mfsp;
 	u_int size;
 	int flags, err;
@@ -424,6 +424,14 @@
 	 * This code is common to root and non-root mounts
 	 */
 	(void) VFS_STATFS(mp, &mp->mnt_stat, p);
+
+	if (fs == NULL) {
+		/* root mount */
+		ump = VFSTOUFS(mp);
+		fs = ump->um_fs;
+	}
+	/* set sector size */
+	mp->mnt_stat.f_spare[0] = fs->fs_fsize / fs->fs_nspf;
 
 	goto success;
 
===================================================================
RCS file: sys/ufs/ufs/RCS/ufs_disksubr.c,v
retrieving revision 1.26
retrieving revision 1.26.1.1
diff -u -r1.26 -r1.26.1.1
--- sys/ufs/ufs/ufs_disksubr.c	1996/09/20 17:39:44	1.26
+++ sys/ufs/ufs/ufs_disksubr.c	1996/10/13 07:57:53	1.26.1.1
@@ -179,14 +179,16 @@
 	register struct buf *bp;
 	struct disklabel *dlp;
 	char *msg = NULL;
+	int scale;
 
+	scale = lp->d_secsize / DEV_BSIZE;
 	bp = geteblk((int)lp->d_secsize);
 	bp->b_dev = dev;
-	bp->b_blkno = LABELSECTOR;
+	bp->b_blkno = LABELSECTOR * scale;
 	bp->b_bcount = lp->d_secsize;
 	bp->b_flags &= ~B_INVAL;
 	bp->b_flags |= B_BUSY | B_READ;
-	bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
+	bp->b_cylinder = (LABELSECTOR * scale) / lp->d_secpercyl;
 	(*strat)(bp);
 	if (biowait(bp))
 		msg = "I/O error";
@@ -284,7 +286,7 @@
 	}
 	bp = geteblk((int)lp->d_secsize);
 	bp->b_dev = dkmodpart(dev, labelpart);
-	bp->b_blkno = LABELSECTOR;
+	bp->b_blkno = LABELSECTOR * (lp->d_secsize / DEV_BSIZE);
 	bp->b_bcount = lp->d_secsize;
 #if 1
 	/*
===================================================================
RCS file: sys/vm/RCS/vnode_pager.c,v
retrieving revision 1.65
retrieving revision 1.65.1.1
diff -u -r1.65 -r1.65.1.1
--- sys/vm/vnode_pager.c	1996/10/17 02:49:35	1.65
+++ sys/vm/vnode_pager.c	1996/11/16 13:35:01	1.65.1.1
@@ -640,12 +640,17 @@
 	struct buf *bp;
 	int s;
 	int error = 0;
+	int dev_bsize;
 
 	vp = object->handle;
 	if (vp->v_mount == NULL)
 		return VM_PAGER_BAD;
 
 	bsize = vp->v_mount->mnt_stat.f_iosize;
+	dev_bsize = vp->v_mount->mnt_stat.f_spare[0];
+	if (dev_bsize == 0) {
+		dev_bsize = DEV_BSIZE;
+	}
 
 	/* get the UNDERLYING device for the file with VOP_BMAP() */
 
@@ -764,7 +769,7 @@
 	 * round up physical size for real devices
 	 */
 	if (dp->v_type == VBLK || dp->v_type == VCHR)
-		size = (size + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
+		size = (size + dev_bsize - 1) & ~(dev_bsize - 1);
 
 	bp = getpbuf();
 	kva = (vm_offset_t) bp->b_data;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9611220950.AA29143>