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