commit 6699070ee14aa0fc3a48c52e0a146f6946e39ce5
parent d27c04494de59d32935865ca40915476d35b2c30
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(-)
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;