diff options
author | Ronnie Sahlberg <sahlberg@ronnie.(none)> | 2008-02-08 08:21:03 +1100 |
---|---|---|
committer | Ronnie Sahlberg <sahlberg@ronnie.(none)> | 2008-02-08 08:21:03 +1100 |
commit | 60e2a45454ed60a73f789ea4c0351fa4117e6053 (patch) | |
tree | 6932e61354202362de5fd5ab3707f8ee30911886 | |
parent | 81232a9e29d610a25a379bc3f1e0ee6fc18da19b (diff) | |
parent | fbba202f1a929fcf29203a89f5bdf92a0a60beef (diff) | |
download | samba-60e2a45454ed60a73f789ea4c0351fa4117e6053.tar.gz samba-60e2a45454ed60a73f789ea4c0351fa4117e6053.tar.xz samba-60e2a45454ed60a73f789ea4c0351fa4117e6053.zip |
Merge git://git.samba.org/tridge/ctdb
(This used to be ctdb commit a8762bf8ca1958985896f174ccafe09361092d09)
-rw-r--r-- | ctdb/lib/tdb/common/tdb.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/ctdb/lib/tdb/common/tdb.c b/ctdb/lib/tdb/common/tdb.c index ea5d9ccc60..a25c3e7aca 100644 --- a/ctdb/lib/tdb/common/tdb.c +++ b/ctdb/lib/tdb/common/tdb.c @@ -696,11 +696,31 @@ int tdb_wipe_all(struct tdb_context *tdb) int i; tdb_off_t offset = 0; ssize_t data_len; + tdb_off_t recovery_head; + tdb_len_t recovery_size = 0; if (tdb_lockall(tdb) != 0) { return -1; } + /* see if the tdb has a recovery area, and remember its size + if so. We don't want to lose this as otherwise each + tdb_wipe_all() in a transaction will increase the size of + the tdb by the size of the recovery area */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); + goto failed; + } + + if (recovery_head != 0) { + struct list_struct rec; + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); + return -1; + } + recovery_size = rec.rec_len + sizeof(rec); + } + /* wipe the hashes */ for (i=0;i<tdb->header.hash_size;i++) { if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { @@ -722,6 +742,11 @@ int tdb_wipe_all(struct tdb_context *tdb) /* add all the rest of the file to the freelist */ data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct); + if (data_len < recovery_size+sizeof(tdb_off_t)) { + recovery_size = 0; + } else { + data_len -= recovery_size; + } if (data_len > 0) { struct list_struct rec; memset(&rec,'\0',sizeof(rec)); @@ -732,6 +757,24 @@ int tdb_wipe_all(struct tdb_context *tdb) } } + /* possibly add the recovery record */ + if (recovery_size != 0) { + struct list_struct rec; + + recovery_head = tdb->map_size - recovery_size; + + ZERO_STRUCT(rec); + rec.rec_len = recovery_size - sizeof(rec); + if (tdb_rec_write(tdb, recovery_head, &rec) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to add recovery record\n")); + goto failed; + } + if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n")); + goto failed; + } + } + if (tdb_unlockall(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); goto failed; |