summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2011-12-19 13:39:04 +0100
committerVolker Lendecke <vl@samba.org>2011-12-25 13:31:58 +0100
commit1eefd6bafba689e807e208149ee39b0f773c1ff8 (patch)
tree41132c6c5c580fefb9bc47967d6ee3238cb0ba03
parentc1e9537ed0f58404fed96a7aa9e581b8ebb1fb60 (diff)
downloadsamba-1eefd6bafba689e807e208149ee39b0f773c1ff8.tar.gz
samba-1eefd6bafba689e807e208149ee39b0f773c1ff8.tar.bz2
samba-1eefd6bafba689e807e208149ee39b0f773c1ff8.zip
tdb: Use tdb_parse_record in tdb_update_hash
This avoids a tdb_fetch, thus a malloc/memcpy/free in the tdb_store path
-rw-r--r--lib/tdb2/tdb1_tdb.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/lib/tdb2/tdb1_tdb.c b/lib/tdb2/tdb1_tdb.c
index a220f47169..869672a578 100644
--- a/lib/tdb2/tdb1_tdb.c
+++ b/lib/tdb2/tdb1_tdb.c
@@ -146,6 +146,19 @@ tdb1_off_t tdb1_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t h
static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key);
+static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+ TDB_DATA *dbuf = (TDB_DATA *)private_data;
+
+ if (dbuf->dsize != data.dsize) {
+ return -1;
+ }
+ if (memcmp(dbuf->dptr, data.dptr, data.dsize) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
/* 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.
@@ -163,18 +176,9 @@ static int tdb1_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash
* surprisingly common (eg. with a ldb re-index). */
if (rec.key_len == key.dsize &&
rec.data_len == dbuf.dsize &&
- rec.full_hash == hash) {
- TDB_DATA data = _tdb1_fetch(tdb, key);
- if (data.dsize == dbuf.dsize &&
- memcmp(data.dptr, dbuf.dptr, data.dsize) == 0) {
- if (data.dptr) {
- free(data.dptr);
- }
+ rec.full_hash == hash &&
+ tdb1_parse_record(tdb, key, tdb_update_hash_cmp, &dbuf) == 0) {
return 0;
- }
- if (data.dptr) {
- free(data.dptr);
- }
}
/* must be long enough key, data and tailer */