summaryrefslogtreecommitdiff
path: root/source3/tdb/tdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/tdb/tdb.c')
-rw-r--r--source3/tdb/tdb.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index ede38f27f9..afc87b7da0 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -922,11 +922,13 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
rec.key_len))
|| memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
/* No, it wasn't: unlock it and start from scratch */
- free(k);
unlock_record(tdb, tdb->travlocks.off);
tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK);
tdb->travlocks.off = 0;
}
+
+ if (k)
+ free(k);
}
if (!tdb->travlocks.off) {
@@ -1180,7 +1182,19 @@ int tdb_lockall(TDB_CONTEXT *tdb)
/* There are no locks on read-only dbs */
if (tdb->read_only) return TDB_ERRCODE(TDB_ERR_LOCK, -1);
if (tdb->lockedkeys) return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
- for (i = 0; i < tdb->header.hash_size; i++) tdb_lock(tdb, i, F_WRLCK);
+ for (i = 0; i < tdb->header.hash_size; i++)
+ if (tdb_lock(tdb, i, F_WRLCK))
+ break;
+
+ /* If error, release locks we have... */
+ if (i < tdb->header.hash_size) {
+ u32 j;
+
+ for ( j = 0; j < i; j++)
+ tdb_unlock(tdb, j, F_WRLCK);
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ }
+
return 0;
}
void tdb_unlockall(TDB_CONTEXT *tdb)
@@ -1211,7 +1225,18 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
tdb->lockedkeys[j+1] = hash;
}
/* Finally, lock in order */
- for (i = 0; i < number; i++) tdb_lock(tdb, i, F_WRLCK);
+ for (i = 0; i < number; i++)
+ if (tdb_lock(tdb, i, F_WRLCK))
+ break;
+
+ /* If error, release locks we have... */
+ if (i < number) {
+ for ( j = 0; j < i; j++)
+ tdb_unlock(tdb, j, F_WRLCK);
+ free(tdb->lockedkeys);
+ tdb->lockedkeys = NULL;
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ }
return 0;
}