X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fio.c;h=ae09597ec4eecacaf362f7c9af616103d9857f1f;hp=82c49406abc1e962a93ad24096203e6a25906245;hb=a42bba8ec446284256a7c9146ba3525404de474c;hpb=4e185ad8ab5a7e01edbbe12d11eb2f1577de7e8b diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 82c49406..ae09597e 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -173,7 +173,7 @@ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, int zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) { char buf[8192] = { 0 }; - void *p = tdb->methods->direct(tdb, off, len); + void *p = tdb->methods->direct(tdb, off, len, true); assert(!tdb->read_only); if (p) { @@ -195,7 +195,8 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) tdb_off_t ret; if (likely(!(tdb->flags & TDB_CONVERT))) { - tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p)); + tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p), + false); if (p) return *p; } @@ -356,7 +357,8 @@ int tdb_write_off(struct tdb_context *tdb, tdb_off_t off, tdb_off_t val) } if (likely(!(tdb->flags & TDB_CONVERT))) { - tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p)); + tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p), + true); if (p) { *p = val; return 0; @@ -450,25 +452,20 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_len_t addition) return 0; } -/* This is only neded for tdb_access_commit, but used everywhere to simplify. */ -struct tdb_access_hdr { - tdb_off_t off; - tdb_len_t len; - bool convert; -}; - const void *tdb_access_read(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, bool convert) { const void *ret = NULL; if (likely(!(tdb->flags & TDB_CONVERT))) - ret = tdb->methods->direct(tdb, off, len); + ret = tdb->methods->direct(tdb, off, len, false); if (!ret) { struct tdb_access_hdr *hdr; hdr = _tdb_alloc_read(tdb, off, len, sizeof(*hdr)); if (hdr) { + hdr->next = tdb->access; + tdb->access = hdr; ret = hdr + 1; if (convert) tdb_convert(tdb, (void *)ret, len); @@ -491,12 +488,14 @@ void *tdb_access_write(struct tdb_context *tdb, } if (likely(!(tdb->flags & TDB_CONVERT))) - ret = tdb->methods->direct(tdb, off, len); + ret = tdb->methods->direct(tdb, off, len, true); if (!ret) { struct tdb_access_hdr *hdr; hdr = _tdb_alloc_read(tdb, off, len, sizeof(*hdr)); if (hdr) { + hdr->next = tdb->access; + tdb->access = hdr; hdr->off = off; hdr->len = len; hdr->convert = convert; @@ -510,35 +509,41 @@ void *tdb_access_write(struct tdb_context *tdb, return ret; } -bool is_direct(const struct tdb_context *tdb, const void *p) +static struct tdb_access_hdr **find_hdr(struct tdb_context *tdb, const void *p) { - return (tdb->map_ptr - && (char *)p >= (char *)tdb->map_ptr - && (char *)p < (char *)tdb->map_ptr + tdb->map_size); + struct tdb_access_hdr **hp; + + for (hp = &tdb->access; *hp; hp = &(*hp)->next) { + if (*hp + 1 == p) + return hp; + } + return NULL; } void tdb_access_release(struct tdb_context *tdb, const void *p) { - if (is_direct(tdb, p)) + struct tdb_access_hdr *hdr, **hp = find_hdr(tdb, p); + + if (hp) { + hdr = *hp; + *hp = hdr->next; + free(hdr); + } else tdb->direct_access--; - else - free((struct tdb_access_hdr *)p - 1); } int tdb_access_commit(struct tdb_context *tdb, void *p) { + struct tdb_access_hdr *hdr, **hp = find_hdr(tdb, p); int ret = 0; - if (!tdb->map_ptr - || (char *)p < (char *)tdb->map_ptr - || (char *)p >= (char *)tdb->map_ptr + tdb->map_size) { - struct tdb_access_hdr *hdr; - - hdr = (struct tdb_access_hdr *)p - 1; + if (hp) { + hdr = *hp; if (hdr->convert) ret = tdb_write_convert(tdb, hdr->off, p, hdr->len); else ret = tdb_write(tdb, hdr->off, p, hdr->len); + *hp = hdr->next; free(hdr); } else tdb->direct_access--; @@ -546,7 +551,8 @@ int tdb_access_commit(struct tdb_context *tdb, void *p) return ret; } -static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len) +static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len, + bool write) { if (unlikely(!tdb->map_ptr)) return NULL;