auto-repack in transactions that expand the tdb
authorAndrew Tridgell <tridge@samba.org>
Mon, 1 Jun 2009 03:11:39 +0000 (13:11 +1000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 1 Jun 2009 03:11:39 +0000 (13:11 +1000)
The idea behind this is to recover from badly fragmented free
lists. Choosing the point where the file expands is fairly arbitrary,
but seems to work well.

lib/tdb/common/transaction.c

index f5c04a69cc01e8abecf5c53d6ac92aed7ae68d4b..e97fe67b4e02781641af95e2d63ad8293804d32e 100644 (file)
@@ -122,6 +122,9 @@ struct tdb_transaction {
 
        /* old file size before transaction */
        tdb_len_t old_map_size;
+
+       /* we should re-pack on commit */
+       bool need_repack;
 };
 
 
@@ -392,6 +395,8 @@ static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size,
                return -1;
        }
 
+       tdb->transaction->need_repack = true;
+
        return 0;
 }
 
@@ -965,6 +970,7 @@ int tdb_transaction_commit(struct tdb_context *tdb)
 {      
        const struct tdb_methods *methods;
        int i;
+       bool need_repack;
 
        if (tdb->transaction == NULL) {
                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n"));
@@ -1056,10 +1062,16 @@ int tdb_transaction_commit(struct tdb_context *tdb)
        utime(tdb->name, NULL);
 #endif
 
+       need_repack = tdb->transaction->need_repack;
+
        /* use a transaction cancel to free memory and remove the
           transaction locks */
        tdb_transaction_cancel(tdb);
 
+       if (need_repack) {
+               return tdb_repack(tdb);
+       }
+
        return 0;
 }