From 99c2693c620cd222da5561d526aa328bec426b77 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Dec 2000 21:29:06 +0000 Subject: Added lock backouts on fail. When chaining together long lines of bloody "if" statements, which should logically be separated, and one of them allocates memory, remember to *free* it *WHETHER OR NOT THE IF STATEMENTS SUCCEEDED* !!!! Yes I do consider this a bug in the coding style of Tridge, Rusty, Tim et al. :-). I'm just pissed 'cos this took 4 hours to track down even with an insure error report stating me in the face and also Ben Woodward looking over the code with me :-). Jeremy. (This used to be commit 506b5e34c3ba16768dbc82ba21044787de160c45) --- source3/tdb/tdb.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'source3/tdb') 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; } -- cgit