URI: 
       More gc work - dedup - deduplicating backup program
  HTML git clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
   DIR commit 6699070ee14aa0fc3a48c52e0a146f6946e39ce5
   DIR parent d27c04494de59d32935865ca40915476d35b2c30
  HTML Author: sin <sin@2f30.org>
       Date:   Fri, 26 Apr 2019 11:16:21 +0100
       
       More gc work
       
       Diffstat:
         M bstorage.c                          |      51 +++++++++++++++++++------------
       
       1 file changed, 31 insertions(+), 20 deletions(-)
       ---
   DIR 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;