commit f91758f2fd077c0288c664572559d01c91ba54fd
parent dfdce10112dbafc512a9b4d69a4f380372532422
Author: sin <sin@2f30.org>
Date: Thu, 25 Apr 2019 21:36:29 +0100
Store a reference count in the block descriptor
Diffstat:
1 file changed, 19 insertions(+), 3 deletions(-)
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) {