Module Name:    src
Committed By:   mlelstv
Date:           Sat Nov 28 14:45:24 UTC 2015

Modified Files:
        src/sys/dev: cgd.c

Log Message:
Inherit sector size from underlying disk to support disks with
sector sizes other than 512 bytes.

The CGD disk image depends on disk geometry as it encodes the block
number into each block. You cannot copy an image between disks
with different sector sizes.


To generate a diff of this commit:
cvs rdiff -u -r1.104 -r1.105 src/sys/dev/cgd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/cgd.c
diff -u src/sys/dev/cgd.c:1.104 src/sys/dev/cgd.c:1.105
--- src/sys/dev/cgd.c:1.104	Thu Aug 27 05:51:50 2015
+++ src/sys/dev/cgd.c	Sat Nov 28 14:45:24 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd.c,v 1.104 2015/08/27 05:51:50 mlelstv Exp $ */
+/* $NetBSD: cgd.c,v 1.105 2015/11/28 14:45:24 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.104 2015/08/27 05:51:50 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.105 2015/11/28 14:45:24 mlelstv Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -304,6 +304,8 @@ static void
 cgdstrategy(struct buf *bp)
 {
 	struct	cgd_softc *cs = getcgd_softc(bp->b_dev);
+	struct	dk_softc *dksc = &cs->sc_dksc;
+	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
 
 	DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
 	    (long)bp->b_bcount));
@@ -314,7 +316,7 @@ cgdstrategy(struct buf *bp)
 	 * buffers to be aligned to 32-bit boundaries.
 	 */
 	if (bp->b_blkno < 0 ||
-	    (bp->b_bcount % DEV_BSIZE) != 0 ||
+	    (bp->b_bcount % dg->dg_secsize) != 0 ||
 	    ((uintptr_t)bp->b_data & 3) != 0) {
 		bp->b_error = EINVAL;
 		bp->b_resid = bp->b_bcount;
@@ -384,6 +386,7 @@ cgd_diskstart(device_t dev, struct buf *
 {
 	struct	cgd_softc *cs = device_private(dev);
 	struct	dk_softc *dksc = &cs->sc_dksc;
+	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
 	struct	buf *nbp;
 	void *	addr;
 	void *	newaddr;
@@ -414,7 +417,7 @@ cgd_diskstart(device_t dev, struct buf *
 			return EAGAIN;
 		}
 		cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn,
-		    DEV_BSIZE, CGD_CIPHER_ENCRYPT);
+		    dg->dg_secsize, CGD_CIPHER_ENCRYPT);
 	}
 
 	nbp->b_data = newaddr;
@@ -423,7 +426,7 @@ cgd_diskstart(device_t dev, struct buf *
 	nbp->b_cflags = bp->b_cflags;
 	nbp->b_iodone = cgdiodone;
 	nbp->b_proc = bp->b_proc;
-	nbp->b_blkno = bn;
+	nbp->b_blkno = btodb(bn * dg->dg_secsize);
 	nbp->b_bcount = bp->b_bcount;
 	nbp->b_private = bp;
 
@@ -446,6 +449,8 @@ cgdiodone(struct buf *nbp)
 	struct	buf *obp = nbp->b_private;
 	struct	cgd_softc *cs = getcgd_softc(obp->b_dev);
 	struct	dk_softc *dksc = &cs->sc_dksc;
+	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
+	daddr_t	bn;
 
 	KDASSERT(cs);
 
@@ -467,9 +472,11 @@ cgdiodone(struct buf *nbp)
 	 *       we used to encrypt the blocks.
 	 */
 
-	if (nbp->b_flags & B_READ)
+	if (nbp->b_flags & B_READ) {
+		bn = dbtob(nbp->b_blkno) / dg->dg_secsize;
 		cgd_cipher(cs, obp->b_data, obp->b_data, obp->b_bcount,
-		    nbp->b_blkno, DEV_BSIZE, CGD_CIPHER_DECRYPT);
+		    bn, dg->dg_secsize, CGD_CIPHER_DECRYPT);
+	}
 
 	/* If we allocated memory, free it now... */
 	if (nbp->b_data != obp->b_data)
@@ -824,10 +831,9 @@ cgdinit(struct cgd_softc *cs, const char
 	dg = &dksc->sc_dkdev.dk_geom;
 	memset(dg, 0, sizeof(*dg));
 	dg->dg_secperunit = psize;
-	// XXX: Inherit?
-	dg->dg_secsize = DEV_BSIZE;
+	dg->dg_secsize = secsize;
 	dg->dg_ntracks = 1;
-	dg->dg_nsectors = 1024 * (1024 / dg->dg_secsize);
+	dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
 	dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
 
 bail:
@@ -899,6 +905,7 @@ cgd_cipher(struct cgd_softc *cs, void *d
 	struct iovec	dstiov[2];
 	struct iovec	srciov[2];
 	size_t		blocksize = cs->sc_cdata.cf_blocksize;
+	size_t		todo;
 	char		sink[CGD_MAXBLOCKSIZE];
 	char		zero_iv[CGD_MAXBLOCKSIZE];
 	char		blkno_buf[CGD_MAXBLOCKSIZE];
@@ -924,12 +931,14 @@ cgd_cipher(struct cgd_softc *cs, void *d
 	dstiov[0].iov_len  = blocksize;
 	srciov[0].iov_base = blkno_buf;
 	srciov[0].iov_len  = blocksize;
-	dstiov[1].iov_len  = secsize;
-	srciov[1].iov_len  = secsize;
 
-	for (; len > 0; len -= secsize) {
+	for (; len > 0; len -= todo) {
+		todo = MIN(len, secsize);
+
 		dstiov[1].iov_base = dst;
 		srciov[1].iov_base = src;
+		dstiov[1].iov_len  = todo;
+		srciov[1].iov_len  = todo;
 
 		memset(blkno_buf, 0x0, blocksize);
 		blkno2blkno_buf(blkno_buf, blkno);
@@ -951,8 +960,8 @@ cgd_cipher(struct cgd_softc *cs, void *d
 		IFDEBUG(CGDB_CRYPTO, hexprint("step 2: sink",
 		    sink, blocksize));
 
-		dst += secsize;
-		src += secsize;
+		dst += todo;
+		src += todo;
 		blkno++;
 	}
 }

Reply via email to