I have submitted a patch to DG that fixes VN for CURRENT. Since VN is
currently broken on CURRENT, the patch is on a fast-track for commit.
I've include the patch below, but beware that it may be committed
quickly. This also fixes swap-backed VN. The -S option can be applied
to files now and two new options -T (truncate/create file) and -Z (write
zero's to file to pre-allocate the file blocks) have been added.
Example usage:
vnconfig -e -s labels -T -Z -S 64m /dev/vn0 /usr/obj/test
disklabel -w -r vn0 auto
newfs /dev/rvn0c
mount /dev/vn0c ....some_mount_point....
...
umount ....the_mount_point...
vnconfig -u /dev/vn0
The VN device can also be used with direct-swap backing store by not
specifying a backing file. Note that the sector size is the system
page size (4K on intel).
vnconfig -e -s labels -S 256m /dev/vn0
disklabel -w -r vn0 auto
newfs /dev/rvn0c
mount /dev/vn0c ....some_mount_point....
...
umount ....the_mount_point...
vnconfig -u /dev/vn0
Performance: The VN device operates as a raw disk device. This means
that 'disk I/O' operations are written to the underlying storage whereas
with MFS 'disk I/O' operations are written to memory. VN should be
reasonably efficient memory-wise at the cost of some performance (e.g. the
I/O performed). MFS is less memory efficient (each cached block exists
in main memory twice instead of once) but if you have lots of memory MFS
will not perform any I/O. Note that VN does take advantage of the VM
cache, of course, because the filesystem running on top of it caches
things in the VM cache.
What does this mean? For small filesystems use MFS. For large
filesystems use VN.
Use of file-backed vs swap-backed VN. It's your choice. A swap-backed
VN device has lower I/O overhead but is not persistant and you must be
sure to have sufficient swap to hold the entire size of the VN device
to avoid running the system out of swap if someone fills up the VN
partition. file-backed storage can be made persistant (you can even run
fsck on the file prior to mounting it).
-Matt
Index: sys/vm/vm_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_pager.c,v
retrieving revision 1.51
diff -u -r1.51 vm_pager.c
--- vm_pager.c 1999/07/05 12:50:54 1.51
+++ vm_pager.c 1999/08/25 02:20:02
@@ -566,6 +566,7 @@
nbp->b_bufsize = nbp->b_bcount;
if ((nbp->b_flags & B_READ) == 0)
nbp->b_dirtyend = nbp->b_bcount;
+ BUF_KERNPROC(nbp);
VOP_STRATEGY(nbp->b_vp, nbp);
} else {
biodone(nbp);
Index: sys/vm/swap_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/swap_pager.c,v
retrieving revision 1.124
diff -u -r1.124 swap_pager.c
--- swap_pager.c 1999/08/23 23:55:03 1.124
+++ swap_pager.c 1999/08/25 02:20:42
@@ -857,6 +857,7 @@
if (nbp == NULL) {
nbp = getchainbuf(bp, swapdev_vp,
B_READ|B_ASYNC);
nbp->b_blkno = blk;
+ nbp->b_bcount = 0;
nbp->b_data = data;
}
nbp->b_bcount += PAGE_SIZE;
Index: sys/dev/vn/vn.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/vn/vn.c,v
retrieving revision 1.86
diff -u -r1.86 vn.c
--- vn.c 1999/08/23 20:35:16 1.86
+++ vn.c 1999/08/25 02:21:50
@@ -207,18 +207,23 @@
static int
vnopen(dev_t dev, int flags, int mode, struct proc *p)
{
- int unit;
struct vn_softc *vn;
- unit = dkunit(dev);
- vn = dev->si_drv1;
- if (!vn)
+ /*
+ * Locate preexisting device
+ */
+
+ if ((vn = dev->si_drv1) == NULL)
vn = vnfindvn(dev);
IFOPT(vn, VN_FOLLOW)
printf("vnopen(%s, 0x%x, 0x%x, %p)\n",
devtoname(dev), flags, mode, (void *)p);
+ /*
+ * Initialize label
+ */
+
IFOPT(vn, VN_LABELS) {
if (vn->sc_flags & VNF_INITED) {
struct disklabel label;
@@ -238,8 +243,9 @@
}
if (dkslice(dev) != WHOLE_DISK_SLICE ||
dkpart(dev) != RAW_PART ||
- mode != S_IFCHR)
+ mode != S_IFCHR) {
return (ENXIO);
+ }
}
return(0);
}
@@ -500,7 +506,15 @@
VOP_UNLOCK(nd.ni_vp, 0, p);
vn->sc_secsize = DEV_BSIZE;
vn->sc_vp = nd.ni_vp;
- vn->sc_size = vattr.va_size / vn->sc_secsize; /* note truncation */
+
+ /*
+ * If the size is specified, override the file attributes. Note that
+ * the vn_size argument is in PAGE_SIZE sized blocks.
+ */
+ if (vio->vn_size)
+ vn->sc_size = (quad_t)vio->vn_size * PAGE_SIZE / vn->sc_secsize;
+ else
+ vn->sc_size = vattr.va_size / vn->sc_secsize;
error = vnsetcred(vn, p->p_ucred);
if (error) {
(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
Index: usr.sbin/vnconfig/vnconfig.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/vnconfig/vnconfig.8,v
retrieving revision 1.8
diff -u -r1.8 vnconfig.8
--- vnconfig.8 1999/07/12 20:12:29 1.8
+++ vnconfig.8 1999/08/25 02:52:49
@@ -133,7 +133,18 @@
If no regular file is specified, VN will use swap for backing store.
This option specifies the size of the device. For example, '23m' for
23 megabytes. The VN device will round the size up to a machine page boundry.
-Filesystems up to 7.9 terrabytes are supported.
+Filesystems up to 7.9 terrabytes are supported. When specified along with
+a regular file, this option overrides the regular file's size insofar as
+VN is concerned.
+.It Fl T
+When a regular file is specified, VN will ftruncate() the file to 0 first.
+Normally you should also specify the -S option to set the size of the file.
+This option also creates the file if it did not previously exist.
+This option is only meaningful if the -S option has been specified.
+.It Fl Z
+When a regular file is specified, VN will zero the contents of the file to
+ensure that all blocks have been allocated by the filesystem. This option is
+only meaningful if the -S option has been specified.
.It Fl u
Disable and ``unconfigure'' the device.
.It Fl v
Index: usr.sbin/vnconfig/vnconfig.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/vnconfig/vnconfig.c,v
retrieving revision 1.10
diff -u -r1.10 vnconfig.c
--- vnconfig.c 1999/05/16 08:09:23 1.10
+++ vnconfig.c 1999/08/25 02:51:51
@@ -50,6 +50,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/param.h>
@@ -62,6 +63,7 @@
#define MAXVNDISK 16
#define LINESIZE 1024
+#define ZBUFSIZE 32768
struct vndisk {
char *dev;
@@ -82,6 +84,8 @@
#define VN_IGNORE 0x80
#define VN_SET 0x100
#define VN_RESET 0x200
+#define VN_TRUNCATE 0x400
+#define VN_ZERO 0x800
int nvndisks;
@@ -111,7 +115,7 @@
char *autolabel = NULL;
configfile = _PATH_VNTAB;
- while ((i = getopt(argc, argv, "acdef:gr:s:S:L:uv")) != -1)
+ while ((i = getopt(argc, argv, "acdef:gr:s:S:TZL:uv")) != -1)
switch (i) {
/* all -- use config file */
@@ -176,6 +180,14 @@
size = getsize(optarg);
break;
+ case 'T':
+ flags |= VN_TRUNCATE;
+ break;
+
+ case 'Z':
+ flags |= VN_ZERO;
+ break;
+
case 'L':
autolabel = optarg;
break;
@@ -190,13 +202,13 @@
if (flags == 0)
flags = VN_CONFIG;
- if (all)
+ if (all) {
readconfig(flags);
- else {
+ } else {
if (argc < optind + 1)
usage();
vndisks[0].dev = argv[optind++];
- vndisks[0].file = argv[optind++];
+ vndisks[0].file = argv[optind++]; /* may be NULL */
vndisks[0].flags = flags;
vndisks[0].size = size;
vndisks[0].autolabel = autolabel;
@@ -235,6 +247,7 @@
char *rdev;
FILE *f;
u_long l;
+ int pgsize = getpagesize();
dev = vnp->dev;
file = vnp->file;
@@ -243,6 +256,47 @@
if (flags & VN_IGNORE)
return(0);
+
+ /*
+ * When a regular file has been specified, do any requested setup
+ * of the file. Truncation (also creates the file if necessary),
+ * sizing, and zeroing.
+ */
+
+ if (file && vnp->size != 0 && (flags & VN_CONFIG)) {
+ int fd;
+ struct stat st;
+
+ if (flags & VN_TRUNCATE)
+ fd = open(file, O_RDWR|O_CREAT|O_TRUNC);
+ else
+ fd = open(file, O_RDWR);
+ if (fd >= 0 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
+ if (st.st_size < (off_t)vnp->size * pgsize)
+ ftruncate(fd, (off_t)vnp->size * pgsize);
+ if (vnp->size != 0)
+ st.st_size = (off_t)vnp->size * pgsize;
+
+ if (flags & VN_ZERO) {
+ char *buf = malloc(ZBUFSIZE);
+ bzero(buf, ZBUFSIZE);
+ while (st.st_size > 0) {
+ int n = (st.st_size > ZBUFSIZE) ?
+ ZBUFSIZE : (int)st.st_size;
+ if (write(fd, buf, n) != n) {
+ ftruncate(fd, 0);
+ printf("Unable to ZERO file %s\n",
+file);
+ return(0);
+ }
+ st.st_size -= (off_t)n;
+ }
+ }
+ close(fd);
+ } else {
+ printf("Unable to open file %s\n", file);
+ return(0);
+ }
+ }
rdev = rawdevice(dev);
f = fopen(rdev, "rw");
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message