X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Fio.c;h=56ccfcba67b7ab2dac531f5d3cf9a08d22644ca4;hb=b44978e1499a61c3d91d93dbd7c45b6fc45b1778;hp=6c8f847b2b8bb19e29ce482d5a3a82c78779102c;hpb=6520c8318b9b8f2d92ae4b9f062788b7e4035aac;p=ccan-lca-2011.git diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 6c8f847..56ccfcb 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -123,19 +123,6 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) return 0; } -/* Either make a copy into pad and return that, or return ptr into mmap. */ -/* Note: pad has to be a real object, so we can't get here if len - * overflows size_t */ -void *tdb_get(struct tdb_context *tdb, tdb_off_t off, void *pad, size_t len) -{ - if (likely(!(tdb->flags & TDB_CONVERT))) { - void *ret = tdb->methods->direct(tdb, off, len); - if (ret) - return ret; - } - return tdb_read_convert(tdb, off, pad, len) == -1 ? NULL : pad; -} - /* Endian conversion: we only ever deal with 8 byte quantities */ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size) { @@ -192,6 +179,12 @@ 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); + + if (tdb->read_only) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + if (p) { memset(p, 0, len); return 0; @@ -208,13 +201,17 @@ int zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) { - tdb_off_t pad, *ret; + tdb_off_t ret; - ret = tdb_get(tdb, off, &pad, sizeof(pad)); - if (!ret) { - return TDB_OFF_ERR; + if (likely(!(tdb->flags & TDB_CONVERT))) { + tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p)); + if (p) + return *p; } - return *ret; + + if (tdb_read_convert(tdb, off, &ret, sizeof(ret)) == -1) + return TDB_OFF_ERR; + return ret; } /* Even on files, we can get partial writes due to signals. */ @@ -364,6 +361,18 @@ int tdb_read_convert(struct tdb_context *tdb, tdb_off_t off, int tdb_write_off(struct tdb_context *tdb, tdb_off_t off, tdb_off_t val) { + if (tdb->read_only) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + if (likely(!(tdb->flags & TDB_CONVERT))) { + tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p)); + if (p) { + *p = val; + return 0; + } + } return tdb_write_convert(tdb, off, &val, sizeof(val)); } @@ -443,7 +452,7 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_len_t addition) file isn't sparse, which would be very bad if we ran out of disk. This must be done with write, not via mmap */ memset(buf, 0x43, sizeof(buf)); - if (fill(tdb, buf, sizeof(buf), tdb->map_size, addition) == -1) + if (0 || fill(tdb, buf, sizeof(buf), tdb->map_size, addition) == -1) return -1; tdb->map_size += addition; tdb_mmap(tdb); @@ -485,6 +494,11 @@ void *tdb_access_write(struct tdb_context *tdb, { void *ret = NULL; + if (tdb->read_only) { + tdb->ecode = TDB_ERR_RDONLY; + return NULL; + } + if (likely(!(tdb->flags & TDB_CONVERT))) ret = tdb->methods->direct(tdb, off, len); @@ -505,14 +519,19 @@ void *tdb_access_write(struct tdb_context *tdb, return ret; } +bool is_direct(const 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); +} + void tdb_access_release(struct tdb_context *tdb, const void *p) { - if (!tdb->map_ptr - || (char *)p < (char *)tdb->map_ptr - || (char *)p >= (char *)tdb->map_ptr + tdb->map_size) - free((struct tdb_access_hdr *)p - 1); - else + if (is_direct(tdb, p)) tdb->direct_access--; + else + free((struct tdb_access_hdr *)p - 1); } int tdb_access_commit(struct tdb_context *tdb, void *p) @@ -546,6 +565,12 @@ static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len) return (char *)tdb->map_ptr + off; } +void add_stat_(struct tdb_context *tdb, uint64_t *stat, size_t val) +{ + if ((uintptr_t)stat < (uintptr_t)tdb->stats + tdb->stats->size) + *stat += val; +} + static const struct tdb_methods io_methods = { tdb_read, tdb_write,