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);
/*
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;
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;
}
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. */
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;
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;
}
}
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;
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;
}
#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,
};
/*