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