dedup

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

commit 6699070ee14aa0fc3a48c52e0a146f6946e39ce5
parent d27c04494de59d32935865ca40915476d35b2c30
Author: sin <sin@2f30.org>
Date:   Fri, 26 Apr 2019 11:16:21 +0100

More gc work

Diffstat:
Mbstorage.c | 51+++++++++++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/bstorage.c b/bstorage.c @@ -23,6 +23,7 @@ #include "blake2.h" #include "block.h" #include "config.h" +#include "queue.h" #include "tree.h" #define VMIN 0 @@ -87,13 +88,15 @@ struct bd { uint64_t size; uint64_t refcnt; unsigned char md[MDSIZE]; - RB_ENTRY(bd) entry; + RB_ENTRY(bd) rbe; + SLIST_ENTRY(bd) sle; }; RB_HEAD(bdcache, bd); - + /* Storage layer context */ struct sctx { struct bdcache bdcache; + SLIST_HEAD(gchead, bd) gchead; struct bhdr bhdr; int fd; int rdonly; /* when set to 1, the bssync() operation is a no-op */ @@ -111,8 +114,8 @@ bd_cmp(struct bd *b1, struct bd *b2) return -1; return 0; } -static RB_PROTOTYPE(bdcache, bd, entry, bd_cmp) -static RB_GENERATE(bdcache, bd, entry, bd_cmp) +static RB_PROTOTYPE(bdcache, bd, rbe, bd_cmp) +static RB_GENERATE(bdcache, bd, rbe, bd_cmp) static int bhash(void *buf, size_t n, unsigned char *md) @@ -277,7 +280,7 @@ loadbd(struct sctx *sctx) if (bd->refcnt > 0) RB_INSERT(bdcache, &sctx->bdcache, bd); else - free(bd); + SLIST_INSERT_HEAD(&sctx->gchead, bd, sle); return 0; } @@ -295,11 +298,18 @@ initbdcache(struct sctx *sctx) if (loadbd(sctx) == 0) continue; - /* Cleanup */ + /* Free block descriptor cache */ RB_FOREACH_SAFE(bd, bdcache, &sctx->bdcache, tmp) { RB_REMOVE(bdcache, &sctx->bdcache, bd); free(bd); } + + /* Free garbage collector list */ + while (!SLIST_EMPTY(&sctx->gchead)) { + bd = SLIST_FIRST(&sctx->gchead); + SLIST_REMOVE(&sctx->gchead, bd, bd, sle); + free(bd); + } return -1; } return 0; @@ -325,6 +335,7 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) sctx = bctx->sctx; RB_INIT(&sctx->bdcache); + SLIST_INIT(&sctx->gchead); bhdr = &sctx->bhdr; memcpy(bhdr->magic, BHDRMAGIC, NBHDRMAGIC); bhdr->flags = (VMAJ << VMAJSHIFT) | VMIN; @@ -380,6 +391,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) sctx = bctx->sctx; RB_INIT(&sctx->bdcache); + SLIST_INIT(&sctx->gchead); bhdr = &sctx->bhdr; if (unpackbhdr(fd, bhdr) < 0) { free(sctx); @@ -567,7 +579,7 @@ bsrm(struct bctx *bctx, unsigned char *md) } RB_REMOVE(bdcache, &sctx->bdcache, bd); - free(bd); + SLIST_INSERT_HEAD(&sctx->gchead, bd, sle); } return 0; } @@ -579,19 +591,10 @@ bsgc(struct bctx *bctx, unsigned char *md) 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); + SLIST_FOREACH(bd, &sctx->gchead, sle) { + assert(bd->refcnt == 0); + punchhole(sctx->fd, bd->offset, bd->size); + } return 0; } @@ -674,11 +677,19 @@ bsclose(struct bctx *bctx) return -1; sctx = bctx->sctx; + /* Free block descriptor cache */ RB_FOREACH_SAFE(bd, bdcache, &sctx->bdcache, tmp) { RB_REMOVE(bdcache, &sctx->bdcache, bd); free(bd); } + /* Free garbage collector list */ + while (!SLIST_EMPTY(&sctx->gchead)) { + bd = SLIST_FIRST(&sctx->gchead); + SLIST_REMOVE(&sctx->gchead, bd, bd, sle); + free(bd); + } + r = close(sctx->fd); free(sctx); return r;