Commit bc67baa3 authored by Mike Hibler's avatar Mike Hibler

Add option to vary the minimum free range size.

This replaces a couple of ad-hoc checks in the FreeBSD and Linux filesystem
code.  The idea is that we record a free range only if it is over a certain
length.  This has the effect of combining multiple short allocated ranges
into a single range, making for more efficient disk writes in the unzipper.
parent d380d13a
......@@ -12,6 +12,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl dhiorv
.Op Fl F Ar sectors
.Op Fl I Ar slice
.Op Fl s Ar slice
.Op Fl z Ar level
......@@ -191,6 +192,16 @@ how many sectors to compress in full disk mode. Can be used to compress
a subset of a disk.
Incompatible with
.Fl s .
.It Fl F Ar sectors
The minimum length in sectors that a free range needs to be before it
is recorded as a free range. Ranges shorter than this length are
.Dq forgotten
and wind up being compressed as allocated data. This option has the
effect of combining multiple, short allocated ranges into a single,
longer range resulting in more efficient disk writes in
.Xr imageunzip .
A value of zero will cause all free blocks to be recorded accurately
in the resulting image. The default value is 64 (32KB).
.It Fl l
Tells
.Nm
......
......@@ -73,6 +73,7 @@ int level = 4;
long dev_bsize = 1;
int ignore[NDOSPART];
int oldstyle = 0;
int frangesize= 64; /* 32k */
#define sectobytes(s) ((off_t)(s) * secsize)
#define bytestosec(b) (uint32_t)((b) / secsize)
......@@ -228,7 +229,7 @@ main(argc, argv)
int rawmode = 0;
extern char build_info[];
while ((ch = getopt(argc, argv, "vlbdihrs:c:z:oI:1")) != -1)
while ((ch = getopt(argc, argv, "vlbdihrs:c:z:oI:1F:")) != -1)
switch(ch) {
case 'v':
version++;
......@@ -273,6 +274,11 @@ main(argc, argv)
case '1':
oldstyle = 1;
break;
case 'F':
frangesize = atoi(optarg);
if (frangesize < 0)
usage();
break;
case 'h':
case '?':
default:
......@@ -768,32 +774,25 @@ read_bsdcg(struct fs *fsp, struct cg *cgp, unsigned int dbstart)
fprintf(stderr, " ");
for (count = i = 0; i < max; i++)
if (isset(p, i)) {
unsigned long dboff, dbcount;
j = i;
while ((i+1)<max && isset(p, i+1))
i++;
#if 1
if (i != j && i-j >= 31) {
#else
if (i-j >= 0) {
#endif
unsigned long dboff =
dbstart + fsbtodb(fsp, j);
unsigned long dbcount =
fsbtodb(fsp, (i-j) + 1);
dboff = dbstart + fsbtodb(fsp, j);
dbcount = fsbtodb(fsp, (i-j) + 1);
if (debug > 2) {
if (count)
fprintf(stderr, ",%s",
count % 4 ? " " :
"\n ");
fprintf(stderr,
"%lu:%ld", dboff, dbcount);
count % 4 ?
" " : "\n ");
fprintf(stderr, "%lu:%ld", dboff, dbcount);
}
addskip(dboff, dbcount);
count++;
}
}
if (debug > 2)
fprintf(stderr, "\n");
return 0;
......@@ -969,12 +968,12 @@ read_linuxgroup(struct ext2_super_block *super,
fprintf(stderr, " ");
for (count = i = 0; i < max; i++)
if (!isset(p, i)) {
unsigned long dboff;
int dbcount;
j = i;
while ((i+1)<max && !isset(p, i+1))
i++;
if (i != j && i-j >= 7) {
unsigned long dboff;
int dbcount;
/*
* The offset of this free range, relative
......@@ -992,15 +991,14 @@ read_linuxgroup(struct ext2_super_block *super,
if (debug > 2) {
if (count)
fprintf(stderr, ",%s",
count % 4 ? " " :
"\n ");
count % 4 ?
" " : "\n ");
fprintf(stderr, "%lu:%d %d:%d",
dboff, dbcount, j, i);
}
addskip(dboff, dbcount);
count++;
}
}
if (debug > 2)
fprintf(stderr, "\n");
......@@ -1323,8 +1321,14 @@ addskip(uint32_t start, uint32_t size)
{
struct range *skip;
if (size < frangesize)
return;
if ((skip = (struct range *) malloc(sizeof(*skip))) == NULL) {
fprintf(stderr, "Out of memory!\n");
fprintf(stderr, "No memory for skip range, "
"try again with '-F <numsect>'\n"
"where <numsect> is greater than the current %d\n",
frangesize);
exit(1);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment