Package: cloop-utils
Version: 2.01.5-3
Severity: wishlist
Tags: patch
Moin,
This patch adds a -t option to advfs. With this option being set, advfs
no longer saves the compressed image in memory; instead, it writes a
temporary file containing the compressed blocks. This makes advfs faster
on computers with few RAM (assuming it worked once without activating
the OOM killer ;-)).
Sebastian
diff -ur cloop-2.01.5/advancecomp-1.9_create_compressed_fs/advfs.cc
cloop-2.01.5.new/advancecomp-1.9_create_compressed_fs/advfs.cc
--- cloop-2.01.5/advancecomp-1.9_create_compressed_fs/advfs.cc 2004-04-18
22:33:29.000000000 +0200
+++ cloop-2.01.5.new/advancecomp-1.9_create_compressed_fs/advfs.cc
2005-02-28 20:47:31.000000000 +0100
@@ -2,6 +2,10 @@
* (c)1999 Paul `Rusty' Russell. GPL.
*
* CHANGELOG:
+ * * Mon Feb 28 20:45:14 CET 2005 Sebastian Schmidt <[EMAIL PROTECTED]>
+ * - Added -t command line option to use a temporary file for the compressed
+ * blocks instead of saving it in cb_list.
+ * - Added information message before the write of the compressed image.
* * Sat Deb 14 22:49:20 CEST 2004 Christian Leber
* - Changed to work with the advancecomp packages, so that it's
* better algorithms may be used
@@ -44,6 +48,8 @@
#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V2.0 Format\n" "modprobe cloop file=$0
&& mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
+#define MAXLEN(blocksize) ((blocksize) + (blocksize)/1000 + 12)
+
struct cb_list
{
struct cb_list *next;
@@ -59,7 +65,8 @@
/* Now using the goto style because it is quicker to read */
static struct cb_list *create_compressed_blocks(int handle, unsigned long
- blocksize, unsigned long *numblocks, int method)
+ blocksize, unsigned long *numblocks, int method,
+ int tempfile)
/* method==0: Use "gzip -9", method==-1: Try best (very slow). */
{
struct cb_list *cbl,**cbp=&cbl;
@@ -67,7 +74,7 @@
const int maxalg=11;
unsigned int last, took[maxalg];
unsigned long long total_uncompressed=0,total_compressed=0;
- unsigned long maxlen = blocksize + blocksize/1000 + 12;
+ unsigned long maxlen = MAXLEN(blocksize);
char *compressed[maxalg], *uncompressed;
if((uncompressed=(char *)malloc(blocksize))==NULL)
{
@@ -131,8 +138,9 @@
}
}
++took[best];
-
- if((*cbp = (cb_list *)malloc(sizeof(struct cb_list)+len[best]))==NULL) /*
get another block */
+
+ if((*cbp = (cb_list *)malloc(sizeof(struct cb_list)+
+ ((tempfile==-1)?len[best]:0)))==NULL) /* get another block */
{
fprintf(stderr, "*** Out of memory allocating block ptrs (virtual memory
exhausted).\n");
goto error_free_cb_list;
@@ -141,7 +149,15 @@
/* Print status */
fprintf(stderr, "[%2d] Block# %5lu size %6lu -> %6lu [compression ratio
%3lu%%, overall: %3Lu%%]\n", best, i, total, len[best],
total>0?((len[best]*100)/total):100,total_uncompressed>0?((total_compressed*100)/total_uncompressed):100);
(*cbp)->size = len[best];
- memcpy((*cbp)->data, compressed[best], len[best]);
+ if (tempfile == -1)
+ memcpy((*cbp)->data, compressed[best], len[best]);
+ else
+ if (write(tempfile, compressed[best], len[best]) != len[best])
+ {
+ perror("Unable to write to temporary file");
+ goto error_free_cb_list;
+ }
+
(*cbp)->next=NULL;
cbp=&((*cbp)->next);
} /* for */
@@ -164,7 +180,8 @@
int usage(char *progname)
{
- fprintf(stderr, "Usage: %s [-b|--best] filename
blocksize(bytes).\n",progname);
+ fprintf(stderr, "Usage: %s [-b|--best] [-t|--tempfile] filename "
+ "blocksize(bytes).\n",progname);
fprintf(stderr, "Use '-' as filename for stdin.\n");
return 1;
}
@@ -176,15 +193,32 @@
struct cloop_head head;
unsigned long numblocks;
unsigned long long bytes_so_far;
+ unsigned long maxlen;
unsigned long i;
int method=0;
struct cb_list *compressed_blocks,*cbp;
+ int tempfile = -1;
+ char *compressed;
if(argc<3) return usage(argv[0]);
for(i=1;i<argc;i++)
{
if(!(strcmp(argv[i],"-b")&&strcmp(argv[i],"--best"))) method=-1;
+ if(!(strcmp(argv[i],"-t")&&strcmp(argv[i],"--tempfile")))
+ {
+ FILE *t = tmpfile();
+ if (t == NULL)
+ {
+ perror("Unable to create temporary file");
+ return 1;
+ }
+ if ((tempfile = fileno(t)) < 0)
+ {
+ perror("Unable to get temporary file's file descriptor");
+ return 1;
+ }
+ }
else if((b=atoi(argv[i]))>0) blocksize=b;
else if(in<0) in=strcmp(argv[i],"-")==0?dup(fileno(stdin)):open(argv[i],
O_RDONLY);
else
@@ -218,7 +252,8 @@
return 1;
}
- compressed_blocks = create_compressed_blocks(in, blocksize, &numblocks,
method);
+ compressed_blocks = create_compressed_blocks(in, blocksize, &numblocks,
+ method, tempfile);
close(in);
@@ -237,6 +272,8 @@
if (!compressed_blocks) return 1;
+ fprintf(stderr, "Writing %lu blocks to stdout, please wait...\n", numblocks);
+
/* Write offsets */
for (i=0,cbp=compressed_blocks; i < numblocks+1; i++)
{
@@ -246,18 +283,67 @@
if(cbp) { bytes_so_far += cbp->size; cbp=cbp->next; }
}
+
+ if (tempfile != -1)
+ {
+ maxlen = MAXLEN(blocksize);
+ if ((compressed = (char *)malloc(maxlen)) == NULL)
+ {
+ fprintf(stderr, "Unable to allocate %d bytes for compressed block\n",
+ maxlen);
+ free_cb_list(compressed_blocks);
+ return 1;
+ }
+ if (lseek(tempfile, 0, SEEK_SET) < 0)
+ {
+ perror("seeking temporary file to beginning");
+ free_cb_list(compressed_blocks);
+ free(compressed);
+ return 1;
+ }
+ }
+
/* Now write blocks and free them. */
for (i = 0, cbp=compressed_blocks; cbp && i < numblocks; i++)
{
- if (write(STDOUT_FILENO, cbp->data, cbp->size) != cbp->size)
+ if (tempfile == -1)
+ compressed = cbp->data;
+ else
+ {
+ ssize_t total, now;
+ for (total = 0; total < cbp->size; total += now)
+ {
+ if ((now = read(tempfile, compressed+total, cbp->size-total)) < 0)
+ {
+ perror("reading from temporary file");
+ free_cb_list(compressed_blocks);
+ free(compressed);
+ return 1;
+ }
+ else if (now == 0)
+ {
+ fprintf(stderr, "EOF while reading from temporary file\n");
+ free_cb_list(compressed_blocks);
+ free(compressed);
+ return 1;
+ }
+ }
+ }
+
+ if (write(STDOUT_FILENO, compressed, cbp->size) != cbp->size)
{
perror("writing block");
+ if (tempfile != -1)
+ free(compressed);
free_cb_list(compressed_blocks);
return 1;
}
cbp=cbp->next;
free(compressed_blocks); compressed_blocks=cbp;
}
+
fprintf(stderr,"Done.\n");
+ if (tempfile != -1)
+ free(compressed);
return 0;
}
diff -ur cloop-2.01.5/debian/create_compressed_fs.1
cloop-2.01.5.new/debian/create_compressed_fs.1
--- cloop-2.01.5/debian/create_compressed_fs.1 2005-02-28 20:42:43.000000000
+0100
+++ cloop-2.01.5.new/debian/create_compressed_fs.1 2005-02-28
20:56:58.000000000 +0100
@@ -12,7 +12,7 @@
\fBcreate_compressed_fs\fR \fB image\fR \fBblocksize\fR [ \fB>
image.cloop_compressed\fR ]
-\fBadvfs\fR \fB image\fR \fBblocksize\fR [ \fB> image.cloop_compressed\fR ]
+\fBadvfs\fR [ \fB-t\fR ] \fBimage\fR \fBblocksize\fR [ \fB>
image.cloop_compressed\fR ]
\fBextract_compressed_fs\fR \fB filename\fR
@@ -30,6 +30,11 @@
\fBadvfs\fR is an experimental alternative to
create_compressed_fs. It should need less memory and can work with data from
STDIN.
+.PP
+If you pass the
+.RB -t
+option to \fBadvfs\fR, a temporary file will be created
+instead of holding the whole compressed image in memory.
.SH "MOUNTING"
.PP
You have to pass the options to the cloop module on loading: