[PATCH 2/6] object-file: propagate files transaction errors
From: Justin Tobler <hidden>
Date: 2026-06-24 04:19:30
Subsystem:
the rest · Maintainer:
Linus Torvalds
The "files" transaction backend may encounter errors related to managing
the temporary directory used to stage objects, but silently ignores
these errors. Instead return errors encountered in the
`odb_transaction_files_{prepare,begin,commit}()` interfaces to allow
callers to handle as needed.
Signed-off-by: Justin Tobler <redacted>
---
object-file.c | 41 ++++++++++++++++++++++++++++-------------
object-file.h | 5 +++--
odb/source-files.c | 6 +-----
odb/transaction.h | 2 +-
4 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/object-file.c b/object-file.c
index a3eb8d71dd..18c2df75fb 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 -1; + + tmp_objdir_replace_primary_odb(transaction->objdir, 0); + + return 0; } static void fsync_loose_object_transaction(struct odb_transaction *base,
@@ -542,13 +546,13 @@ static void fsync_loose_object_transaction(struct odb_transaction *base, /* * Cleanup after batch-mode fsync_object_files. */ -static void flush_loose_object_transaction(struct odb_transaction_files *transaction) +static int flush_loose_object_transaction(struct odb_transaction_files *transaction) { struct strbuf temp_path = STRBUF_INIT; struct tempfile *temp; if (!transaction->objdir) - return; + return 0; /* * Issue a full hardware flush against a temporary file to ensure
@@ -570,8 +574,12 @@ static void flush_loose_object_transaction(struct odb_transaction_files *transac * 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 -1; + transaction->objdir = NULL; + + return 0; } /* Finalize a file on disk, and close it. */
@@ -1670,27 +1678,34 @@ int read_loose_object(struct repository *repo, 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); - flush_loose_object_transaction(transaction); + if (flush_loose_object_transaction(transaction)) + return -1; 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; struct object_database *odb = source->odb; - if (odb->transaction) - return NULL; + if (odb->transaction) { + *out = NULL; + return 0; + } transaction = xcalloc(1, sizeof(*transaction)); 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 528c4e6e69..ac927fec07 100644
--- a/object-file.h
+++ b/object-file.h@@ -195,8 +195,9 @@ struct odb_transaction; * Tell the object database to optimize for adding * multiple objects. odb_transaction_files_commit must be called * to make new objects visible. If a transaction is already - * pending, NULL is returned. + * pending, out is set to NULL. */ -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..f4c1ebfaaa 100644
--- a/odb/transaction.h
+++ b/odb/transaction.h@@ -17,7 +17,7 @@ struct odb_transaction { struct odb_source *source; /* The ODB source specific callback invoked to commit a transaction. */ - void (*commit)(struct odb_transaction *transaction); + int (*commit)(struct odb_transaction *transaction); /* * This callback is expected to write the given object stream into
--
2.54.0.105.g59ff4886a5