ret = tdb_storev(cache->tdb, key, dbufs, ARRAY_SIZE(dbufs), 0);
- return ret == 0;
+ if (ret == 0) {
+ return true;
+ }
+ if (tdb_error(cache->tdb) != TDB_ERR_CORRUPT) {
+ return false;
+ }
+
+ ret = tdb_wipe_all(cache->tdb);
+ SMB_ASSERT(ret == 0);
+
+ return false;
}
/**
ret = tdb_delete(cache->tdb, key);
- return (ret != -1);
+ if (ret == 0) {
+ return true;
+ }
+ if (tdb_error(cache->tdb) != TDB_ERR_CORRUPT) {
+ return false;
+ }
+
+ ret = tdb_wipe_all(cache->tdb);
+ SMB_ASSERT(ret == 0);
+
+ return true; /* We've deleted a bit more... */
}
static bool gencache_pull_timeout(TDB_DATA key,
DATA_BLOB blob,
void *private_data);
void *private_data;
+ bool format_error;
};
static int gencache_parse_fn(TDB_DATA key, TDB_DATA data, void *private_data)
{
- struct gencache_parse_state *state;
+ struct gencache_parse_state *state = private_data;
struct gencache_timeout t;
DATA_BLOB payload;
bool ret;
ret = gencache_pull_timeout(key, data, &t.timeout, &payload);
if (!ret) {
- return -1;
+ state->format_error = true;
+ return 0;
}
- state = (struct gencache_parse_state *)private_data;
state->parser(&t, payload, state->private_data);
return 0;
void *private_data),
void *private_data)
{
- struct gencache_parse_state state;
+ struct gencache_parse_state state = {
+ .parser = parser, .private_data = private_data
+ };
TDB_DATA key = string_term_tdb_data(keystr);
int ret;
return false;
}
- state.parser = parser;
- state.private_data = private_data;
-
ret = tdb_parse_record(cache->tdb, key,
gencache_parse_fn, &state);
- if (ret == 0) {
- return true;
+ if ((ret == -1) && (tdb_error(cache->tdb) == TDB_ERR_CORRUPT)) {
+ goto wipe;
+ }
+ if (ret == -1) {
+ return false;
+ }
+ if (state.format_error) {
+ ret = tdb_delete(cache->tdb, key);
+ if (ret == -1) {
+ goto wipe;
+ }
+ return false;
}
+ return true;
- return (ret == 0);
+wipe:
+ ret = tdb_wipe_all(cache->tdb);
+ SMB_ASSERT(ret == 0);
+ return false;
}
struct gencache_get_data_blob_state {
void *private_data, const char *pattern)
{
struct gencache_iterate_blobs_state state;
+ int ret;
if ((fn == NULL) || (pattern == NULL) || !gencache_init()) {
return;
state.pattern = pattern;
state.private_data = private_data;
- tdb_traverse(cache->tdb, gencache_iterate_blobs_fn, &state);
+ ret = tdb_traverse(cache->tdb, gencache_iterate_blobs_fn, &state);
+
+ if ((ret == -1) && (tdb_error(cache->tdb) == TDB_ERR_CORRUPT)) {
+ ret = tdb_wipe_all(cache->tdb);
+ SMB_ASSERT(ret == 0);
+ }
}
/**