summaryrefslogtreecommitdiffstats
path: root/usr.bin/mkuzip
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2016-03-13 21:09:08 +0000
committersobomax <sobomax@FreeBSD.org>2016-03-13 21:09:08 +0000
commitbd7cbc7f20b157f6c712deaebba1cfb4f619cfcd (patch)
treed17352cd27fe79fa75ed249b409198803b5cb09f /usr.bin/mkuzip
parent94e9e924f73543b44ec6c79d2f758cdd047f9dfd (diff)
downloadFreeBSD-src-bd7cbc7f20b157f6c712deaebba1cfb4f619cfcd.zip
FreeBSD-src-bd7cbc7f20b157f6c712deaebba1cfb4f619cfcd.tar.gz
In the de-duplication mode, when found matching md5 checksum also read
back block and compare actual content. Just output original block instead of back reference in the unlikely event of collision.
Diffstat (limited to 'usr.bin/mkuzip')
-rw-r--r--usr.bin/mkuzip/mkuz_blockcache.c49
-rw-r--r--usr.bin/mkuzip/mkuzip.c2
2 files changed, 48 insertions, 3 deletions
diff --git a/usr.bin/mkuzip/mkuz_blockcache.c b/usr.bin/mkuzip/mkuz_blockcache.c
index a3ac564..204fce2 100644
--- a/usr.bin/mkuzip/mkuz_blockcache.c
+++ b/usr.bin/mkuzip/mkuz_blockcache.c
@@ -29,7 +29,9 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <err.h>
#include <md5.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -49,6 +51,35 @@ struct mkuz_blkcache {
static struct mkuz_blkcache blkcache;
+static int
+verify_match(int fd, off_t data_offset, void *data, ssize_t len,
+ struct mkuz_blkcache *bcep)
+{
+ void *vbuf;
+ ssize_t rlen;
+ int rval;
+
+ rval = -1;
+ vbuf = malloc(len);
+ if (vbuf == NULL) {
+ goto e0;
+ }
+ if (lseek(fd, bcep->data_offset, SEEK_SET) < 0) {
+ goto e1;
+ }
+ rlen = read(fd, vbuf, len);
+ if (rlen != len) {
+ goto e2;
+ }
+ rval = (memcmp(data, vbuf, len) == 0) ? 1 : 0;
+e2:
+ lseek(fd, data_offset, SEEK_SET);
+e1:
+ free(vbuf);
+e0:
+ return (rval);
+}
+
struct mkuz_blkcache_hit *
mkuz_blkcache_regblock(int fd, uint32_t blkno, off_t offset, ssize_t len,
void *data)
@@ -57,6 +88,7 @@ mkuz_blkcache_regblock(int fd, uint32_t blkno, off_t offset, ssize_t len,
MD5_CTX mcontext;
off_t data_offset;
unsigned char mdigest[16];
+ int rval;
data_offset = lseek(fd, 0, SEEK_CUR);
if (data_offset < 0) {
@@ -76,10 +108,23 @@ mkuz_blkcache_regblock(int fd, uint32_t blkno, off_t offset, ssize_t len,
}
}
if (bcep != NULL) {
+ rval = verify_match(fd, data_offset, data, len, bcep);
+ if (rval == 1) {
+#if defined(MKUZ_DEBUG)
+ fprintf(stderr, "cache hit %d, %d, %d\n",
+ (int)bcep->hit.offset, (int)data_offset, (int)len);
+#endif
+ return (&bcep->hit);
+ }
+ if (rval == 0) {
#if defined(MKUZ_DEBUG)
- printf("cache hit %d, %d, %d\n", (int)bcep->hit.offset, (int)data_offset, (int)len);
+ fprintf(stderr, "block MD5 collision, you should try lottery, "
+ "man!\n");
#endif
- return (&bcep->hit);
+ return (NULL);
+ }
+ warn("verify_match");
+ return (NULL);
}
bcep = malloc(sizeof(struct mkuz_blkcache));
if (bcep == NULL)
diff --git a/usr.bin/mkuzip/mkuzip.c b/usr.bin/mkuzip/mkuzip.c
index fa73653..c436075 100644
--- a/usr.bin/mkuzip/mkuzip.c
+++ b/usr.bin/mkuzip/mkuzip.c
@@ -221,7 +221,7 @@ int main(int argc, char **argv)
}
toc = mkuz_safe_malloc((hdr.nblocks + 1) * sizeof(*toc));
- fdw = open(oname, O_WRONLY | O_TRUNC | O_CREAT,
+ fdw = open(oname, (en_dedup ? O_RDWR : O_WRONLY) | O_TRUNC | O_CREAT,
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (fdw < 0) {
err(1, "open(%s)", oname);
OpenPOWER on IntegriCloud