X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb%2Ftransaction.c;h=0944bb36e98a6a3af4e32ac2052e512483bc4311;hp=4c261598972dad139442abc12e03ed3a37cc5379;hb=059678ec4216112f96d8ad992ec7c0b8a6e3b80b;hpb=03c1876179e48121ab2bb445053fcb8371f36e5e;ds=sidebyside diff --git a/ccan/tdb/transaction.c b/ccan/tdb/transaction.c index 4c261598..0944bb36 100644 --- a/ccan/tdb/transaction.c +++ b/ccan/tdb/transaction.c @@ -127,6 +127,9 @@ struct tdb_transaction { /* 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; } + tdb->transaction->need_repack = true; + return 0; } @@ -423,6 +428,10 @@ static const struct tdb_methods transaction_methods = { */ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) { + if (tdb->flags & TDB_NOSYNC) { + return 0; + } + if (fsync(tdb->fd) != 0) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); @@ -989,6 +998,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")); @@ -1066,11 +1076,9 @@ int tdb_transaction_commit(struct tdb_context *tdb) SAFE_FREE(tdb->transaction->blocks); tdb->transaction->num_blocks = 0; - if (!(tdb->flags & TDB_NOSYNC)) { - /* ensure the new data is on disk */ - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - return -1; - } + /* ensure the new data is on disk */ + if (transaction_sync(tdb, 0, tdb->map_size) == -1) { + return -1; } tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); @@ -1090,10 +1098,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_internal(tdb); + if (need_repack) { + return tdb_repack(tdb); + } + return 0; }