diff options
Diffstat (limited to 'source3/tdb/tdb.c')
-rw-r--r-- | source3/tdb/tdb.c | 31 |
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; } |