Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorJames Cameron <quozl@laptop.org>2011-04-21 04:46:31 (GMT)
committer Daniel Drake <dsd@laptop.org>2011-05-03 19:47:08 (GMT)
commita17b54443ecceea57df5dfc05145da2d085e2fba (patch)
tree0cc34f0b5195190a6e71a31254ff7d4ad39844e1 /bin
parenta208d67f5aa86f39da0bcbc25e8c635056c84ec1 (diff)
zhashfs: detect fill pattern and suppress blocks in output
Allows the unused filesystem blocks of the image to be left out of the .zd file, resulting in a factor of two reduction in fs-update times on a typical build on a 4GB microSD. Greater reduction occurs on larger microSD or SD cards. Has no effect if a fill pattern file is not found.
Diffstat (limited to 'bin')
-rw-r--r--bin/zhashfs.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/bin/zhashfs.c b/bin/zhashfs.c
index 87fd2df..b3b86e0 100644
--- a/bin/zhashfs.c
+++ b/bin/zhashfs.c
@@ -13,6 +13,8 @@ static long zbufsize;
static long zblocksize;
static char *hashname;
+#define PATTERN_SIZE 4096
+
#define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x); } while (0);
static void run_cmd(int res, int line, char *file, char *cmd)
{
@@ -77,7 +79,12 @@ int main(int argc, char **argv)
off_t insize;
int readlen;
- int allf;
+ int skip;
+
+ unsigned char *pbuf; // fill pattern buffer
+ char *pname; // fill pattern file name
+ FILE *pfile; // fill pattern file
+ int patterned, n;
if (argc < 6) {
fprintf(stderr, "%s: zblocksize hashname signed_file_name spec_file_name zdata_file_name [ #blocks ]\n", argv[0]);
@@ -112,6 +119,18 @@ int main(int argc, char **argv)
infile = fopen(argv[3], "rb");
LTC_ARGCHK(infile != NULL);
+ /* open and read an optional fill pattern file */
+ pbuf = NULL;
+ pname = strcat(argv[3], ".fill");
+ pfile = fopen(pname, "rb");
+ if (pfile != NULL) {
+ pbuf = malloc(PATTERN_SIZE);
+ LTC_ARGCHK(pbuf != NULL);
+ n = fread(pbuf, 1, PATTERN_SIZE, pfile);
+ LTC_ARGCHK(n == PATTERN_SIZE);
+ fclose(pfile);
+ }
+
/* open output file */
outfile = fopen(argv[4], "wb");
LTC_ARGCHK(outfile != NULL);
@@ -155,18 +174,38 @@ int main(int argc, char **argv)
LTC_ARGCHK(readlen == zblocksize);
#ifdef notdef
- allf = 1;
+ skip = 1;
for (p = (unsigned char *)buf; p < &buf[zblocksize]; p++) {
if (*p != 0xff) {
- allf = 0;
+ skip = 0;
break;
}
}
#else
- allf = 0;
+ skip = 0;
#endif
- if (!allf)
+ if (pbuf) {
+ /* check if this zblock is fully patterned as unused, and if
+ any parts of the zblock are patterned then zero them, for ease
+ of compression */
+
+ patterned = 1;
+ for (n = 0; n < (zblocksize / PATTERN_SIZE); n++) {
+ if (memcmp(&buf[n*PATTERN_SIZE], pbuf, PATTERN_SIZE)) {
+ patterned = 0;
+ } else {
+ memset(&buf[n*PATTERN_SIZE], 0, PATTERN_SIZE);
+ }
+ }
+
+ /* skip any block that is fully patterned, thus relying on the
+ fs-update card erase-blocks */
+
+ if (patterned) skip++;
+ }
+
+ if (!skip)
write_block(i, buf);
fprintf(stdout, "\r%ld", i); fflush(stdout);