diff --git a/object-file.c b/object-file.c index c16b2c2ac1..3d76b890b8 100644 --- a/object-file.c +++ b/object-file.c @@ -499,7 +499,7 @@ struct odb_transaction_files { struct transaction_packfile packfile; }; -static void odb_transaction_files_prepare(struct odb_transaction *base) +static int odb_transaction_files_prepare(struct odb_transaction *base) { struct odb_transaction_files *transaction = container_of_or_null(base, struct odb_transaction_files, base); @@ -511,11 +511,15 @@ static void odb_transaction_files_prepare(struct odb_transaction *base) * added at the time they call odb_transaction_files_begin. */ if (!transaction || transaction->objdir) - return; + return 0; transaction->objdir = tmp_objdir_create(base->source->odb->repo, "bulk-fsync"); - if (transaction->objdir) - tmp_objdir_replace_primary_odb(transaction->objdir, 0); + if (!transaction->objdir) + return error(_("unable to create temporary object directory")); + + tmp_objdir_replace_primary_odb(transaction->objdir, 0); + + return 0; } static void odb_transaction_files_fsync(struct odb_transaction *base, @@ -1637,7 +1641,7 @@ out: return ret; } -static void odb_transaction_files_commit(struct odb_transaction *base) +static int odb_transaction_files_commit(struct odb_transaction *base) { struct odb_transaction_files *transaction = container_of(base, struct odb_transaction_files, base); @@ -1666,14 +1670,19 @@ static void odb_transaction_files_commit(struct odb_transaction *base) * Make the object files visible in the primary ODB after their data is * fully durable. */ - tmp_objdir_migrate(transaction->objdir); + if (tmp_objdir_migrate(transaction->objdir)) + return error(_("unable to migrate temporary objects")); + transaction->objdir = NULL; } flush_packfile_transaction(transaction); + + return 0; } -struct odb_transaction *odb_transaction_files_begin(struct odb_source *source) +int odb_transaction_files_begin(struct odb_source *source, + struct odb_transaction **out) { struct odb_transaction_files *transaction; @@ -1681,6 +1690,7 @@ struct odb_transaction *odb_transaction_files_begin(struct odb_source *source) transaction->base.source = source; transaction->base.commit = odb_transaction_files_commit; transaction->base.write_object_stream = odb_transaction_files_write_object_stream; + *out = &transaction->base; - return &transaction->base; + return 0; } diff --git a/object-file.h b/object-file.h index ea43d818f0..1a023226ac 100644 --- a/object-file.h +++ b/object-file.h @@ -196,6 +196,7 @@ struct odb_transaction; * multiple objects. odb_transaction_files_commit must be called * to make new objects visible. */ -struct odb_transaction *odb_transaction_files_begin(struct odb_source *source); +int odb_transaction_files_begin(struct odb_source *source, + struct odb_transaction **out); #endif /* OBJECT_FILE_H */ diff --git a/odb/source-files.c b/odb/source-files.c index 5bdd042922..2545bd81d4 100644 --- a/odb/source-files.c +++ b/odb/source-files.c @@ -182,11 +182,7 @@ static int odb_source_files_write_object_stream(struct odb_source *source, static int odb_source_files_begin_transaction(struct odb_source *source, struct odb_transaction **out) { - struct odb_transaction *tx = odb_transaction_files_begin(source); - if (!tx) - return -1; - *out = tx; - return 0; + return odb_transaction_files_begin(source, out); } static int odb_source_files_read_alternates(struct odb_source *source, diff --git a/odb/transaction.h b/odb/transaction.h index 854fda06f5..d52f0533ce 100644 --- a/odb/transaction.h +++ b/odb/transaction.h @@ -16,8 +16,11 @@ struct odb_transaction { /* The ODB source the transaction is opened against. */ struct odb_source *source; - /* The ODB source specific callback invoked to commit a transaction. */ - void (*commit)(struct odb_transaction *transaction); + /* + * The ODB source specific callback invoked to commit a transaction. + * Returns 0 on success, a negative error code otherwise. + */ + int (*commit)(struct odb_transaction *transaction); /* * This callback is expected to write the given object stream into