X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fio.c;h=676f4942bf604c879b767e8a296eca0f319d2dae;hp=6cb1bdda6d5e68646dfe81976b73477f47445902;hb=d1383862ad9a74e713dc915d351b74da4db35078;hpb=6804501c350181dea8f531142b28c620b70edbd9 diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 6cb1bdda..676f4942 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -48,8 +48,7 @@ void tdb_mmap(struct tdb_context *tdb) if (tdb->flags & TDB_NOMMAP) return; - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), + tdb->map_ptr = mmap(NULL, tdb->map_size, tdb->mmap_flags, MAP_SHARED, tdb->fd, 0); /* @@ -73,9 +72,10 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) struct stat st; int ret; - /* FIXME: We can't hold pointers during this: we could unmap! */ - /* (We currently do this in traverse!) */ -// assert(!tdb->direct_access || tdb_has_expansion_lock(tdb)); + /* We can't hold pointers during this: we could unmap! */ + assert(!tdb->direct_access + || (tdb->flags & TDB_NOLOCK) + || tdb_has_expansion_lock(tdb)); if (len <= tdb->map_size) return 0; @@ -123,27 +123,13 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) return 0; } -static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len) -{ - if (unlikely(!tdb->map_ptr)) - return NULL; - - /* FIXME: We can do a subset of this! */ - if (tdb->transaction) - return NULL; - - if (unlikely(tdb_oob(tdb, off + len, true) == -1)) - return NULL; - return (char *)tdb->map_ptr + off; -} - /* 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_direct(tdb, off, len); + void *ret = tdb->methods->direct(tdb, off, len); if (ret) return ret; } @@ -161,25 +147,25 @@ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size) return buf; } -/* Return first non-zero offset in num offset array, or num. */ /* FIXME: Return the off? */ -uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, tdb_off_t off, - uint64_t num) +uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, + tdb_off_t base, uint64_t start, uint64_t end) { uint64_t i; const uint64_t *val; /* Zero vs non-zero is the same unconverted: minor optimization. */ - val = tdb_access_read(tdb, off, num * sizeof(tdb_off_t), false); + val = tdb_access_read(tdb, base + start * sizeof(tdb_off_t), + (end - start) * sizeof(tdb_off_t), false); if (!val) - return num; + return end; - for (i = 0; i < num; i++) { + for (i = 0; i < (end - start); i++) { if (val[i]) break; } tdb_access_release(tdb, val); - return i; + return start + i; } /* Return first zero offset in num offset array, or num. */ @@ -205,7 +191,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_direct(tdb, off, len); + void *p = tdb->methods->direct(tdb, off, len); if (p) { memset(p, 0, len); return 0; @@ -311,7 +297,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, tdb->ecode = TDB_ERR_IO; tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "tdb_write failed at %llu len=%llu (%s)\n", - off, len, strerror(errno)); + (long long)off, (long long)len, + strerror(errno)); return -1; } } @@ -477,7 +464,7 @@ const void *tdb_access_read(struct tdb_context *tdb, const void *ret = NULL; if (likely(!(tdb->flags & TDB_CONVERT))) - ret = tdb_direct(tdb, off, len); + ret = tdb->methods->direct(tdb, off, len); if (!ret) { struct tdb_access_hdr *hdr; @@ -499,7 +486,7 @@ void *tdb_access_write(struct tdb_context *tdb, void *ret = NULL; if (likely(!(tdb->flags & TDB_CONVERT))) - ret = tdb_direct(tdb, off, len); + ret = tdb->methods->direct(tdb, off, len); if (!ret) { struct tdb_access_hdr *hdr; @@ -657,11 +644,22 @@ int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record * } #endif +static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len) +{ + if (unlikely(!tdb->map_ptr)) + return NULL; + + if (unlikely(tdb_oob(tdb, off + len, true) == -1)) + return NULL; + return (char *)tdb->map_ptr + off; +} + static const struct tdb_methods io_methods = { tdb_read, tdb_write, tdb_oob, tdb_expand_file, + tdb_direct, }; /*