[master] 2c76f5b Collect all the stuff which implements objects on top of "simple" stevedores and call it "SML".
Poul-Henning Kamp
phk at FreeBSD.org
Mon Dec 14 23:36:58 CET 2015
commit 2c76f5b2152d714f42c322041d9552d73ef597c9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Dec 14 22:35:56 2015 +0000
Collect all the stuff which implements objects on top of "simple"
stevedores and call it "SML".
I bet this is going to surprise Martin :-)
diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index 99e7fb4..1f1f110 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -113,6 +113,7 @@ noinst_HEADERS = \
mgt/mgt_cli.h \
mgt/mgt_param.h \
storage/storage.h \
+ storage/storage_simple.h \
storage/storage_persistent.h \
waiter/waiter_priv.h \
waiter/mgt_waiter.h
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index 206cf03..cadd0f1 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -57,18 +57,6 @@ obj_getmethods(const struct objcore *oc)
return (oc->stobj->stevedore->methods);
}
-static struct object *
-obj_getobj(struct worker *wrk, struct objcore *oc)
-{
- const struct storeobj_methods *m;
-
- CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
- m = obj_getmethods(oc);
- AN(m->getobj);
- return (m->getobj(wrk, oc));
-}
-
/*====================================================================
* ObjIterate()
*
@@ -78,127 +66,12 @@ int
ObjIterate(struct worker *wrk, struct objcore *oc,
void *priv, objiterate_f *func)
{
- struct busyobj *bo;
- struct object *obj;
- struct storage *st;
- struct storage *checkpoint = NULL;
- ssize_t checkpoint_len = 0;
- ssize_t len = 0;
- int ret = 0;
- ssize_t ol;
- ssize_t nl;
- ssize_t sl;
- void *p;
- ssize_t l;
const struct storeobj_methods *om = obj_getmethods(oc);
- if (om->objiterator != NULL)
- return (om->objiterator(wrk, oc, priv, func));
-
- obj = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
-
- bo = HSH_RefBusy(oc);
-
- if (bo == NULL) {
- VTAILQ_FOREACH(st, &obj->list, list)
- if (func(priv, 0, st->ptr, st->len))
- return (-1);
- return (0);
- }
-
- p = NULL;
- l = 0;
-
- while (1) {
- ol = len;
- nl = VBO_waitlen(wrk, bo, ol);
- if (bo->state == BOS_FAILED) {
- ret = -1;
- break;
- }
- if (nl == ol) {
- if (bo->state == BOS_FINISHED)
- break;
- continue;
- }
- Lck_Lock(&bo->mtx);
- AZ(VTAILQ_EMPTY(&obj->list));
- if (checkpoint == NULL) {
- st = VTAILQ_FIRST(&obj->list);
- sl = 0;
- } else {
- st = checkpoint;
- sl = checkpoint_len;
- ol -= checkpoint_len;
- }
- while (st != NULL) {
- if (st->len > ol) {
- p = st->ptr + ol;
- l = st->len - ol;
- len += l;
- break;
- }
- ol -= st->len;
- assert(ol >= 0);
- nl -= st->len;
- assert(nl > 0);
- sl += st->len;
- st = VTAILQ_NEXT(st, list);
- if (VTAILQ_NEXT(st, list) != NULL) {
- checkpoint = st;
- checkpoint_len = sl;
- }
- }
- CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
- CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
- st = VTAILQ_NEXT(st, list);
- if (st != NULL && st->len == 0)
- st = NULL;
- Lck_Unlock(&bo->mtx);
- assert(l > 0 || bo->state == BOS_FINISHED);
- if (func(priv, st != NULL ? 0 : 1, p, l)) {
- ret = -1;
- break;
- }
- }
- if (oc->flags & OC_F_PASS)
- bo->abandon = 1;
- VBO_DerefBusyObj(wrk, &bo);
- return (ret);
-}
-
-/*--------------------------------------------------------------------
- */
-
-static struct storage *
-objallocwithnuke(struct worker *wrk, const struct stevedore *stv, size_t size)
-{
- struct storage *st = NULL;
- unsigned fail;
-
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
-
- if (size > cache_param->fetch_maxchunksize)
- size = cache_param->fetch_maxchunksize;
-
- assert(size <= UINT_MAX); /* field limit in struct storage */
-
- for (fail = 0; fail <= cache_param->nuke_limit; fail++) {
- /* try to allocate from it */
- AN(stv->alloc);
- st = STV_alloc(stv, size);
- if (st != NULL)
- break;
-
- /* no luck; try to free some space and keep trying */
- if (fail < cache_param->nuke_limit &&
- EXP_NukeOne(wrk, stv->lru) == -1)
- break;
- }
- CHECK_OBJ_ORNULL(st, STORAGE_MAGIC);
- return (st);
+ AN(func);
+ AN(om->objiterator);
+ return (om->objiterator(wrk, oc, priv, func));
}
/*====================================================================
@@ -213,8 +86,6 @@ objallocwithnuke(struct worker *wrk, const struct stevedore *stv, size_t size)
int
ObjGetSpace(struct worker *wrk, struct objcore *oc, ssize_t *sz, uint8_t **ptr)
{
- struct object *o;
- struct storage *st;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -222,37 +93,8 @@ ObjGetSpace(struct worker *wrk, struct objcore *oc, ssize_t *sz, uint8_t **ptr)
AN(ptr);
assert(*sz > 0);
- if (om->objgetspace != NULL)
- return (om->objgetspace(wrk, oc, sz, ptr));
-
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
-
- st = VTAILQ_LAST(&o->list, storagehead);
- if (st != NULL && st->len < st->space) {
- *sz = st->space - st->len;
- *ptr = st->ptr + st->len;
- assert (*sz > 0);
- return (1);
- }
-
- st = objallocwithnuke(wrk, oc->stobj->stevedore, *sz);
- if (st == NULL)
- return (0);
-
- if (oc->busyobj != NULL) {
- CHECK_OBJ_NOTNULL(oc->busyobj, BUSYOBJ_MAGIC);
- Lck_Lock(&oc->busyobj->mtx);
- VTAILQ_INSERT_TAIL(&o->list, st, list);
- Lck_Unlock(&oc->busyobj->mtx);
- } else {
- AN(oc->flags & (OC_F_PRIVATE));
- VTAILQ_INSERT_TAIL(&o->list, st, list);
- }
- *sz = st->space - st->len;
- assert (*sz > 0);
- *ptr = st->ptr + st->len;
- return (1);
+ AN(om->objgetspace);
+ return (om->objgetspace(wrk, oc, sz, ptr));
}
/*====================================================================
@@ -265,25 +107,13 @@ ObjGetSpace(struct worker *wrk, struct objcore *oc, ssize_t *sz, uint8_t **ptr)
void
ObjExtend(struct worker *wrk, struct objcore *oc, ssize_t l)
{
- struct object *o;
- struct storage *st;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
assert(l > 0);
- if (om->objextend != NULL) {
- om->objextend(wrk, oc, l);
- return;
- }
-
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- st = VTAILQ_LAST(&o->list, storagehead);
- CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
- assert(st->len + l <= st->space);
- st->len += l;
- o->len += l;
+ AN(om->objextend);
+ om->objextend(wrk, oc, l);
}
/*====================================================================
@@ -295,20 +125,14 @@ ObjExtend(struct worker *wrk, struct objcore *oc, ssize_t l)
uint64_t
ObjGetLen(struct worker *wrk, struct objcore *oc)
{
- struct object *o;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- if (om->objgetlen != NULL)
- return (om->objgetlen(wrk, oc));
-
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- return (o->len);
+ AN(om->objgetlen);
+ return (om->objgetlen(wrk, oc));
}
-
/*====================================================================
* ObjTrimStore()
*
@@ -319,31 +143,13 @@ ObjGetLen(struct worker *wrk, struct objcore *oc)
void
ObjTrimStore(struct worker *wrk, struct objcore *oc)
{
- const struct stevedore *stv;
- struct storage *st;
- struct object *o;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- if (om->objtrimstore != NULL) {
+ if (om->objtrimstore != NULL)
om->objtrimstore(wrk, oc);
- return;
- }
-
- stv = oc->stobj->stevedore;
- CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- st = VTAILQ_LAST(&o->list, storagehead);
- if (st == NULL)
- return;
- if (st->len == 0) {
- VTAILQ_REMOVE(&o->list, st, list);
- STV_free(stv, st);
- } else if (st->len < st->space) {
- STV_trim(stv, st, st->len, 1);
- }
+ return;
}
/*====================================================================
@@ -356,32 +162,12 @@ ObjTrimStore(struct worker *wrk, struct objcore *oc)
void
ObjSlim(struct worker *wrk, struct objcore *oc)
{
- const struct stevedore *stv;
- struct object *o;
- struct storage *st, *stn;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- if (om->objslim != NULL) {
+ if (om->objslim != NULL)
om->objslim(wrk, oc);
- return;
- }
-
- stv = oc->stobj->stevedore;
- CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
-
- if (o->esidata != NULL) {
- STV_free(stv, o->esidata);
- o->esidata = NULL;
- }
- VTAILQ_FOREACH_SAFE(st, &o->list, list, stn) {
- CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
- VTAILQ_REMOVE(&o->list, st, list);
- STV_free(stv, st);
- }
}
/*====================================================================
@@ -393,8 +179,8 @@ ObjUpdateMeta(struct worker *wrk, struct objcore *oc)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- if (m->updatemeta != NULL)
- m->updatemeta(wrk, oc);
+ if (m->objupdatemeta != NULL)
+ m->objupdatemeta(wrk, oc);
}
/*====================================================================
@@ -406,8 +192,8 @@ ObjFreeObj(struct worker *wrk, struct objcore *oc)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- AN(m->freeobj);
- m->freeobj(wrk, oc);
+ AN(m->objfree);
+ m->objfree(wrk, oc);
AZ(oc->stobj->stevedore);
}
@@ -418,8 +204,8 @@ ObjGetLRU(const struct objcore *oc)
{
const struct storeobj_methods *m = obj_getmethods(oc);
- AN(m->getlru);
- return (m->getlru(oc));
+ AN(m->objgetlru);
+ return (m->objgetlru(oc));
}
/*====================================================================
@@ -432,47 +218,12 @@ void *
ObjGetattr(struct worker *wrk, struct objcore *oc, enum obj_attr attr,
ssize_t *len)
{
- struct object *o;
- ssize_t dummy;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- if (om->objgetattr != NULL)
- return (om->objgetattr(wrk, oc, attr, len));
-
- if (len == NULL)
- len = &dummy;
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- switch (attr) {
- case OA_ESIDATA:
- if (o->esidata == NULL)
- return (NULL);
- *len = o->esidata->len;
- return (o->esidata->ptr);
- case OA_FLAGS:
- *len = sizeof o->oa_flags;
- return (o->oa_flags);
- case OA_GZIPBITS:
- *len = sizeof o->oa_gzipbits;
- return (o->oa_gzipbits);
- case OA_HEADERS:
- *len = 0; // XXX: hack
- return (o->oa_http);
- case OA_LASTMODIFIED:
- *len = sizeof o->oa_lastmodified;
- return (o->oa_lastmodified);
- case OA_VARY:
- *len = 4; // XXX: hack
- return (o->oa_vary);
- case OA_VXID:
- *len = sizeof o->oa_vxid;
- return (o->oa_vxid);
- default:
- break;
- }
- WRONG("Unsupported OBJ_ATTR");
+ AN(om->objgetattr);
+ return (om->objgetattr(wrk, oc, attr, len));
}
/*====================================================================
@@ -486,64 +237,12 @@ void *
ObjSetattr(struct worker *wrk, struct objcore *oc, enum obj_attr attr,
ssize_t len, const void *ptr)
{
- struct object *o;
- void *retval = NULL;
- struct storage *st;
const struct storeobj_methods *om = obj_getmethods(oc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- if (om->objsetattr != NULL)
- return (om->objsetattr(wrk, oc, attr, len, ptr));
-
- o = obj_getobj(wrk, oc);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- st = o->objstore;
- switch (attr) {
- case OA_ESIDATA:
- o->esidata = objallocwithnuke(wrk, oc->stobj->stevedore, len);
- if (o->esidata == NULL)
- return (NULL);
- o->esidata->len = len;
- retval = o->esidata->ptr;
- break;
- case OA_FLAGS:
- assert(len == sizeof o->oa_flags);
- retval = o->oa_flags;
- break;
- case OA_GZIPBITS:
- assert(len == sizeof o->oa_gzipbits);
- retval = o->oa_gzipbits;
- break;
- case OA_HEADERS:
- len = PRNDUP(len);
- assert(st->len + len <= st->space);
- o->oa_http = (void*)(st->ptr + st->len);
- st->len += len;
- retval = o->oa_http;
- break;
- case OA_LASTMODIFIED:
- assert(len == sizeof o->oa_lastmodified);
- retval = o->oa_lastmodified;
- break;
- case OA_VARY:
- len = PRNDUP(len);
- assert(st->len + len <= st->space);
- o->oa_vary = (void*)(st->ptr + st->len);
- st->len += len;
- retval = o->oa_vary;
- break;
- case OA_VXID:
- assert(len == sizeof o->oa_vxid);
- retval = o->oa_vxid;
- break;
- default:
- WRONG("Unsupported OBJ_ATTR");
- break;
- }
- if (ptr != NULL)
- memcpy(retval, ptr, len);
- return (retval);
+ AN(om->objsetattr);
+ return (om->objsetattr(wrk, oc, attr, len, ptr));
}
/*====================================================================
diff --git a/bin/varnishd/storage/mgt_stevedore.c b/bin/varnishd/storage/mgt_stevedore.c
index 109290f..9852ea6 100644
--- a/bin/varnishd/storage/mgt_stevedore.c
+++ b/bin/varnishd/storage/mgt_stevedore.c
@@ -183,8 +183,8 @@ STV_Config(const char *spec)
ARGV_ERR("(-s%s) too many arguments\n", stv->name);
AN(stv->alloc);
- if (stv->allocobj == NULL)
- stv->allocobj = stv_default_allocobj;
+ AN(stv->allocobj);
+ AN(stv->methods);
if (!strcmp(stv->ident, TRANSIENT_STORAGE)) {
stv->transient = 1;
diff --git a/bin/varnishd/storage/mgt_storage_persistent.c b/bin/varnishd/storage/mgt_storage_persistent.c
index 76d6436..f55d793 100644
--- a/bin/varnishd/storage/mgt_storage_persistent.c
+++ b/bin/varnishd/storage/mgt_storage_persistent.c
@@ -44,6 +44,7 @@
#include "cache/cache.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
#include "vsha256.h"
diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c
index 6c0ad0b..1029dd2 100644
--- a/bin/varnishd/storage/stevedore.c
+++ b/bin/varnishd/storage/stevedore.c
@@ -131,65 +131,6 @@ STV_alloc(const struct stevedore *stv, size_t size)
return (st);
}
-/*--------------------------------------------------------------------
- * This function is called by stevedores ->allocobj() method, which
- * very often will be stv_default_allocobj() below, to convert a slab
- * of storage into object which the stevedore can then register in its
- * internal state, before returning it to STV_NewObject().
- * As you probably guessed: All this for persistence.
- */
-
-struct object *
-STV_MkObject(const struct stevedore *stv, struct objcore *oc, void *ptr)
-{
- struct object *o;
-
- CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
- CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
-
- assert(PAOK(ptr));
-
- o = ptr;
- INIT_OBJ(o, OBJECT_MAGIC);
-
- VTAILQ_INIT(&o->list);
-
- oc->stobj->magic = STOREOBJ_MAGIC;
- oc->stobj->stevedore = stv;
- AN(stv->methods);
- oc->stobj->priv = o;
- return (o);
-}
-
-/*--------------------------------------------------------------------
- * This is the default ->allocobj() which all stevedores who do not
- * implement persistent storage can rely on.
- */
-
-int
-stv_default_allocobj(const struct stevedore *stv, struct objcore *oc,
- unsigned wsl)
-{
- struct object *o;
- struct storage *st;
- unsigned ltot;
-
- CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
- ltot = sizeof(struct object) + PRNDUP(wsl);
- st = stv->alloc(stv, ltot);
- if (st == NULL)
- return (0);
- if (st->space < ltot) {
- stv->free(st);
- return (0);
- }
- o = STV_MkObject(stv, oc, st->ptr);
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- st->len = sizeof(*o);
- o->objstore = st;
- return (1);
-}
-
/*-------------------------------------------------------------------
* Allocate storage for an object, based on the header information.
* XXX: If we know (a hint of) the length, we could allocate space
diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h
index f6636ee..a42a9cb 100644
--- a/bin/varnishd/storage/storage.h
+++ b/bin/varnishd/storage/storage.h
@@ -55,46 +55,17 @@ struct storage {
unsigned space;
};
-/* Object ------------------------------------------------------------*/
-
-VTAILQ_HEAD(storagehead, storage);
-
-struct object {
- unsigned magic;
-#define OBJECT_MAGIC 0x32851d42
- struct storage *objstore;
-
- char oa_vxid[4];
- uint8_t *oa_vary;
- uint8_t *oa_http;
- uint8_t oa_flags[1];
- char oa_gzipbits[32];
- char oa_lastmodified[8];
-
- struct storagehead list;
- ssize_t len;
-
- struct storage *esidata;
-};
-
/* Methods on objcore ------------------------------------------------*/
#ifdef VARNISH_CACHE_CHILD
-typedef void updatemeta_f(struct worker *, struct objcore *oc);
-typedef void freeobj_f(struct worker *, struct objcore *oc);
-typedef struct lru *getlru_f(const struct objcore *oc);
-
-/*
- * Stevedores can either be simple, and provide just this method:
- */
+typedef void objupdatemeta_f(struct worker *, struct objcore *oc);
+typedef void objfree_f(struct worker *, struct objcore *oc);
+typedef struct lru *objgetlru_f(const struct objcore *oc);
-typedef struct object *getobj_f(struct worker *, struct objcore *oc);
+/* This method is only used by SML (...to get to persistent) */
+typedef struct object *sml_getobj_f(struct worker *, struct objcore *oc);
-/*
- * Or the can be "complex" and provide all of these methods:
- * (Described in comments in cache_obj.c)
- */
typedef int objiterator_f(struct worker *, struct objcore *oc,
void *priv, objiterate_f *func);
typedef int objgetspace_f(struct worker *, struct objcore *,
@@ -109,11 +80,11 @@ typedef void *objsetattr_f(struct worker *, struct objcore *,
typedef uint64_t objgetlen_f(struct worker *, struct objcore *);
struct storeobj_methods {
- freeobj_f *freeobj;
- getlru_f *getlru;
- updatemeta_f *updatemeta;
+ objfree_f *objfree;
+ objgetlru_f *objgetlru;
+ objupdatemeta_f *objupdatemeta;
- getobj_f *getobj;
+ sml_getobj_f *sml_getobj;
objiterator_f *objiterator;
objgetspace_f *objgetspace;
@@ -152,10 +123,6 @@ typedef void storage_banexport_f(const struct stevedore *, const uint8_t *bans,
#include "tbl/vrt_stv_var.h"
#undef VRTSTVTYPE
-extern storage_allocobj_f stv_default_allocobj;
-
-extern const struct storeobj_methods default_oc_methods;
-
/*--------------------------------------------------------------------*/
struct stevedore {
@@ -199,8 +166,6 @@ extern struct stevedore *stv_transient;
int STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx);
uintmax_t STV_FileSize(int fd, const char *size, unsigned *granularity,
const char *ctx);
-struct object *STV_MkObject(const struct stevedore *, struct objcore *,
- void *ptr);
struct lru *LRU_Alloc(void);
void LRU_Free(struct lru *lru);
diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c
index 151f75e..c1d7992 100644
--- a/bin/varnishd/storage/storage_file.c
+++ b/bin/varnishd/storage/storage_file.c
@@ -39,6 +39,7 @@
#include "cache/cache.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
#include "vnum.h"
#include "vfil.h"
@@ -535,7 +536,8 @@ const struct stevedore smf_stevedore = {
.alloc = smf_alloc,
.trim = smf_trim,
.free = smf_free,
- .methods = &default_oc_methods,
+ .allocobj = SML_allocobj,
+ .methods = &SML_methods,
};
#ifdef INCLUDE_TEST_DRIVER
diff --git a/bin/varnishd/storage/storage_malloc.c b/bin/varnishd/storage/storage_malloc.c
index ce6b0c2..d7d4561 100644
--- a/bin/varnishd/storage/storage_malloc.c
+++ b/bin/varnishd/storage/storage_malloc.c
@@ -36,6 +36,7 @@
#include "cache/cache.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
#include "vnum.h"
@@ -251,7 +252,8 @@ const struct stevedore sma_stevedore = {
.alloc = sma_alloc,
.free = sma_free,
.trim = sma_trim,
- .methods = &default_oc_methods,
+ .allocobj = SML_allocobj,
+ .methods = &SML_methods,
.var_free_space = sma_free_space,
.var_used_space = sma_used_space,
};
diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c
index b87fece..a71f150 100644
--- a/bin/varnishd/storage/storage_persistent.c
+++ b/bin/varnishd/storage/storage_persistent.c
@@ -44,6 +44,7 @@
#include "cache/cache.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
#include "hash/hash_slinger.h"
#include "vcli.h"
@@ -53,6 +54,8 @@
#include "storage/storage_persistent.h"
+static struct storeobj_methods smp_oc_realmethods;
+
/*--------------------------------------------------------------------*/
/*
@@ -526,7 +529,7 @@ smp_allocobj(const struct stevedore *stv, struct objcore *oc, unsigned wsl)
assert(st->space >= ltot);
- o = STV_MkObject(stv, oc, st->ptr);
+ o = SML_MkObject(stv, oc, st->ptr);
AN(oc->stobj->stevedore);
assert(oc->stobj->stevedore == stv);
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
@@ -592,7 +595,7 @@ const struct stevedore smp_stevedore = {
.signal_close = smp_signal_close,
.baninfo = smp_baninfo,
.banexport = smp_banexport,
- .methods = &smp_oc_methods,
+ .methods = &smp_oc_realmethods,
};
/*--------------------------------------------------------------------
@@ -682,6 +685,11 @@ void
SMP_Init(void)
{
CLI_AddFuncs(debug_cmds);
+ smp_oc_realmethods = SML_methods;
+ smp_oc_realmethods.sml_getobj = smp_oc_methods.sml_getobj;
+ smp_oc_realmethods.objupdatemeta = smp_oc_methods.objupdatemeta;
+ smp_oc_realmethods.objfree = smp_oc_methods.objfree;
+ smp_oc_realmethods.objgetlru = smp_oc_methods.objgetlru;
}
/*--------------------------------------------------------------------
diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c
index ab604d8..8b370c6 100644
--- a/bin/varnishd/storage/storage_persistent_silo.c
+++ b/bin/varnishd/storage/storage_persistent_silo.c
@@ -40,6 +40,7 @@
#include "cache/cache.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
#include "hash/hash_slinger.h"
#include "vsha256.h"
@@ -387,7 +388,7 @@ smp_loaded_st(const struct smp_sc *sc, const struct smp_seg *sg,
*/
static struct object *
-smp_oc_getobj(struct worker *wrk, struct objcore *oc)
+smp_oc_sml_getobj(struct worker *wrk, struct objcore *oc)
{
struct object *o;
struct smp_seg *sg;
@@ -401,7 +402,7 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc)
AN(oc->stobj->stevedore);
/* Some calls are direct, but they should match anyway */
- assert(oc->stobj->stevedore->methods->getobj == smp_oc_getobj);
+ assert(oc->stobj->stevedore->methods->sml_getobj == smp_oc_sml_getobj);
CAST_OBJ_NOTNULL(sg, oc->stobj->priv, SMP_SEG_MAGIC);
so = smp_find_so(sg, oc->stobj->priv2);
@@ -455,7 +456,7 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc)
}
static void
-smp_oc_updatemeta(struct worker *wrk, struct objcore *oc)
+smp_oc_objupdatemeta(struct worker *wrk, struct objcore *oc)
{
struct object *o;
struct smp_seg *sg;
@@ -463,7 +464,7 @@ smp_oc_updatemeta(struct worker *wrk, struct objcore *oc)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
- o = smp_oc_getobj(wrk, oc);
+ o = smp_oc_sml_getobj(wrk, oc);
AN(o);
CAST_OBJ_NOTNULL(sg, oc->stobj->priv, SMP_SEG_MAGIC);
@@ -482,8 +483,8 @@ smp_oc_updatemeta(struct worker *wrk, struct objcore *oc)
}
}
-static void __match_proto__(freeobj_f)
-smp_oc_freeobj(struct worker *wrk, struct objcore *oc)
+static void __match_proto__(objfree_f)
+smp_oc_objfree(struct worker *wrk, struct objcore *oc)
{
struct smp_seg *sg;
struct smp_object *so;
@@ -516,8 +517,8 @@ smp_oc_freeobj(struct worker *wrk, struct objcore *oc)
* Find the per-segment lru list for this object
*/
-static struct lru * __match_proto__(getlru_f)
-smp_oc_getlru(const struct objcore *oc)
+static struct lru * __match_proto__(objgetlru_f)
+smp_oc_objgetlru(const struct objcore *oc)
{
struct smp_seg *sg;
@@ -526,10 +527,10 @@ smp_oc_getlru(const struct objcore *oc)
}
const struct storeobj_methods smp_oc_methods = {
- .getobj = smp_oc_getobj,
- .updatemeta = smp_oc_updatemeta,
- .freeobj = smp_oc_freeobj,
- .getlru = smp_oc_getlru,
+ .sml_getobj = smp_oc_sml_getobj,
+ .objupdatemeta = smp_oc_objupdatemeta,
+ .objfree = smp_oc_objfree,
+ .objgetlru = smp_oc_objgetlru,
};
/*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/storage/storage_simple.c b/bin/varnishd/storage/storage_simple.c
index 141b413..b8eedec 100644
--- a/bin/varnishd/storage/storage_simple.c
+++ b/bin/varnishd/storage/storage_simple.c
@@ -33,27 +33,92 @@
#include <stdlib.h>
#include "cache/cache.h"
+#include "hash/hash_slinger.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
+
+/*--------------------------------------------------------------------
+ * This function is called by stevedores ->allocobj() method, which
+ * very often will be SML_allocobj() below, to convert a slab
+ * of storage into object which the stevedore can then register in its
+ * internal state, before returning it to STV_NewObject().
+ * As you probably guessed: All this for persistence.
+ */
+
+struct object *
+SML_MkObject(const struct stevedore *stv, struct objcore *oc, void *ptr)
+{
+ struct object *o;
+
+ CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
+ CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+
+ assert(PAOK(ptr));
+
+ o = ptr;
+ INIT_OBJ(o, OBJECT_MAGIC);
+
+ VTAILQ_INIT(&o->list);
+
+ oc->stobj->magic = STOREOBJ_MAGIC;
+ oc->stobj->stevedore = stv;
+ AN(stv->methods);
+ oc->stobj->priv = o;
+ return (o);
+}
+
+/*--------------------------------------------------------------------
+ * This is the default ->allocobj() which all stevedores who do not
+ * implement persistent storage can rely on.
+ */
+
+int
+SML_allocobj(const struct stevedore *stv, struct objcore *oc,
+ unsigned wsl)
+{
+ struct object *o;
+ struct storage *st;
+ unsigned ltot;
+
+ CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+ ltot = sizeof(struct object) + PRNDUP(wsl);
+ st = stv->alloc(stv, ltot);
+ if (st == NULL)
+ return (0);
+ if (st->space < ltot) {
+ stv->free(st);
+ return (0);
+ }
+ o = SML_MkObject(stv, oc, st->ptr);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ st->len = sizeof(*o);
+ o->objstore = st;
+ return (1);
+}
/*---------------------------------------------------------------------
*/
-static struct object * __match_proto__(getobj_f)
-default_oc_getobj(struct worker *wrk, struct objcore *oc)
+static struct object *
+getobj(struct worker *wrk, struct objcore *oc)
{
+ const struct storeobj_methods *m;
struct object *o;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+ m = oc->stobj->stevedore->methods;
+ if (m->sml_getobj != NULL)
+ return (m->sml_getobj(wrk, oc));
if (oc->stobj->priv == NULL)
return (NULL);
CAST_OBJ_NOTNULL(o, oc->stobj->priv, OBJECT_MAGIC);
return (o);
}
-static void __match_proto__(freeobj_f)
-default_oc_freeobj(struct worker *wrk, struct objcore *oc)
+static void __match_proto__(objfree_f)
+sml_objfree(struct worker *wrk, struct objcore *oc)
{
struct object *o;
@@ -71,8 +136,8 @@ default_oc_freeobj(struct worker *wrk, struct objcore *oc)
wrk->stats->n_object--;
}
-static struct lru * __match_proto__(getlru_f)
-default_oc_getlru(const struct objcore *oc)
+static struct lru * __match_proto__(objgetlru_f)
+sml_objgetlru(const struct objcore *oc)
{
const struct stevedore *stv;
@@ -81,8 +146,363 @@ default_oc_getlru(const struct objcore *oc)
return (stv->lru);
}
-const struct storeobj_methods default_oc_methods = {
- .getobj = default_oc_getobj,
- .freeobj = default_oc_freeobj,
- .getlru = default_oc_getlru,
+static int __match_proto__(objiterate_f)
+sml_iterator(struct worker *wrk, struct objcore *oc,
+ void *priv, objiterate_f *func)
+{
+ struct busyobj *bo;
+ struct object *obj;
+ struct storage *st;
+ struct storage *checkpoint = NULL;
+ ssize_t checkpoint_len = 0;
+ ssize_t len = 0;
+ int ret = 0;
+ ssize_t ol;
+ ssize_t nl;
+ ssize_t sl;
+ void *p;
+ ssize_t l;
+
+ obj = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
+
+ bo = HSH_RefBusy(oc);
+
+ if (bo == NULL) {
+ VTAILQ_FOREACH(st, &obj->list, list)
+ if (func(priv, 0, st->ptr, st->len))
+ return (-1);
+ return (0);
+ }
+
+ p = NULL;
+ l = 0;
+
+ while (1) {
+ ol = len;
+ nl = VBO_waitlen(wrk, bo, ol);
+ if (bo->state == BOS_FAILED) {
+ ret = -1;
+ break;
+ }
+ if (nl == ol) {
+ if (bo->state == BOS_FINISHED)
+ break;
+ continue;
+ }
+ Lck_Lock(&bo->mtx);
+ AZ(VTAILQ_EMPTY(&obj->list));
+ if (checkpoint == NULL) {
+ st = VTAILQ_FIRST(&obj->list);
+ sl = 0;
+ } else {
+ st = checkpoint;
+ sl = checkpoint_len;
+ ol -= checkpoint_len;
+ }
+ while (st != NULL) {
+ if (st->len > ol) {
+ p = st->ptr + ol;
+ l = st->len - ol;
+ len += l;
+ break;
+ }
+ ol -= st->len;
+ assert(ol >= 0);
+ nl -= st->len;
+ assert(nl > 0);
+ sl += st->len;
+ st = VTAILQ_NEXT(st, list);
+ if (VTAILQ_NEXT(st, list) != NULL) {
+ checkpoint = st;
+ checkpoint_len = sl;
+ }
+ }
+ CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
+ CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
+ st = VTAILQ_NEXT(st, list);
+ if (st != NULL && st->len == 0)
+ st = NULL;
+ Lck_Unlock(&bo->mtx);
+ assert(l > 0 || bo->state == BOS_FINISHED);
+ if (func(priv, st != NULL ? 0 : 1, p, l)) {
+ ret = -1;
+ break;
+ }
+ }
+ if (oc->flags & OC_F_PASS)
+ bo->abandon = 1;
+ VBO_DerefBusyObj(wrk, &bo);
+ return (ret);
+}
+
+/*--------------------------------------------------------------------
+ */
+
+static struct storage *
+objallocwithnuke(struct worker *wrk, const struct stevedore *stv, size_t size)
+{
+ struct storage *st = NULL;
+ unsigned fail;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+ CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
+
+ if (size > cache_param->fetch_maxchunksize)
+ size = cache_param->fetch_maxchunksize;
+
+ assert(size <= UINT_MAX); /* field limit in struct storage */
+
+ for (fail = 0; fail <= cache_param->nuke_limit; fail++) {
+ /* try to allocate from it */
+ AN(stv->alloc);
+ st = STV_alloc(stv, size);
+ if (st != NULL)
+ break;
+
+ /* no luck; try to free some space and keep trying */
+ if (fail < cache_param->nuke_limit &&
+ EXP_NukeOne(wrk, stv->lru) == -1)
+ break;
+ }
+ CHECK_OBJ_ORNULL(st, STORAGE_MAGIC);
+ return (st);
+}
+
+static int __match_proto__(objgetspace_f)
+sml_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz,
+ uint8_t **ptr)
+{
+ struct object *o;
+ struct storage *st;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+ AN(sz);
+ AN(ptr);
+ assert(*sz > 0);
+
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+
+ st = VTAILQ_LAST(&o->list, storagehead);
+ if (st != NULL && st->len < st->space) {
+ *sz = st->space - st->len;
+ *ptr = st->ptr + st->len;
+ assert (*sz > 0);
+ return (1);
+ }
+
+ st = objallocwithnuke(wrk, oc->stobj->stevedore, *sz);
+ if (st == NULL)
+ return (0);
+
+ if (oc->busyobj != NULL) {
+ CHECK_OBJ_NOTNULL(oc->busyobj, BUSYOBJ_MAGIC);
+ Lck_Lock(&oc->busyobj->mtx);
+ VTAILQ_INSERT_TAIL(&o->list, st, list);
+ Lck_Unlock(&oc->busyobj->mtx);
+ } else {
+ AN(oc->flags & (OC_F_PRIVATE));
+ VTAILQ_INSERT_TAIL(&o->list, st, list);
+ }
+ *sz = st->space - st->len;
+ assert (*sz > 0);
+ *ptr = st->ptr + st->len;
+ return (1);
+}
+
+static void __match_proto__(objextend_f)
+sml_extend(struct worker *wrk, struct objcore *oc, ssize_t l)
+{
+ struct object *o;
+ struct storage *st;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+ assert(l > 0);
+
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ st = VTAILQ_LAST(&o->list, storagehead);
+ CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
+ assert(st->len + l <= st->space);
+ st->len += l;
+ o->len += l;
+}
+
+static uint64_t __match_proto__(objgetlen_f)
+sml_getlen(struct worker *wrk, struct objcore *oc)
+{
+ struct object *o;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ return (o->len);
+}
+
+static void __match_proto__(objtrimstore_f)
+sml_trimstore(struct worker *wrk, struct objcore *oc)
+{
+ const struct stevedore *stv;
+ struct storage *st;
+ struct object *o;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+
+ stv = oc->stobj->stevedore;
+ CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ st = VTAILQ_LAST(&o->list, storagehead);
+ if (st == NULL)
+ return;
+ if (st->len == 0) {
+ VTAILQ_REMOVE(&o->list, st, list);
+ STV_free(stv, st);
+ } else if (st->len < st->space) {
+ STV_trim(stv, st, st->len, 1);
+ }
+}
+
+static void __match_proto__(objslim_f)
+sml_slim(struct worker *wrk, struct objcore *oc)
+{
+ const struct stevedore *stv;
+ struct object *o;
+ struct storage *st, *stn;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+
+ stv = oc->stobj->stevedore;
+ CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+
+ if (o->esidata != NULL) {
+ STV_free(stv, o->esidata);
+ o->esidata = NULL;
+ }
+ VTAILQ_FOREACH_SAFE(st, &o->list, list, stn) {
+ CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
+ VTAILQ_REMOVE(&o->list, st, list);
+ STV_free(stv, st);
+ }
+}
+
+static void * __match_proto__(objgetattr_f)
+sml_getattr(struct worker *wrk, struct objcore *oc, enum obj_attr attr,
+ ssize_t *len)
+{
+ struct object *o;
+ ssize_t dummy;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+
+ if (len == NULL)
+ len = &dummy;
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ switch (attr) {
+ case OA_ESIDATA:
+ if (o->esidata == NULL)
+ return (NULL);
+ *len = o->esidata->len;
+ return (o->esidata->ptr);
+ case OA_FLAGS:
+ *len = sizeof o->oa_flags;
+ return (o->oa_flags);
+ case OA_GZIPBITS:
+ *len = sizeof o->oa_gzipbits;
+ return (o->oa_gzipbits);
+ case OA_HEADERS:
+ *len = 0; // XXX: hack
+ return (o->oa_http);
+ case OA_LASTMODIFIED:
+ *len = sizeof o->oa_lastmodified;
+ return (o->oa_lastmodified);
+ case OA_VARY:
+ *len = 4; // XXX: hack
+ return (o->oa_vary);
+ case OA_VXID:
+ *len = sizeof o->oa_vxid;
+ return (o->oa_vxid);
+ default:
+ break;
+ }
+ WRONG("Unsupported OBJ_ATTR");
+}
+
+static void * __match_proto__(objsetattr_f)
+sml_setattr(struct worker *wrk, struct objcore *oc, enum obj_attr attr,
+ ssize_t len, const void *ptr)
+{
+ struct object *o;
+ void *retval = NULL;
+ struct storage *st;
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+
+ o = getobj(wrk, oc);
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ st = o->objstore;
+ switch (attr) {
+ case OA_ESIDATA:
+ o->esidata = objallocwithnuke(wrk, oc->stobj->stevedore, len);
+ if (o->esidata == NULL)
+ return (NULL);
+ o->esidata->len = len;
+ retval = o->esidata->ptr;
+ break;
+ case OA_FLAGS:
+ assert(len == sizeof o->oa_flags);
+ retval = o->oa_flags;
+ break;
+ case OA_GZIPBITS:
+ assert(len == sizeof o->oa_gzipbits);
+ retval = o->oa_gzipbits;
+ break;
+ case OA_HEADERS:
+ len = PRNDUP(len);
+ assert(st->len + len <= st->space);
+ o->oa_http = (void*)(st->ptr + st->len);
+ st->len += len;
+ retval = o->oa_http;
+ break;
+ case OA_LASTMODIFIED:
+ assert(len == sizeof o->oa_lastmodified);
+ retval = o->oa_lastmodified;
+ break;
+ case OA_VARY:
+ len = PRNDUP(len);
+ assert(st->len + len <= st->space);
+ o->oa_vary = (void*)(st->ptr + st->len);
+ st->len += len;
+ retval = o->oa_vary;
+ break;
+ case OA_VXID:
+ assert(len == sizeof o->oa_vxid);
+ retval = o->oa_vxid;
+ break;
+ default:
+ WRONG("Unsupported OBJ_ATTR");
+ break;
+ }
+ if (ptr != NULL)
+ memcpy(retval, ptr, len);
+ return (retval);
+}
+
+
+const struct storeobj_methods SML_methods = {
+ .objfree = sml_objfree,
+ .objgetlru = sml_objgetlru,
+ .objiterator = sml_iterator,
+ .objgetspace = sml_getspace,
+ .objextend = sml_extend,
+ .objgetlen = sml_getlen,
+ .objtrimstore = sml_trimstore,
+ .objslim = sml_slim,
+ .objgetattr = sml_getattr,
+ .objsetattr = sml_setattr,
};
diff --git a/bin/varnishd/storage/storage_simple.h b/bin/varnishd/storage/storage_simple.h
new file mode 100644
index 0000000..b199e7a
--- /dev/null
+++ b/bin/varnishd/storage/storage_simple.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2011 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * SML is a set of methods for simple stevedores which just do simple
+ * memory allocation and leave all the high-level stuff to SML.
+ *
+ */
+
+/* Object ------------------------------------------------------------*/
+
+VTAILQ_HEAD(storagehead, storage);
+
+struct object {
+ unsigned magic;
+#define OBJECT_MAGIC 0x32851d42
+ struct storage *objstore;
+
+ char oa_vxid[4];
+ uint8_t *oa_vary;
+ uint8_t *oa_http;
+ uint8_t oa_flags[1];
+ char oa_gzipbits[32];
+ char oa_lastmodified[8];
+
+ struct storagehead list;
+ ssize_t len;
+
+ struct storage *esidata;
+};
+
+extern const struct storeobj_methods SML_methods;
+
+struct object *SML_MkObject(const struct stevedore *, struct objcore *,
+ void *ptr);
+
+storage_allocobj_f SML_allocobj;
+
diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c
index eb194aa..aa268ec 100644
--- a/bin/varnishd/storage/storage_umem.c
+++ b/bin/varnishd/storage/storage_umem.c
@@ -41,6 +41,7 @@
#include "cache/cache.h"
#include "storage/storage.h"
+#include "storage/storage_simple.h"
static size_t smu_max = SIZE_MAX;
static MTX smu_mtx;
@@ -161,7 +162,8 @@ const struct stevedore smu_stevedore = {
.alloc = smu_alloc,
.free = smu_free,
.trim = smu_trim,
- .methods = &default_oc_methods,
+ .allocobj = SML_allocobj,
+ .methods = &SML_methods,
};
#endif /* HAVE_UMEM_H */
More information about the varnish-commit
mailing list