[master] 2babc68 Map whole VSM clusters instead of their segments
Nils Goroll
nils.goroll at uplex.de
Fri Jan 19 08:48:08 UTC 2018
commit 2babc68abe967715b51aa526f14417f1c081cc05
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Thu Jan 18 12:45:18 2018 +0100
Map whole VSM clusters instead of their segments
Merges #2545
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index b63684f..f19468e 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -79,8 +79,10 @@ struct vsm_seg {
unsigned flags;
#define VSM_FLAG_MARKSCAN (1U<<0)
#define VSM_FLAG_STALE (1U<<1)
+#define VSM_FLAG_CLUSTER (1U<<2)
VTAILQ_ENTRY(vsm_seg) list;
struct vsm_set *set;
+ struct vsm_seg *cluster;
char **av;
int refs;
void *s;
@@ -96,6 +98,7 @@ struct vsm_set {
const char *dname;
VTAILQ_HEAD(,vsm_seg) segs;
VTAILQ_HEAD(,vsm_seg) stale;
+ VTAILQ_HEAD(,vsm_seg) clusters;
int dfd;
struct stat dst;
@@ -158,10 +161,18 @@ vsm_mapseg(struct vsm *vd, struct vsm_seg *vg)
CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC);
+ if (vg->s != NULL)
+ return (0);
+
ps = getpagesize();
+
of = strtoul(vg->av[2], NULL, 10);
off = RDN2(of, ps);
+ if (vg->flags & VSM_FLAG_CLUSTER)
+ assert(of == 0);
+ assert(vg->cluster == NULL);
+
sz = strtoul(vg->av[3], NULL, 10);
assert(sz > 0);
assert(of >= off);
@@ -217,11 +228,13 @@ vsm_delseg(struct vsm_seg *vg)
CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC);
- if (vg->b != NULL)
+ if (vg->s != NULL)
vsm_unmapseg(vg);
if (vg->flags & VSM_FLAG_STALE)
VTAILQ_REMOVE(&vg->set->stale, vg, list);
+ else if (vg->flags & VSM_FLAG_CLUSTER)
+ VTAILQ_REMOVE(&vg->set->clusters, vg, list);
else
VTAILQ_REMOVE(&vg->set->segs, vg, list);
VAV_Free(vg->av);
@@ -239,6 +252,7 @@ vsm_newset(const char *dirname)
AN(vs);
VTAILQ_INIT(&vs->segs);
VTAILQ_INIT(&vs->stale);
+ VTAILQ_INIT(&vs->clusters);
vs->dname = dirname;
vs->dfd = vs->fd = -1;
return (vs);
@@ -260,6 +274,8 @@ vsm_delset(struct vsm_set **p)
vsm_delseg(VTAILQ_FIRST(&vs->stale));
while (!VTAILQ_EMPTY(&vs->segs))
vsm_delseg(VTAILQ_FIRST(&vs->segs));
+ while (!VTAILQ_EMPTY(&vs->clusters))
+ vsm_delseg(VTAILQ_FIRST(&vs->clusters));
FREE_OBJ(vs);
}
@@ -387,6 +403,21 @@ vsm_cmp_av(char * const *a1, char * const *a2)
}
}
+static struct vsm_seg *
+vsm_findcluster(const struct vsm_seg *vga)
+{
+ const struct vsm_set *vs = vga->set;
+ struct vsm_seg *vg;
+ AN(vs);
+ AN(vga->av[1]);
+ VTAILQ_FOREACH(vg, &vs->clusters, list) {
+ AN(vg->av[1]);
+ if (! strcmp(vga->av[1], vg->av[1]))
+ return (vg);
+ }
+ return (NULL);
+}
+
static unsigned
vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
{
@@ -518,10 +549,6 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
VAV_Free(av);
break;
}
- if (ac == 4) {
- VAV_Free(av);
- continue;
- }
if (vg == NULL) {
ALLOC_OBJ(vg2, VSM_SEG_MAGIC);
@@ -530,7 +557,13 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
vg2->set = vs;
vg2->flags = VSM_FLAG_MARKSCAN;
vg2->serial = ++vd->serial;
- VTAILQ_INSERT_TAIL(&vs->segs, vg2, list);
+ if (ac == 4) {
+ vg2->flags |= VSM_FLAG_CLUSTER;
+ VTAILQ_INSERT_TAIL(&vs->clusters, vg2, list);
+ } else {
+ VTAILQ_INSERT_TAIL(&vs->segs, vg2, list);
+ vg2->cluster = vsm_findcluster(vg2);
+ }
continue;
}
@@ -738,7 +771,8 @@ VSM__itern(struct vsm *vd, struct vsm_fantom *vf)
int
VSM_Map(struct vsm *vd, struct vsm_fantom *vf)
{
- struct vsm_seg *vg;
+ struct vsm_seg *vg, *vgc;
+ size_t of, sz;
int r;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
@@ -761,10 +795,39 @@ VSM_Map(struct vsm *vd, struct vsm_fantom *vf)
return (0);
}
- r = vsm_mapseg(vd, vg);
+ assert(vg->refs == 0);
+
+ vgc = vg->cluster;
+ if (vgc == NULL) {
+ r = vsm_mapseg(vd, vg);
+ if (r)
+ return (r);
+ vf->b = vg->b;
+ vf->e = vg->e;
+
+ vg->refs++;
+
+ return (0);
+ }
+
+ assert(vgc->flags & VSM_FLAG_CLUSTER);
+ assert(vg->s == NULL);
+ assert(vg->sz == 0);
+
+ r = vsm_mapseg(vd, vgc);
if (r)
return (r);
+ vgc->refs++;
+
+ of = strtoul(vg->av[2], NULL, 10);
+ sz = strtoul(vg->av[3], NULL, 10);
+ assert(sz > 0);
+
+ assert(vgc->sz >= of + sz);
+ assert(vgc->s == vgc->b);
+ vg->b = (char *)vgc->b + of;
+ vg->e = (char *)vg->b + sz;
vf->b = vg->b;
vf->e = vg->e;
@@ -794,7 +857,17 @@ VSM_Unmap(struct vsm *vd, struct vsm_fantom *vf)
vf->e = NULL;
if (vg->refs > 0)
return(0);
- vsm_unmapseg(vg);
+
+ if (vg->cluster) {
+ assert(vg->s == NULL);
+ assert(vg->sz == 0);
+ assert(vg->cluster->refs > 0);
+ if (--vg->cluster->refs == 0)
+ vsm_unmapseg(vg->cluster);
+ vg->b = vg->e = NULL;
+ } else {
+ vsm_unmapseg(vg);
+ }
if (vg->flags & VSM_FLAG_STALE)
vsm_delseg(vg);
return (0);
More information about the varnish-commit
mailing list