summaryrefslogtreecommitdiff
path: root/source3/tdb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-12-15 21:29:06 +0000
committerJeremy Allison <jra@samba.org>2000-12-15 21:29:06 +0000
commit99c2693c620cd222da5561d526aa328bec426b77 (patch)
tree5f524e8a0a8fa929953df69357195ffaf83b68af /source3/tdb
parent89af6fd745a6f49668bae5b5c2d239d3671fb299 (diff)
downloadsamba-99c2693c620cd222da5561d526aa328bec426b77.tar.gz
samba-99c2693c620cd222da5561d526aa328bec426b77.tar.bz2
samba-99c2693c620cd222da5561d526aa328bec426b77.zip
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)
Diffstat (limited to 'source3/tdb')
-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;
}