Subject: compressed vnd
To: tech-kern <tech-kern@netbsd.org>
From: Wei Lu <w.lu@tuhh.de>
List: tech-kern
Date: 05/25/2005 00:36:27
Cliff Wright <cliff@snipe444.org> released a patch of vnd pseudo-device driver to support compressed filesystem image. I like it very much.
However, there was a little problem on his patch. When ppp_deflate or ipsec or opencrypto is not compiled in the kernel, the compiling of modified vnd device fails becuz zlib object is not included.
the revised patch (generated on my NetBSD/i386 2.0.2) is as follows:
_______________________
--- /usr/src/sys/conf/files 2005-05-25 01:06:24.000000000 +0200
+++ /usr/src/sys/conf/files.orig 2004-08-30 11:24:33.000000000 +0200
@@ -1269,7 +1269,7 @@
file net/route.c
file net/rtsock.c
file net/slcompress.c sl | ppp | strip | (irip & irip_vj)
-file net/zlib.c (ppp & ppp_deflate) | ipsec | opencrypto | vnd
+file net/zlib.c (ppp & ppp_deflate) | ipsec | opencrypto
file net80211/ieee80211.c wlan
file net80211/ieee80211_compat.c wlan
file net80211/ieee80211_crypto.c wlan
--- /usr/src/sys/dev/vnd.c 2005-05-25 00:00:34.000000000 +0200
+++ /usr/src/sys/dev/vnd.c.orig 2004-01-25 19:06:48.000000000 +0100
@@ -156,7 +156,6 @@
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/conf.h>
-#include <net/zlib.h>
#include <miscfs/specfs/specdev.h>
@@ -208,7 +207,6 @@
void vndclear __P((struct vnd_softc *, int));
void vndstart __P((struct vnd_softc *));
-void compstrategy __P((struct buf *, off_t));
int vndsetcred __P((struct vnd_softc *, struct ucred *));
void vndthrottle __P((struct vnd_softc *, struct vnode *));
void vndiodone __P((struct buf *));
@@ -221,8 +219,6 @@
static int vndlock __P((struct vnd_softc *));
static void vndunlock __P((struct vnd_softc *));
-static void *vnd_alloc __P((void *, u_int, u_int));
-static void vnd_free __P((void *, void *));
dev_type_open(vndopen);
dev_type_close(vndclose);
@@ -267,9 +263,6 @@
for (i = 0; i < numvnd; i++) {
vnd_softc[i].sc_unit = i;
- vnd_softc[i].sc_comp_offsets = NULL;
- vnd_softc[i].sc_comp_buff = NULL;
- vnd_softc[i].sc_comp_decombuf = NULL;
bufq_alloc(&vnd_softc[i].sc_tab,
BUFQ_DISKSORT|BUFQ_SORT_RAWBLOCK);
}
@@ -490,12 +483,6 @@
bp->b_flags |= B_ERROR;
goto done;
}
- /* handle a compressed read */
- if((bp->b_flags & B_READ) && (vnd->sc_flags & VNF_COMP)) {
- compstrategy(bp, bn);
- goto done;
- }
-
bsize = vnd->sc_vp->v_mount->mnt_stat.f_iosize;
addr = bp->b_data;
flags = (bp->b_flags & (B_READ|B_ASYNC)) | B_CALL;
@@ -739,98 +726,6 @@
splx(s);
}
-/* compressed file read */
-void
-compstrategy(bp, bn)
- struct buf *bp;
- off_t bn;
-{
- int error;
- int unit = vndunit(bp->b_dev);
- struct vnd_softc *vnd = &vnd_softc[unit];
- u_int32_t comp_block;
- struct uio auio;
- caddr_t addr;
-
- /* set up constants for data move */
- auio.uio_rw = UIO_READ;
- auio.uio_segflg = bp->b_flags & B_PHYS ? UIO_USERSPACE : UIO_SYSSPACE;
- auio.uio_procp = bp->b_proc;
-
- /* read, and transfer the data */
- addr = bp->b_data;
- while(bp->b_resid > 0) {
- unsigned length;
- size_t length_in_buffer;
- u_int32_t offset_in_buffer;
- struct iovec aiov;
-
- /* calculate the compressed block number */
- comp_block = bn / (off_t)vnd->sc_comp_blksz;
-
- /* check for good block number */
- if(comp_block >= vnd->sc_comp_numoffs) {
- bp->b_error = EINVAL;
- bp->b_flags |= B_ERROR;
- return;
- }
-
- /* read in the compressed block, if not in buffer */
- if (comp_block != vnd->sc_comp_buffblk) {
- length = vnd->sc_comp_offsets[comp_block + 1] -
- vnd->sc_comp_offsets[comp_block];
- error = vn_rdwr(UIO_READ, vnd->sc_vp, vnd->sc_comp_buff,
- length, vnd->sc_comp_offsets[comp_block],
- UIO_SYSSPACE, IO_UNIT, vnd->sc_cred, NULL, NULL);
- if(error) {
- bp->b_error = error;
- bp->b_flags |= B_ERROR;
- return;
- }
- /* uncompress the buffer */
- vnd->sc_comp_stream.next_in = vnd->sc_comp_buff;
- vnd->sc_comp_stream.avail_in = length;
- vnd->sc_comp_stream.next_out = vnd->sc_comp_decombuf;
- vnd->sc_comp_stream.avail_out = vnd->sc_comp_blksz;
- inflateReset(&vnd->sc_comp_stream);
- error = inflate(&vnd->sc_comp_stream, Z_FINISH);
- if(error != Z_STREAM_END) {
- if(vnd->sc_comp_stream.msg)
- printf("%s: compressed file, %s\n",
- vnd->sc_xname,
- vnd->sc_comp_stream.msg);
- bp->b_error = EBADMSG;
- bp->b_flags |= B_ERROR;
- return;
- }
- vnd->sc_comp_buffblk = comp_block;
- }
-
- /* transfer the usable uncompressed data */
- offset_in_buffer = bn % (off_t)vnd->sc_comp_blksz;
- length_in_buffer = vnd->sc_comp_blksz - offset_in_buffer;
- if(length_in_buffer > bp->b_resid)
- length_in_buffer = bp->b_resid;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- aiov.iov_base = addr;
- aiov.iov_len = length_in_buffer;
- auio.uio_resid = aiov.iov_len;
- auio.uio_offset = 0;
- error = uiomove(vnd->sc_comp_decombuf + offset_in_buffer,
- length_in_buffer, &auio);
- if(error) {
- bp->b_error = error;
- bp->b_flags |= B_ERROR;
- return;
- }
-
- bn += length_in_buffer;
- addr += length_in_buffer;
- bp->b_resid -= length_in_buffer;
- }
-}
-
/* ARGSUSED */
int
vndread(dev, uio, flags)
@@ -964,115 +859,11 @@
if ((error = vn_open(&nd, fflags, 0)) != 0)
goto unlock_and_exit;
error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p);
+ VOP_UNLOCK(nd.ni_vp, 0);
if (!error && nd.ni_vp->v_type != VREG)
error = EOPNOTSUPP;
- if (error) {
- VOP_UNLOCK(nd.ni_vp, 0);
+ if (error)
goto close_and_exit;
- }
-
- /* If using a compressed file, initialize its info */
- if (vio->vnd_flags & VNF_COMP) {
- struct comp_header *ch;
- int error;
- int i;
- u_int32_t comp_size;
- u_int32_t comp_maxsize;
-
- /* allocate space for compresed file header */
- ch = malloc(sizeof(struct comp_header),
- M_TEMP, M_WAITOK);
-
- /* read compressed file header */
- error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)ch,
- sizeof(struct comp_header), 0, UIO_SYSSPACE,
- IO_UNIT|IO_NODELOCKED, p->p_ucred, NULL, NULL);
- if(error) {
- free(ch, M_TEMP);
- VOP_UNLOCK(nd.ni_vp, 0);
- goto close_and_exit;
- }
-
- /* save some header info */
- vnd->sc_comp_blksz = ntohl(ch->block_size);
- /* note last offset is the file byte size */
- vnd->sc_comp_numoffs = ntohl(ch->num_blocks)+1;
- free(ch, M_TEMP);
- if(vnd->sc_comp_blksz % DEV_BSIZE !=0) {
- VOP_UNLOCK(nd.ni_vp, 0);
- error = EINVAL;
- goto close_and_exit;
- }
- if(sizeof(struct comp_header) +
- sizeof(u_int64_t) * vnd->sc_comp_numoffs >
- vattr.va_size) {
- VOP_UNLOCK(nd.ni_vp, 0);
- error = EINVAL;
- goto close_and_exit;
- }
-
- /* set decompressed file size */
- vattr.va_size =
- (vnd->sc_comp_numoffs - 1) * vnd->sc_comp_blksz;
-
- /* allocate space for all the compressed offsets */
- vnd->sc_comp_offsets =
- malloc(sizeof(u_int64_t) * vnd->sc_comp_numoffs,
- M_DEVBUF, M_WAITOK);
-
- /* read in the offsets */
- error = vn_rdwr(UIO_READ, nd.ni_vp,
- (caddr_t)vnd->sc_comp_offsets,
- sizeof(u_int64_t) * vnd->sc_comp_numoffs,
- sizeof(struct comp_header), UIO_SYSSPACE,
- IO_UNIT|IO_NODELOCKED, p->p_ucred, NULL, NULL);
- if(error) {
- VOP_UNLOCK(nd.ni_vp, 0);
- goto close_and_exit;
- }
- /*
- * find largest block size (used for allocation limit).
- * Also convert offset to native byte order.
- */
- comp_maxsize = 0;
- for (i = 0; i < vnd->sc_comp_numoffs - 1; i++) {
- vnd->sc_comp_offsets[i] =
- be64toh(vnd->sc_comp_offsets[i]);
- comp_size = be64toh(vnd->sc_comp_offsets[i + 1])
- - vnd->sc_comp_offsets[i];
- if (comp_size > comp_maxsize)
- comp_maxsize = comp_size;
- }
- vnd->sc_comp_offsets[vnd->sc_comp_numoffs - 1] =
- be64toh(vnd->sc_comp_offsets[vnd->sc_comp_numoffs - 1]);
-
- /* create compressed data buffer */
- vnd->sc_comp_buff = malloc(comp_maxsize,
- M_DEVBUF, M_WAITOK);
-
- /* create decompressed buffer */
- vnd->sc_comp_decombuf = malloc(vnd->sc_comp_blksz,
- M_DEVBUF, M_WAITOK);
- vnd->sc_comp_buffblk = -1;
-
- /* Initialize decompress stream */
- bzero(&vnd->sc_comp_stream, sizeof(z_stream));
- vnd->sc_comp_stream.zalloc = vnd_alloc;
- vnd->sc_comp_stream.zfree = vnd_free;
- error = inflateInit2(&vnd->sc_comp_stream, MAX_WBITS);
- if(error) {
- if(vnd->sc_comp_stream.msg)
- printf("vnd%d: compressed file, %s\n",
- unit, vnd->sc_comp_stream.msg);
- VOP_UNLOCK(nd.ni_vp, 0);
- error = EINVAL;
- goto close_and_exit;
- }
-
- vnd->sc_flags |= VNF_COMP | VNF_READONLY;
- }
-
- VOP_UNLOCK(nd.ni_vp, 0);
vnd->sc_vp = nd.ni_vp;
vnd->sc_size = btodb(vattr.va_size); /* note truncation */
@@ -1173,19 +964,6 @@
close_and_exit:
(void) vn_close(nd.ni_vp, fflags, p->p_ucred, p);
unlock_and_exit:
- /* free any allocated memory (for compressed file) */
- if(vnd->sc_comp_offsets) {
- free(vnd->sc_comp_offsets, M_DEVBUF);
- vnd->sc_comp_offsets = NULL;
- }
- if(vnd->sc_comp_buff) {
- free(vnd->sc_comp_buff, M_DEVBUF);
- vnd->sc_comp_buff = NULL;
- }
- if(vnd->sc_comp_decombuf) {
- free(vnd->sc_comp_decombuf, M_DEVBUF);
- vnd->sc_comp_decombuf = NULL;
- }
vndunlock(vnd);
return (error);
@@ -1465,22 +1243,7 @@
if ((vnd->sc_flags & VNF_READONLY) == 0)
fflags |= FWRITE;
- /* free the compressed file buffers */
- if(vnd->sc_flags & VNF_COMP) {
- if(vnd->sc_comp_offsets) {
- free(vnd->sc_comp_offsets, M_DEVBUF);
- vnd->sc_comp_offsets = NULL;
- }
- if(vnd->sc_comp_buff) {
- free(vnd->sc_comp_buff, M_DEVBUF);
- vnd->sc_comp_buff = NULL;
- }
- if(vnd->sc_comp_decombuf) {
- free(vnd->sc_comp_decombuf, M_DEVBUF);
- vnd->sc_comp_decombuf = NULL;
- }
- }
- vnd->sc_flags &= ~(VNF_INITED | VNF_READONLY | VNF_VLABEL | VNF_COMP);
+ vnd->sc_flags &= ~(VNF_INITED | VNF_READONLY | VNF_VLABEL);
if (vp == (struct vnode *)0)
panic("vndioctl: null vp");
(void) vn_close(vp, fflags, vnd->sc_cred, p);
@@ -1665,23 +1428,3 @@
wakeup(sc);
}
}
-
-/* compression memory allocation routines */
-static void *
-vnd_alloc(aux, items, siz)
- void *aux;
- u_int items;
- u_int siz;
-{
- void *ptr;
- ptr = malloc(items * siz, M_TEMP, M_NOWAIT);
- return ptr;
-}
-
-static void
-vnd_free(aux, ptr)
- void *aux;
- void *ptr;
-{
- free(ptr, M_TEMP);
-}
--- /usr/src/sys/dev/vndvar.h 2005-05-25 00:00:34.000000000 +0200
+++ /usr/src/sys/dev/vndvar.h.orig 2003-08-07 18:30:52.000000000 +0200
@@ -162,13 +162,6 @@
struct vndgeom sc_geom; /* virtual geometry */
struct pool sc_vxpool; /* vndxfer pool */
struct pool sc_vbpool; /* vndbuf pool */
- u_int32_t sc_comp_blksz; /* precompressed block size */
- u_int32_t sc_comp_numoffs;/* count of compressed block offsets */
- u_int64_t *sc_comp_offsets;/* file idx's to compressed blocks */
- unsigned char *sc_comp_buff; /* compressed data buffer */
- unsigned char *sc_comp_decombuf;/* decompressed data buffer */
- int32_t sc_comp_buffblk;/* current decompressed block */
- z_stream sc_comp_stream;/* decompress descriptor */
};
#endif
@@ -182,15 +175,6 @@
#define VNF_READONLY 0x040 /* unit is read-only */
#define VNF_KLABEL 0x080 /* keep label on close */
#define VNF_VLABEL 0x100 /* label is valid */
-#define VNF_COMP 0x200 /* file is compressed */
-
-/* structure of header in a compressed file */
-struct comp_header
-{
- char preamble[128];
- u_int32_t block_size;
- u_int32_t num_blocks;
-};
/*
* A simple structure for describing which vnd units are in use.
--- /usr/src/usr.sbin/vnconfig/vnconfig.c 2005-05-25 00:00:34.000000000 +0200
+++ /usr/src/usr.sbin/vnconfig/vnconfig.c.orig 2004-01-25 22:49:04.000000000 +0100
@@ -139,7 +139,6 @@
int verbose = 0;
int readonly = 0;
int force = 0;
-int compressed = 0;
char *tabname;
int config __P((char *, char *, char *, int));
@@ -155,7 +154,7 @@
{
int ch, rv, action = VND_CONFIG;
- while ((ch = getopt(argc, argv, "Fcf:lrt:uvz")) != -1) {
+ while ((ch = getopt(argc, argv, "Fcf:lrt:uv")) != -1) {
switch (ch) {
case 'F':
force = 1;
@@ -182,10 +181,6 @@
case 'v':
verbose = 1;
break;
- case 'z':
- compressed = 1;
- readonly = 1;
- break;
default:
case '?':
usage();
@@ -319,9 +314,6 @@
if (readonly)
vndio.vnd_flags |= VNDIOF_READONLY;
- if (compressed)
- vndio.vnd_flags |= 0x200; /* VNF_COMP, cliff */
-
/*
* Clear (un-configure) the device
*/
__________________
Wei Lu