Implement block gc operation - dedup - deduplicating backup program
 (HTM) git clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d27c04494de59d32935865ca40915476d35b2c30
 (DIR) parent 8f5a4daf24872ef4bab13dc180ed4e693b4c5c8a
 (HTM) Author: sin <sin@2f30.org>
       Date:   Fri, 26 Apr 2019 11:07:20 +0100
       
       Implement block gc operation
       
       Diffstat:
         M TODO                                |       2 +-
         M bcompress.c                         |      10 ++++++++++
         M block.c                             |      12 ++++++++++++
         M block.h                             |       2 ++
         M bstorage.c                          |      25 +++++++++++++++++++++++++
       
       5 files changed, 50 insertions(+), 1 deletion(-)
       ---
 (DIR) 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)
 (DIR) 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();
 (DIR) 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;
 (DIR) 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);
 (DIR) 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.