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++;
}
}