commit d27c04494de59d32935865ca40915476d35b2c30
parent 8f5a4daf24872ef4bab13dc180ed4e693b4c5c8a
Author: sin <sin@2f30.org>
Date: Fri, 26 Apr 2019 11:07:20 +0100
Implement block gc operation
Diffstat:
5 files changed, 50 insertions(+), 1 deletion(-)
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)
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();
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;
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);
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.