static bool test_records(struct tdb_context *tdb) { int i; struct tdb_data key = { (unsigned char *)&i, sizeof(i) }; struct tdb_data data = { (unsigned char *)&i, sizeof(i) }; for (i = 0; i < 1000; i++) { if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) return false; } for (i = 0; i < 1000; i++) { if (tdb_parse_record(tdb, key, parse, &data) != TDB_SUCCESS) return false; } if (tdb_parse_record(tdb, key, parse, &data) != TDB_ERR_NOEXIST) return false; /* Test error return from parse function. */ i = 0; if (tdb_parse_record(tdb, key, parse_err, NULL) != 100) return false; return true; }
BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) { TDB_DATA key = locking_key(dev, inode); BOOL result = False; tdb_parse_record(tdb, key, pull_delete_on_close_flag, (void *)&result); return result; }
static NTSTATUS db_ctdb_ltdb_parse( struct db_ctdb_ctx *db, TDB_DATA key, void (*parser)(TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA data, void *private_data), void *private_data) { struct db_ctdb_ltdb_parse_state state; int ret; state.parser = parser; state.private_data = private_data; ret = tdb_parse_record(db->wtdb->tdb, key, db_ctdb_ltdb_parser, &state); if (ret == -1) { return NT_STATUS_NOT_FOUND; } return NT_STATUS_OK; }
static NTSTATUS db_tdb_parse(struct db_context *db, TDB_DATA key, void (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { struct db_tdb_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_tdb_ctx); struct db_tdb_parse_state state; int ret; state.parser = parser; state.private_data = private_data; ret = tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_parser, &state); if (ret != 0) { return map_nt_error_from_tdb(tdb_error(ctx->wtdb->tdb)); } return NT_STATUS_OK; }
static struct db_record *db_tdb_fetch_locked(struct db_context *db, TALLOC_CTX *mem_ctx, TDB_DATA key) { struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, struct db_tdb_ctx); struct tdb_fetch_locked_state state; db_tdb_log_key("Locking", key); if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) { DEBUG(3, ("tdb_chainlock failed\n")); return NULL; } state.mem_ctx = mem_ctx; state.result = NULL; tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, &state); if (state.result == NULL) { db_tdb_fetchlock_parse(key, tdb_null, &state); } if (state.result == NULL) { tdb_chainunlock(ctx->wtdb->tdb, key); return NULL; } talloc_set_destructor(state.result, db_tdb_record_destr); state.result->private_data = talloc_reference(state.result, ctx); state.result->store = db_tdb_store; state.result->delete_rec = db_tdb_delete; DEBUG(10, ("Allocated locked data 0x%p\n", state.result)); return state.result; }
int db_hash_fetch(struct db_hash_context *dh, uint8_t *keybuf, size_t keylen, db_hash_record_parser_fn parser, void *private_data) { struct db_hash_fetch_state state; TDB_DATA key; int ret; if (dh == NULL || parser == NULL) { return EINVAL; } state.parser = parser; state.private_data = private_data; key.dptr = keybuf; key.dsize = keylen; ret = tdb_parse_record(dh->db, key, db_hash_fetch_parser, &state); if (ret == -1) { return ENOENT; } return ret; }
static struct db_record *db_tdb_fetch_locked_internal( struct db_context *db, TALLOC_CTX *mem_ctx, TDB_DATA key) { struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, struct db_tdb_ctx); struct tdb_fetch_locked_state state; state.mem_ctx = mem_ctx; state.result = NULL; if ((tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, &state) < 0) && (tdb_error(ctx->wtdb->tdb) != TDB_ERR_NOEXIST)) { tdb_chainunlock(ctx->wtdb->tdb, key); return NULL; } if (state.result == NULL) { db_tdb_fetchlock_parse(key, tdb_null, &state); } if (state.result == NULL) { tdb_chainunlock(ctx->wtdb->tdb, key); return NULL; } talloc_set_destructor(state.result, db_tdb_record_destr); state.result->private_data = talloc_reference(state.result, ctx); state.result->store = db_tdb_store; state.result->delete_rec = db_tdb_delete; DEBUG(10, ("Allocated locked data 0x%p\n", state.result)); return state.result; }
/* update an entry in place - this only works if the new data size is <= the old data size and the key exists. on failure return -1. */ static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) { struct tdb_record rec; tdb_off_t rec_ptr; /* find entry */ if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) return -1; /* it could be an exact duplicate of what is there - this is * surprisingly common (eg. with a ldb re-index). */ if (rec.key_len == key.dsize && rec.data_len == dbuf.dsize && rec.full_hash == hash && tdb_parse_record(tdb, key, tdb_update_hash_cmp, &dbuf) == 0) { return 0; } /* must be long enough key, data and tailer */ if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) { tdb->ecode = TDB_SUCCESS; /* Not really an error */ return -1; } if (tdb->methods->tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, dbuf.dptr, dbuf.dsize) == -1) return -1; if (dbuf.dsize != rec.data_len) { /* update size */ rec.data_len = dbuf.dsize; return tdb_rec_write(tdb, rec_ptr, &rec); } return 0; }