X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Ftdb1_transaction.c;h=411caef360d4ff5e1353b60263e7252d87d9ef1f;hp=fa6ffda379d2d706165c8c9a534168b5cdfbe56c;hb=614259f13c3e694fcd6b57fc05a329066e43c76d;hpb=bbeb528e74c0e234e1f724ac8d54be404cfc6f9a diff --git a/ccan/tdb2/tdb1_transaction.c b/ccan/tdb2/tdb1_transaction.c index fa6ffda3..411caef3 100644 --- a/ccan/tdb2/tdb1_transaction.c +++ b/ccan/tdb2/tdb1_transaction.c @@ -418,20 +418,37 @@ static const struct tdb1_methods transaction1_methods = { static int _tdb1_transaction_start(struct tdb_context *tdb) { /* some sanity checks */ - if ((tdb->flags & TDB_RDONLY) || (tdb->flags & TDB_INTERNAL) || tdb->tdb1.traverse_read) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, - "tdb1_transaction_start: cannot start a" - " transaction on a read-only or" - " internal db"); + if (tdb->flags & TDB_INTERNAL) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb1_transaction_start:" + " cannot start a" + " transaction on an" + " internal tdb"); + return -1; + } + + if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_RDONLY, + TDB_LOG_USE_ERROR, + "tdb_transaction_start:" + " cannot start a" + " transaction on a " + " read-only tdb"); return -1; } /* cope with nested tdb1_transaction_start() calls */ if (tdb->tdb1.transaction != NULL) { if (!(tdb->flags & TDB_ALLOW_NESTING)) { - tdb->last_error = TDB_ERR_EINVAL; + tdb->last_error + = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_transaction_start:" + " already inside transaction"); return -1; } + tdb->stats.transaction_nest++; tdb->tdb1.transaction->nesting++; return 0; } @@ -511,6 +528,7 @@ static int _tdb1_transaction_start(struct tdb_context *tdb) tdb->tdb1.transaction->io_methods = tdb->tdb1.io; tdb->tdb1.io = &transaction1_methods; + tdb->stats.transactions++; return 0; fail: @@ -621,6 +639,7 @@ static int _tdb1_transaction_cancel(struct tdb_context *tdb) */ int tdb1_transaction_cancel(struct tdb_context *tdb) { + tdb->stats.transaction_cancel++; return _tdb1_transaction_cancel(tdb); } @@ -739,6 +758,7 @@ static int tdb1_recovery_allocate(struct tdb_context *tdb, " failed to create recovery area"); return -1; } + tdb->stats.transaction_expand_file++; /* remap the file (if using mmap) */ methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); @@ -1000,6 +1020,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb_context *tdb) " expansion failed"); return -1; } + tdb->stats.transaction_expand_file++; tdb->file->map_size = tdb->tdb1.transaction->old_map_size; methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); } @@ -1153,7 +1174,8 @@ int tdb1_transaction_commit(struct tdb_context *tdb) _tdb1_transaction_cancel(tdb); if (need_repack) { - return tdb1_repack(tdb); + if (tdb_repack(tdb) != 0) + return -1; } return 0; @@ -1289,14 +1311,14 @@ int tdb1_transaction_recover(struct tdb_context *tdb) } /* Any I/O failures we say "needs recovery". */ -bool tdb1_needs_recovery(struct tdb_context *tdb) +tdb_bool_err tdb1_needs_recovery(struct tdb_context *tdb) { tdb1_off_t recovery_head; struct tdb1_record rec; /* find the recovery area */ if (tdb1_ofs_read(tdb, TDB1_RECOVERY_HEAD, &recovery_head) == -1) { - return true; + return TDB_ERR_TO_OFF(tdb->last_error); } if (recovery_head == 0) { @@ -1307,7 +1329,7 @@ bool tdb1_needs_recovery(struct tdb_context *tdb) /* read the recovery record */ if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) { - return true; + return TDB_ERR_TO_OFF(tdb->last_error); } return (rec.magic == TDB1_RECOVERY_MAGIC);