Store a reference count in the block descriptor - 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 f91758f2fd077c0288c664572559d01c91ba54fd
 (DIR) parent dfdce10112dbafc512a9b4d69a4f380372532422
 (HTM) Author: sin <sin@2f30.org>
       Date:   Thu, 25 Apr 2019 21:36:29 +0100
       
       Store a reference count in the block descriptor
       
       Diffstat:
         M bstorage.c                          |      22 +++++++++++++++++++---
       
       1 file changed, 19 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/bstorage.c b/bstorage.c
       @@ -42,7 +42,7 @@
        #define BDTYPE                0x100
        
        #define BHDRSIZE        (NBHDRMAGIC + 8 + 8)
       -#define BDSIZE                (8 + 8 + 8 + (MDSIZE))
       +#define BDSIZE                (8 + 8 + 8 + 8 + (MDSIZE))
        
        extern int pack(unsigned char *dst, char *fmt, ...);
        extern int unpack(unsigned char *src, char *fmt, ...);
       @@ -77,6 +77,7 @@ struct bd {
                uint64_t type;
                uint64_t offset;
                uint64_t size;
       +        uint64_t refcnt;
                unsigned char md[MDSIZE];
                RB_ENTRY(bd) entry;
        };
       @@ -218,11 +219,12 @@ unpackbd(int fd, struct bd *bd)
                if (xread(fd, buf, sizeof(buf)) != sizeof(buf))
                        return -1;
        
       -        snprintf(fmt, sizeof(fmt), "qqq'%d", MDSIZE);
       +        snprintf(fmt, sizeof(fmt), "qqqq'%d", MDSIZE);
                n = unpack(buf, fmt,
                           &bd->type,
                           &bd->offset,
                           &bd->size,
       +                   &bd->refcnt,
                           bd->md);
        
                assert(n == BDSIZE);
       @@ -237,11 +239,12 @@ packbd(int fd, struct bd *bd)
                char fmt[BUFSIZ];
                int n;
        
       -        snprintf(fmt, sizeof(fmt), "qqq'%d", MDSIZE);
       +        snprintf(fmt, sizeof(fmt), "qqqq'%d", MDSIZE);
                n = pack(buf, fmt,
                         bd->type,
                         bd->offset,
                         bd->size,
       +                 bd->refcnt,
                         bd->md);
        
                assert(n == BDSIZE);
       @@ -457,6 +460,18 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
        
                bd = RB_FIND(bdcache, &sctx->bdcache, &key);
                if (bd != NULL) {
       +                off_t bdoffs;
       +
       +                bdoffs = bd->offset - BDSIZE;
       +                if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0)
       +                        return -1;
       +
       +                bd->refcnt++;
       +                if (packbd(sctx->fd, bd) < 0) {
       +                        bd->refcnt--;
       +                        return -1;
       +                }
       +
                        memcpy(md, bd->md, MDSIZE);
                        return 0;
                }
       @@ -471,6 +486,7 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                bd->type = BDTYPE;
                bd->offset = offs + BDSIZE;
                bd->size = n;
       +        bd->refcnt = 1;
                memcpy(bd->md, key.md, MDSIZE);
        
                if (packbd(sctx->fd, bd) < 0) {