]> git.ozlabs.org Git - ccan/commitdiff
Import from SAMBA tdb:
authorRusty Russell <rusty@rustcorp.com.au>
Wed, 29 Jul 2009 23:18:53 +0000 (08:48 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Wed, 29 Jul 2009 23:18:53 +0000 (08:48 +0930)
commit a386173fa1c7c5bcc11ea9260d84b6c52c154b3d
Author: Andrew Tridgell <tridge@samba.org>
Date:   Mon Jun 1 13:11:39 2009 +1000

    auto-repack in transactions that expand the tdb

    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.

ccan/tdb/transaction.c

index 1086c5f037793d9df00269ff78b14ae2ad126e72..0944bb36e98a6a3af4e32ac2052e512483bc4311 100644 (file)
@@ -127,6 +127,9 @@ struct tdb_transaction {
 
        /* old file size before transaction */
        tdb_len_t old_map_size;
 
        /* old file size before transaction */
        tdb_len_t old_map_size;
+
+       /* we should re-pack on commit */
+       bool need_repack;
 };
 
 
 };
 
 
@@ -397,6 +400,8 @@ static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size,
                return -1;
        }
 
                return -1;
        }
 
+       tdb->transaction->need_repack = true;
+
        return 0;
 }
 
        return 0;
 }
 
@@ -993,6 +998,7 @@ int tdb_transaction_commit(struct tdb_context *tdb)
 {      
        const struct tdb_methods *methods;
        int i;
 {      
        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"));
 
        if (tdb->transaction == NULL) {
                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n"));
@@ -1092,10 +1098,16 @@ int tdb_transaction_commit(struct tdb_context *tdb)
        utime(tdb->name, NULL);
 #endif
 
        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_internal(tdb);
 
        /* use a transaction cancel to free memory and remove the
           transaction locks */
        tdb_transaction_cancel_internal(tdb);
 
+       if (need_repack) {
+               return tdb_repack(tdb);
+       }
+
        return 0;
 }
 
        return 0;
 }