-.\" $OpenBSD: mount_vnd.8,v 1.13 2008/05/26 21:14:46 jmc Exp $
+.\" $OpenBSD: mount_vnd.8,v 1.14 2008/08/14 17:10:29 jsing Exp $
.\"
.\" Copyright (c) 1993 University of Utah.
.\" Copyright (c) 1980, 1989, 1991, 1993
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 26 2008 $
+.Dd $Mdocdate: August 14 2008 $
.Dt MOUNT_VND 8
.Os
.Sh NAME
.Op Fl K Ar rounds
.Op Fl o Ar options
.Op Fl S Ar saltfile
+.Op Fl s Ar secsize
.Ar image
.Ar vnd_dev
.Ek
.Op Fl ckluv
.Op Fl K Ar rounds
.Op Fl S Ar saltfile
+.Op Fl s Ar secsize
.Ar vnd_dev
.Ar image
.Ek
.Fl S ,
it defaults to
.Ar image Ns .slt .
+.It Fl s Ar secsize
+Specify the sector size, in bytes, to be used by the device.
+The default sector size is 512 bytes.
+If specified
+.Ar secsize
+must be a multiple of 512 bytes and cannot exceed 65536 bytes.
.It Fl u
.Nm vnconfig
only.
-/* $OpenBSD: mount_vnd.c,v 1.5 2008/06/14 01:47:27 grunk Exp $ */
+/* $OpenBSD: mount_vnd.c,v 1.6 2008/08/14 17:10:29 jsing Exp $ */
/*
* Copyright (c) 1993 University of Utah.
* Copyright (c) 1990, 1993
int run_mount_vnd = 0;
__dead void usage(void);
-int config(char *, char *, int, char *, size_t);
+int config(char *, char *, int, size_t, char *, size_t);
int getinfo(const char *);
char *get_pkcs_key(char *, char *);
{
int ch, rv, action, opt_c, opt_k, opt_K, opt_l, opt_u;
char *key, *mntopts, *rounds, *saltopt;
- size_t keylen = 0;
+ size_t keylen = 0, secsize = 0;
+ const char *errstr;
extern char *__progname;
if (strcasecmp(__progname, "mount_vnd") == 0)
key = mntopts = rounds = saltopt = NULL;
action = VND_CONFIG;
- while ((ch = getopt(argc, argv, "ckK:lo:S:uv")) != -1) {
+ while ((ch = getopt(argc, argv, "ckK:lo:s:S:uv")) != -1) {
switch (ch) {
case 'c':
opt_c = 1;
case 'S':
saltopt = optarg;
break;
+ case 's':
+ secsize = strtonum(optarg, 512, 65536, &errstr);
+ if (errstr || (secsize & 0x1ff) != 0)
+ errx(1, "invalid sector size: %s", optarg);
+ break;
case 'u':
opt_u = 1;
break;
ind_raw = 0;
ind_reg = 1;
}
- rv = config(argv[ind_raw], argv[ind_reg], action, key, keylen);
+ rv = config(argv[ind_raw], argv[ind_reg], action, secsize, key,
+ keylen);
} else if (action == VND_UNCONFIG && argc == 1)
- rv = config(argv[0], NULL, action, NULL, 0);
+ rv = config(argv[0], NULL, action, 0, NULL, 0);
else if (action == VND_GET)
rv = getinfo(argc ? argv[0] : NULL);
else
}
int
-config(char *dev, char *file, int action, char *key, size_t keylen)
+config(char *dev, char *file, int action, size_t secsize, char *key,
+ size_t keylen)
{
struct vnd_ioctl vndio;
FILE *f;
goto out;
}
vndio.vnd_file = file;
+ vndio.vnd_secsize = secsize;
vndio.vnd_key = (u_char *)key;
vndio.vnd_keylen = keylen;
-/* $OpenBSD: vnd.c,v 1.88 2008/07/23 16:24:43 beck Exp $ */
+/* $OpenBSD: vnd.c,v 1.89 2008/08/14 17:10:29 jsing Exp $ */
/* $NetBSD: vnd.c,v 1.26 1996/03/30 23:06:11 christos Exp $ */
/*
char sc_file[VNDNLEN]; /* file we're covering */
int sc_flags; /* flags */
- size_t sc_size; /* size of vnd in blocks */
+ size_t sc_size; /* size of vnd in sectors */
+ size_t sc_secsize; /* sector size in bytes */
struct vnode *sc_vp; /* vnode */
struct ucred *sc_cred; /* credentials */
struct buf sc_tab; /* transfer queue */
bzero(lp, sizeof(struct disklabel));
- lp->d_secsize = DEV_BSIZE;
+ lp->d_secsize = sc->sc_secsize;
lp->d_ntracks = 1;
lp->d_nsectors = 100;
lp->d_ncylinders = sc->sc_size / 100;
return;
}
+ /* Ensure that the requested block is sector aligned. */
+ if (bp->b_blkno % DL_BLKSPERSEC(vnd->sc_dk.dk_label) != 0) {
+ bp->b_error = EINVAL;
+ bp->b_flags |= B_ERROR;
+ s = splbio();
+ biodone(bp);
+ splx(s);
+ return;
+ }
+
bn = bp->b_blkno;
bp->b_resid = bp->b_bcount;
bp->b_resid = bp->b_bcount;
}
- sz = howmany(bp->b_bcount, DEV_BSIZE);
+ if (vnd->sc_flags & VNF_HAVELABEL)
+ sz = howmany(bp->b_bcount, vnd->sc_dk.dk_label->d_secsize);
+ else
+ sz = howmany(bp->b_bcount, DEV_BSIZE);
/* No bypassing of buffer cache? */
if (vndsimple(bp->b_dev)) {
/* Loop until all queued requests are handled. */
for (;;) {
int part = DISKPART(bp->b_dev);
- daddr64_t off = DL_GETPOFFSET(&vnd->sc_dk.dk_label->d_partitions[part]);
-
+ daddr64_t off = DL_SECTOBLK(vnd->sc_dk.dk_label,
+ DL_GETPOFFSET(&vnd->sc_dk.dk_label->d_partitions[part]));
aiov.iov_base = bp->b_data;
auio.uio_resid = aiov.iov_len = bp->b_bcount;
auio.uio_iov = &aiov;
}
/* The old-style buffercache bypassing method. */
- bn += DL_GETPOFFSET(&vnd->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)]);
+ bn += DL_SECTOBLK(vnd->sc_dk.dk_label,
+ DL_GETPOFFSET(&vnd->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)]));
bn = dbtob(bn);
bsize = vnd->sc_vp->v_mount->mnt_stat.f_iosize;
addr = bp->b_data;
{
struct partinfo pi;
struct bdevsw *bsw;
- long sscale;
dev_t dev;
dev = vp->v_rdev;
return (0);
if (bsw->d_ioctl(dev, DIOCGPART, (caddr_t)&pi, FREAD, p))
return (0);
- sscale = pi.disklab->d_secsize / DEV_BSIZE;
- DNPRINTF(VDB_INIT, "vndbdevsize: size %li secsize %li sscale %li\n",
- (long)pi.part->p_size,(long)pi.disklab->d_secsize,sscale);
- return (pi.part->p_size * sscale);
+ DNPRINTF(VDB_INIT, "vndbdevsize: size %li secsize %li\n",
+ (long)pi.part->p_size,(long)pi.disklab->d_secsize);
+ return (pi.part->p_size);
}
/* ARGSUSED */
return(ENXIO);
}
+ /* Set sector size for device, if specified. */
+ if (vio->vnd_secsize == 0)
+ vnd->sc_secsize = DEV_BSIZE;
+ else if (vio->vnd_secsize % DEV_BSIZE == 0)
+ vnd->sc_secsize = vio->vnd_secsize;
+ else
+ return (EINVAL);
+
/*
* Open for read and write first. This lets vn_open() weed out
* directories, sockets, etc. so we don't have to worry about
vndunlock(vnd);
return (error);
}
- vnd->sc_size = btodb(vattr.va_size); /* note truncation */
+ vnd->sc_size = vattr.va_size / vnd->sc_secsize;
}
VOP_UNLOCK(nd.ni_vp, 0, p);
vnd->sc_vp = nd.ni_vp;
} else
vnd->sc_keyctx = NULL;
- vio->vnd_size = dbtob((off_t)vnd->sc_size);
+ vio->vnd_size = vnd->sc_size * vnd->sc_secsize;
vnd->sc_flags |= VNF_INITED;
DNPRINTF(VDB_INIT, "vndioctl: SET vp %p size %llx\n",
/* XXX: Horrible kludge to establish credentials for NFS */
aiov.iov_base = tmpbuf;
- aiov.iov_len = MIN(DEV_BSIZE, dbtob((off_t)vnd->sc_size));
+ aiov.iov_len = MIN(DEV_BSIZE, vnd->sc_size * vnd->sc_secsize);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
if (unit >= numvnd || (vnd->sc_flags & VNF_INITED) == 0)
return (-1);
- return (vnd->sc_size);
+ return (vnd->sc_size * (vnd->sc_secsize / DEV_BSIZE));
}
int