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:

Reply via email to