From fb355e4200fcf98f36a4f3e1fbeb1e16b4761ee6 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 13 Sep 2024 09:38:07 +0000 Subject: Push what I have for now Signed-off-by: Laurent Bercot --- package/deps.mak | 15 +++++++------- src/cache/query.c | 4 ++-- src/include/shibari/dcache.h | 8 ++++++-- src/libdcache/dcache-internal.h | 5 +++++ src/libdcache/dcache_add.c | 27 +++++++++++++++++++++++++ src/libdcache/dcache_add_data.c | 2 +- src/libdcache/dcache_clean_expired.c | 2 +- src/libdcache/dcache_free.c | 8 ++++---- src/libdcache/dcache_get_data.c | 1 + src/libdcache/dcache_load.c | 39 +++++++++++++++++++++++++----------- src/libdcache/dcache_node_add.c | 21 +++++++++++++++++++ src/libdcache/dcache_node_new.c | 22 +++++++++----------- src/libdcache/dcache_save.c | 16 +++++++++------ src/libdcache/dcache_search.c | 28 ++++++++++++++++++++++++++ src/libdcache/dcache_searchnode.c | 28 -------------------------- src/libdcache/deps-lib/dcache | 4 ++++ 16 files changed, 154 insertions(+), 76 deletions(-) create mode 100644 src/libdcache/dcache_add.c create mode 100644 src/libdcache/dcache_node_add.c create mode 100644 src/libdcache/dcache_search.c delete mode 100644 src/libdcache/dcache_searchnode.c diff --git a/package/deps.mak b/package/deps.mak index a9813a3..71778da 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -35,13 +35,14 @@ src/config/util.o src/config/util.lo: src/config/util.c src/config/shibari-cache src/libdcache/dcache_add_data.o src/libdcache/dcache_add_data.lo: src/libdcache/dcache_add_data.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h src/libdcache/dcache_clean_expired.o src/libdcache/dcache_clean_expired.lo: src/libdcache/dcache_clean_expired.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h src/libdcache/dcache_delete.o src/libdcache/dcache_delete.lo: src/libdcache/dcache_delete.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h -src/libdcache/dcache_free.o src/libdcache/dcache_free.lo: src/libdcache/dcache_free.c src/include/shibari/dcache.h -src/libdcache/dcache_get_data.o src/libdcache/dcache_get_data.lo: src/libdcache/dcache_get_data.c src/include/shibari/dcache.h +src/libdcache/dcache_free.o src/libdcache/dcache_free.lo: src/libdcache/dcache_free.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h +src/libdcache/dcache_get_data.o src/libdcache/dcache_get_data.lo: src/libdcache/dcache_get_data.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h src/libdcache/dcache_init.o src/libdcache/dcache_init.lo: src/libdcache/dcache_init.c src/include/shibari/dcache.h -src/libdcache/dcache_load.o src/libdcache/dcache_load.lo: src/libdcache/dcache_load.c src/include/shibari/dcache.h +src/libdcache/dcache_load.o src/libdcache/dcache_load.lo: src/libdcache/dcache_load.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h +src/libdcache/dcache_node_add.o src/libdcache/dcache_node_add.lo: src/libdcache/dcache_node_add.c src/libdcache/dcache-internal.h src/libdcache/dcache_node_new.o src/libdcache/dcache_node_new.lo: src/libdcache/dcache_node_new.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h src/libdcache/dcache_save.o src/libdcache/dcache_save.lo: src/libdcache/dcache_save.c src/include/shibari/dcache.h -src/libdcache/dcache_searchnode.o src/libdcache/dcache_searchnode.lo: src/libdcache/dcache_searchnode.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h +src/libdcache/dcache_search.o src/libdcache/dcache_search.lo: src/libdcache/dcache_search.c src/libdcache/dcache-internal.h src/include/shibari/dcache.h src/server/shibari-server-tcp.o src/server/shibari-server-tcp.lo: src/server/shibari-server-tcp.c src/include/shibari/common.h src/include/shibari/server.h src/server/shibari-server-udp.o src/server/shibari-server-udp.lo: src/server/shibari-server-udp.c src/include/shibari/common.h src/include/shibari/server.h src/server/shibari_packet_add_glue.o src/server/shibari_packet_add_glue.lo: src/server/shibari_packet_add_glue.c src/include/shibari/constants.h src/include/shibari/packet.h src/include/shibari/tdb.h src/include/shibari/util.h @@ -69,12 +70,12 @@ libshibari-common.so.xyzzy: src/common/shibari_log_answer.lo src/common/shibari_ shibari-cache-config: EXTRA_LIBS := -ls6dns -lskarnet shibari-cache-config: src/config/shibari-cache-config.o src/config/repo.o src/config/defaults.o src/config/lexparse.o src/config/util.o ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) -libdcache.a.xyzzy: src/libdcache/dcache_add_data.o src/libdcache/dcache_clean_expired.o src/libdcache/dcache_delete.o src/libdcache/dcache_free.o src/libdcache/dcache_init.o src/libdcache/dcache_load.o src/libdcache/dcache_save.o +libdcache.a.xyzzy: src/libdcache/dcache_add_data.o src/libdcache/dcache_clean_expired.o src/libdcache/dcache_delete.o src/libdcache/dcache_free.o src/libdcache/dcache_get_data.o src/libdcache/dcache_init.o src/libdcache/dcache_load.o src/libdcache/dcache_node_add.o src/libdcache/dcache_node_new.o src/libdcache/dcache_save.o src/libdcache/dcache_search.o else -libdcache.a.xyzzy: src/libdcache/dcache_add_data.lo src/libdcache/dcache_clean_expired.lo src/libdcache/dcache_delete.lo src/libdcache/dcache_free.lo src/libdcache/dcache_init.lo src/libdcache/dcache_load.lo src/libdcache/dcache_save.lo +libdcache.a.xyzzy: src/libdcache/dcache_add_data.lo src/libdcache/dcache_clean_expired.lo src/libdcache/dcache_delete.lo src/libdcache/dcache_free.lo src/libdcache/dcache_get_data.lo src/libdcache/dcache_init.lo src/libdcache/dcache_load.lo src/libdcache/dcache_node_add.lo src/libdcache/dcache_node_new.lo src/libdcache/dcache_save.lo src/libdcache/dcache_search.lo endif libdcache.so.xyzzy: EXTRA_LIBS := -libdcache.so.xyzzy: src/libdcache/dcache_add_data.lo src/libdcache/dcache_clean_expired.lo src/libdcache/dcache_delete.lo src/libdcache/dcache_free.lo src/libdcache/dcache_init.lo src/libdcache/dcache_load.lo src/libdcache/dcache_save.lo +libdcache.so.xyzzy: src/libdcache/dcache_add_data.lo src/libdcache/dcache_clean_expired.lo src/libdcache/dcache_delete.lo src/libdcache/dcache_free.lo src/libdcache/dcache_get_data.lo src/libdcache/dcache_init.lo src/libdcache/dcache_load.lo src/libdcache/dcache_node_add.lo src/libdcache/dcache_node_new.lo src/libdcache/dcache_save.lo src/libdcache/dcache_search.lo ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) libshibari-server.a.xyzzy: src/server/shibari_packet_init.o src/server/shibari_packet_begin.o src/server/shibari_packet_end.o src/server/shibari_packet_add_rr.o src/server/shibari_tdb_entry_parse.o src/server/shibari_tdb_extract_domain.o src/server/shibari_tdb_find_authority.o src/server/shibari_tdb_read_entry.o src/server/shibari_packet_add_glue.o src/server/shibari_packet_assert_authority.o src/server/shibari_packet_tdb_answer_query.o src/server/shibari_packet_tdb_axfr.o else diff --git a/src/cache/query.c b/src/cache/query.c index 7fa5af3..4832340 100644 --- a/src/cache/query.c +++ b/src/cache/query.c @@ -47,12 +47,12 @@ uint16_t query_event (uint16_t qid) default : rcode = 2 ; break ; } s6dns_engine_query(&q->dt, &question.s, &question.len, &qtype) ; - r = dcache_searchnode_g(&g->dcache, &nodeid, question.s, question.len, qtype) ; + r = dcache_search_g(&g->dcache, &nodeid, question.s, question.len, qtype) ; switch (r) { case -1 : log_warn_unexpected_answer(question.s, question.len, qtype, 0) ; - if (!rcode) dcache_add_new_answer(&g->dcache, question.s, question.len, qtype, s6dns_engine_packet(&q->dt), s6dns_engine_packetlen(&q->dt)) ; + if (!rcode) dcache_add_g(&g->dcache, question.s, question.len, qtype, s6dns_engine_packet(&q->dt), s6dns_engine_packetlen(&q->dt), &expire) ; break ; case 1 : log_warn_unexpected_answer(question.s, question.len, qtype, 1) ; diff --git a/src/include/shibari/dcache.h b/src/include/shibari/dcache.h index 1127249..3e02b54 100644 --- a/src/include/shibari/dcache.h +++ b/src/include/shibari/dcache.h @@ -43,14 +43,18 @@ struct dcache_s extern void dcache_init (dcache *, uint64_t) ; -extern int dcache_searchnode (dcache *, uint32_t *, char const *, uint16_t, uint16_t, tai const *) ; -#define dcache_searchnode_g(d, idx, q, qlen, qtype) dcache_searchnode(d, idx, q, qlen, (qtype), tain_secp(&STAMP)) +extern int dcache_search (dcache *, uint32_t *, char const *, uint16_t, uint16_t, tai const *) ; +#define dcache_search_g(d, idx, q, qlen, qtype) dcache_search(d, idx, q, qlen, (qtype), tain_secp(&STAMP)) extern void dcache_clean_expired (dcache *, tai const *) ; #define dcache_clean_expired_g(d) dcache_clean_expired((d), tain_secp(&STAMP)) extern void dcache_free (dcache *) ; + +extern int dcache_add (dcache *, char const *, uint16_t, uint16_t, char const *, uint16_t, tai const *, tai const *) ; +#define dcache_add_g(z, q, qlen, qtype, data, datalen, expire) dcache_add(z, q, qlen, qtype, data, datalen, tain_secp(&STAMP), expire) + extern int dcache_save (dcache const *, char const *) ; extern int dcache_load (dcache *, char const *) ; diff --git a/src/libdcache/dcache-internal.h b/src/libdcache/dcache-internal.h index 49ec504..9986456 100644 --- a/src/libdcache/dcache-internal.h +++ b/src/libdcache/dcache-internal.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -14,6 +15,10 @@ #define DNODE(z, i) GENSETDYN_P(dcache_node, &(z)->storage, i) #define DCACHE_NODE_OVERHEAD (32 + sizeof(dcache_node) + 3 * sizeof(avlnode)) +extern int dcache_node_new (dcache *, uint32_t *, char const *, uint16_t, uint16_t, uint16_t) ; +extern int dcache_node_add (dcache *, uint32_t) ; +#define dcache_node_free(node) stralloc_free(&(node)->sa) + extern void dcache_delete (dcache *, uint32_t) ; #endif diff --git a/src/libdcache/dcache_add.c b/src/libdcache/dcache_add.c new file mode 100644 index 0000000..82f1ef4 --- /dev/null +++ b/src/libdcache/dcache_add.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include +#include + +#include +#include "dcache-internal.h" + +#include + +int dcache_add (dcache *z, char const *q, uint16_t qlen, uint16_t qtype, char const *data, uint16_t datalen, tai const *entry, tai const *expire) +{ + uint32_t i ; + dcache_node *node ; + if (!dcache_node_new(z, &i, q, qlen, qtype, datalen)) return 0 ; + node = DNODE(z, i) ; + node->entry = *entry ; + node->expire = *expire ; + memcpy(node->sa.s + node->sa.len, data, datalen) ; + node->sa.len += datalen ; + if (!dcache_node_add(z, i)) + { + dcache_node_free(node) ; + return 0 ; + } + return 1 ; +} diff --git a/src/libdcache/dcache_add_data.c b/src/libdcache/dcache_add_data.c index aa1a110..06d20b7 100644 --- a/src/libdcache/dcache_add_data.c +++ b/src/libdcache/dcache_add_data.c @@ -56,7 +56,7 @@ int dcache_add_data (dcache *z, char const *q, uint16_t qlen, uint16_t qtype, ch if (z->size > z->max - size) dcache_clean_expired(z, stamp) ; if (z->size > z->max - size) dcache_gc_by_entry(z, z->max - size) ; if (z->size > z->max - size) return (errno = ENOBUFS, 0) ; - if (!dcache_searchnode(z, &i, q, qlen, qtype, stamp)) return 0 ; + if (!dcache_search(z, &i, q, qlen, qtype, stamp)) return 0 ; if (!dcache_add_data_to_node(z, i, qlen, data, datalen, expire, stamp)) return 0 ; z->size += size ; z->motion += size ; diff --git a/src/libdcache/dcache_clean_expired.c b/src/libdcache/dcache_clean_expired.c index d81bec8..7109e5c 100644 --- a/src/libdcache/dcache_clean_expired.c +++ b/src/libdcache/dcache_clean_expired.c @@ -14,7 +14,7 @@ void dcache_clean_expired (dcache *z, tai const *stamp) { uint32_t i ; if (!avltree_min(&z->by_expire, &i)) break ; - if (tai_less(stamp, &DNODE(z, i)->expire)) break ; + if (!tai_less(&DNODE(z, i)->expire, stamp)) break ; dcache_delete(z, i) ; } } diff --git a/src/libdcache/dcache_free.c b/src/libdcache/dcache_free.c index 07d6982..58dec5f 100644 --- a/src/libdcache/dcache_free.c +++ b/src/libdcache/dcache_free.c @@ -1,15 +1,15 @@ /* ISC license. */ -#include #include #include #include +#include "dcache-internal.h" -static void dcache_node_free (void *p) +static void dnode_free (void *p) { dcache_node *node = p ; - stralloc_free(&node->sa) ; + dcache_node_free(node) ; } void dcache_free (dcache *z) @@ -18,6 +18,6 @@ void dcache_free (dcache *z) avltree_free(&z->by_expire) ; avltree_free(&z->by_entry) ; avltree_free(&z->by_key) ; - gensetdyn_deepfree(&z->storage, &dcache_node_free) ; + gensetdyn_deepfree(&z->storage, &dnode_free) ; *z = dcache_zero ; } diff --git a/src/libdcache/dcache_get_data.c b/src/libdcache/dcache_get_data.c index f14977c..36d16c9 100644 --- a/src/libdcache/dcache_get_data.c +++ b/src/libdcache/dcache_get_data.c @@ -5,6 +5,7 @@ #include #include +#include "dcache-internal.h" void dcache_get_data (dcache *z, uint32_t nid, dcache_string *data) { diff --git a/src/libdcache/dcache_load.c b/src/libdcache/dcache_load.c index 0693b21..f195b28 100644 --- a/src/libdcache/dcache_load.c +++ b/src/libdcache/dcache_load.c @@ -9,32 +9,47 @@ #include #include #include +#include #include +#include "dcache-internal.h" #include +static inline int dcache_adjust_node (dcache *z, uint32_t i, char const *data, uint16_t datalen, tai const *entry, tai const *expire) +{ + /* can't happen. Complete if it ever can. */ + return (errno = EDOM, 0) ; +} + +static inline int dcache_add_keydata (dcache *z, char const *q, uint16_t qlen, uint16_t qtype, char const *data, uint16_t datalen, tai const *entry, tai const *expire) +{ + uint32_t i ; + if (dcache_search_g(z, &i, q, qlen, qtype)) return dcache_adjust_node(z, i, data, datalen, entry, expire) ; + return dcache_add(z, q, qlen, qtype, data, datalen, entry, expire) ; +} + static inline int dcache_load_node (dcache *z, buffer *b) { tai entry, expire ; - uint16_t keylen ; - uint16_t datalen ; - char pack[TAI_PACK * 2 + 4] ; - ssize_t r = buffer_get(b, pack, TAI_PACK * 2 + 4) ; + uint16_t qtype, qlen, datalen ; + char pack[TAI_PACK * 2 + 6] ; + ssize_t r = buffer_get(b, pack, TAI_PACK * 2 + 6) ; if (!r) return 0 ; - if (r < TAI_PACK * 2 + 4) return -1 ; + if (r < TAI_PACK * 2 + 6) return -1 ; tai_unpack(pack, &entry) ; tai_unpack(pack + TAI_PACK, &expire) ; - uint16_unpack_big(pack + TAI_PACK * 2, &keylen) ; - uint16_unpack_big(pack + TAI_PACK * 2 + 2, &datalen) ; + uint16_unpack_big(pack + TAI_PACK * 2, &datalen) ; + uint16_unpack_big(pack + TAI_PACK * 2 + 2, &qtype) ; + uint16_unpack_big(pack + TAI_PACK * 2 + 4, &qlen) ; { - uint32_t len = (uint32_t)keylen + (uint32_t)datalen ; - char blob[len+1] ; /* 128 kB max, it's ok */ - r = buffer_get(b, blob, len+1) ; + uint32_t len = qlen + datalen ; + char blob[len+1] ; /* 128 kB max */ + r = buffer_get(b, blob, len + 1) ; if (!r) return (errno = EPIPE, -1) ; - if (r < len) return -1 ; + if (r <= len) return -1 ; if (blob[len]) return (errno = EPROTO, -1) ; -// if (!dcache_add(z, blob, keylen, blob + keylen, datalen, &expire, &entry)) return -1 ; + if (!dcache_add_keydata(z, blob, qlen, qtype, blob + qlen, datalen, &entry, &expire)) return -1 ; } return 1 ; } diff --git a/src/libdcache/dcache_node_add.c b/src/libdcache/dcache_node_add.c new file mode 100644 index 0000000..a9cc539 --- /dev/null +++ b/src/libdcache/dcache_node_add.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include + +#include "dcache-internal.h" + +int dcache_node_add (dcache *z, uint32_t i) +{ + dcache_node *node = DNODE(z, i) ; + if (!avltree_insert(&z->by_key, i)) return 0 ; + if (node->sa.len < node->sa.a) return 1 ; + if (!avltree_insert(&z->by_entry, i)) goto err0 ; + if (!avltree_insert(&z->by_expire, i)) goto err1 ; + return 1 ; + + err1: + avltree_delete(&z->by_entry, &node->entry) ; + err0: + avltree_delete(&z->by_key, node->sa.s) ; + return 0 ; +} diff --git a/src/libdcache/dcache_node_new.c b/src/libdcache/dcache_node_new.c index 1d13eaf..01e2278 100644 --- a/src/libdcache/dcache_node_new.c +++ b/src/libdcache/dcache_node_new.c @@ -6,28 +6,24 @@ #include #include #include -#include #include #include "dcache-internal.h" -dcache_node *dcache_node_new (dcache *z, char const *key, uint16_t keylen) +int dcache_node_new (dcache *z, uint32_t *idx, char const *q, uint16_t qlen, uint16_t qtype, uint16_t extra) { - static tai const tai_infinite = TAI_INFINITE ; dcache_node *node ; uint32_t i ; - if (!gensetdyn_new(&z->storage, i)) return 0 ; + if (!gensetdyn_new(&z->storage, &i)) return 0 ; node = DNODE(z, i) ; - if (!stralloc_ready(&node->sa, 6 + keylen)) goto err0 ; - uint16_pack_big(node->sa.s, keylen) ; - memcpy(node->sa.s + 2, key, keylen) ; - node->sa.len = 2 + keylen ; - node->entry = tai_infinite ; - node->expire = tai_infinite ; - return node ; + if (!stralloc_ready_tuned(&node->sa, 4 + qlen + extra, 0, 0, 1)) goto err0 ; + uint16_pack_big(node->sa.s, qtype) ; + uint16_pack_big(node->sa.s + 2, qlen) ; + memcpy(node->sa.s + 4, q, qlen) ; + node->sa.len = 4 + qlen ; + *idx = i ; + return 1 ; - err1: - node->sa.len = 0 ; err0: gensetdyn_delete(&z->storage, i) ; return 0 ; diff --git a/src/libdcache/dcache_save.c b/src/libdcache/dcache_save.c index 62c55a2..3cff3c5 100644 --- a/src/libdcache/dcache_save.c +++ b/src/libdcache/dcache_save.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -21,13 +20,18 @@ static int write_node_iter (void *data, void *aux) { dcache_node *y = data ; buffer *b = aux ; - char pack[TAI_PACK * 2 + 4] ; + char pack[TAI_PACK] ; + uint16_t len ; + if (y->sa.a != y->sa.len) return 1 ; tai_pack(pack, &y->entry) ; + if (buffer_put(b, pack, TAI_PACK) == -1) return 0 ; tai_pack(pack + TAI_PACK, &y->expire) ; -// uint16_pack(pack + TAI_PACK * 2, y->key.len) ; -// uint16_pack(pack + TAI_PACK * 2 + 2, y->datalen) ; - if (buffer_put(b, pack, TAI_PACK * 2 + 4) == -1) return 0 ; -// if (buffer_put(b, y->key.s, y->key.len + y->datalen) == -1) return 0 ; + if (buffer_put(b, pack, TAI_PACK) == -1) return 0 ; + uint16_unpack_big(y->sa.s + 2, &len) ; + len = y->sa.len - len ; + uint16_pack_big(pack, len) ; + if (buffer_put(b, pack, 2) == -1) return 0 ; + if (buffer_put(b, y->sa.s, y->sa.len) == -1) return 0 ; if (buffer_put(b, "", 1) == -1) return 0 ; return 1 ; } diff --git a/src/libdcache/dcache_search.c b/src/libdcache/dcache_search.c new file mode 100644 index 0000000..d01faa0 --- /dev/null +++ b/src/libdcache/dcache_search.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include + +#include +#include + +#include +#include "dcache-internal.h" + +int dcache_search (dcache *z, uint32_t *idx, char const *q, uint16_t qlen, uint16_t qtype, tai const *stamp) +{ + dcache_node *node ; + uint32_t i ; + char key[4 + qlen] ; + uint16_pack_big(key, qtype) ; + uint16_pack_big(key+2, qlen) ; + memcpy(key+4, q, qlen) ; + if (!avltree_search(&z->by_key, &key, &i)) return -1 ; + node = DNODE(z, i) ; + if (node->sa.len == node->sa.a && tai_less(&node->expire, stamp)) + { + dcache_delete(z, i) ; + return -1 ; + } + *idx = i ; + return node->sa.len == node->sa.a ; +} diff --git a/src/libdcache/dcache_searchnode.c b/src/libdcache/dcache_searchnode.c deleted file mode 100644 index ef7341c..0000000 --- a/src/libdcache/dcache_searchnode.c +++ /dev/null @@ -1,28 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include - -#include -#include "dcache-internal.h" - -int dcache_searchnode (dcache *z, uint32_t *idx, char const *q, uint16_t qlen, uint16_t qtype, tai const *stamp) -{ - dcache_node *node ; - uint32_t i ; - char key[4 + qlen] ; - uint16_pack_big(key, qtype) ; - uint16_pack_big(key+2, qlen) ; - memcpy(key+4, q, qlen) ; - if (!avltree_search(&z->by_key, &k, &i)) return -1 ; - node = DNODE(z, i) ; - if (node->sa.len == node->sa.a && !tai_less(stamp, &node->expire)) - { - dcache_delete(z, i) ; - return -1 ; - } - *idx = i ; - return node->sa.len == node->sa.a ; -} diff --git a/src/libdcache/deps-lib/dcache b/src/libdcache/deps-lib/dcache index 07f9f51..4e411c4 100644 --- a/src/libdcache/deps-lib/dcache +++ b/src/libdcache/deps-lib/dcache @@ -2,6 +2,10 @@ dcache_add_data.o dcache_clean_expired.o dcache_delete.o dcache_free.o +dcache_get_data.o dcache_init.o dcache_load.o +dcache_node_add.o +dcache_node_new.o dcache_save.o +dcache_search.o -- cgit 1.4.1