dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | LICENSE

commit d27c04494de59d32935865ca40915476d35b2c30
parent 8f5a4daf24872ef4bab13dc180ed4e693b4c5c8a
Author: sin <sin@2f30.org>
Date:   Fri, 26 Apr 2019 11:07:20 +0100

Implement block gc operation

Diffstat:
MTODO | 2+-
Mbcompress.c | 10++++++++++
Mblock.c | 12++++++++++++
Mblock.h | 2++
Mbstorage.c | 25+++++++++++++++++++++++++
5 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/TODO b/TODO @@ -2,4 +2,4 @@ Use a ring buffer in the chunker (avoid memmove() call) Create a library archive out of the blake2b files and link with it pledge/unveil support Use flock() to avoid corruption -Impelment dup-gc(1) +Implement dup-gc(1) diff --git a/bcompress.c b/bcompress.c @@ -26,6 +26,7 @@ static int bcopen(struct bctx *bctx, char *path, int flags, int mode, struct bpa static int bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); static int bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); static int bcrm(struct bctx *bctx, unsigned char *md); +static int bcgc(struct bctx *bctx, unsigned char *md); static int bccheck(struct bctx *bctx, unsigned char *md); static int bcsync(struct bctx *bctx); static int bcclose(struct bctx *bctx); @@ -36,6 +37,7 @@ static struct bops bops = { .put = bcput, .get = bcget, .rm = bcrm, + .gc = bcgc, .check = bccheck, .sync = bcsync, .close = bcclose, @@ -248,6 +250,14 @@ bcrm(struct bctx *bctx, unsigned char *md) } static int +bcgc(struct bctx *bctx, unsigned char *md) +{ + struct bops *bops = bstorageops(); + + return bops->gc(bctx, md); +} + +static int bccheck(struct bctx *bctx, unsigned char *md) { struct bops *bops = bstorageops(); diff --git a/block.c b/block.c @@ -90,6 +90,18 @@ brm(struct bctx *bctx, unsigned char *md) } int +bgc(struct bctx *bctx, unsigned char *md) +{ + struct bops *bops; + + if (bctx == NULL || md == NULL) + return -1; + + bops = bcompressops(); + return bops->gc(bctx, md); +} + +int bcheck(struct bctx *bctx, unsigned char *md) { struct bops *bops; diff --git a/block.h b/block.h @@ -18,6 +18,7 @@ struct bops { int (*put)(struct bctx *bctx, void *buf, size_t n, unsigned char *md); int (*get)(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); int (*rm)(struct bctx *bctx, unsigned char *md); + int (*gc)(struct bctx *bctx, unsigned char *md); int (*check)(struct bctx *bctx, unsigned char *md); int (*sync)(struct bctx *bctx); int (*close)(struct bctx *bctx); @@ -29,6 +30,7 @@ extern int bopen(char *path, int flags, int mode, struct bparam *bpar, struct bc extern int bput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); extern int bget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); extern int brm(struct bctx *bctx, unsigned char *md); +extern int bgc(struct bctx *bctx, unsigned char *md); extern int bcheck(struct bctx *bctx, unsigned char *md); extern int bsync(struct bctx *bctx); extern int bclose(struct bctx *bctx); diff --git a/bstorage.c b/bstorage.c @@ -56,6 +56,7 @@ static int bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bpa static int bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); static int bsget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); static int bsrm(struct bctx *bctx, unsigned char *md); +static int bsgc(struct bctx *bctx, unsigned char *md); static int bscheck(struct bctx *bctx, unsigned char *md); static int bssync(struct bctx *bctx); static int bsclose(struct bctx *bctx); @@ -66,6 +67,7 @@ static struct bops bops = { .put = bsput, .get = bsget, .rm = bsrm, + .gc = bsgc, .check = bscheck, .sync = bssync, .close = bsclose, @@ -570,6 +572,29 @@ bsrm(struct bctx *bctx, unsigned char *md) return 0; } +static int +bsgc(struct bctx *bctx, unsigned char *md) +{ + struct sctx *sctx; + struct bd key, *bd; + + sctx = bctx->sctx; + + /* Lookup block in the cache */ + memcpy(key.md, md, MDSIZE); + bd = RB_FIND(bdcache, &sctx->bdcache, &key); + if (bd == NULL) + return -1; + + /* Live block descriptor, nothing to do here */ + if (bd->refcnt > 0) + return 0; + + /* Re-punch the hole */ + punchhole(sctx->fd, bd->offset, bd->size); + return 0; +} + /* * Lookup the block and rehash it. Check that the * resulting hash matches the given hash.