]> git.ipfire.org Git - thirdparty/git.git/commitdiff
object-file: propagate files transaction errors
authorJustin Tobler <jltobler@gmail.com>
Fri, 10 Jul 2026 16:37:16 +0000 (11:37 -0500)
committerJunio C Hamano <gitster@pobox.com>
Fri, 10 Jul 2026 20:21:53 +0000 (13:21 -0700)
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 them as needed.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file.c
object-file.h
odb/source-files.c
odb/transaction.h

index c16b2c2ac1c225567cec3f012f791fe38a9f0f44..3d76b890b8d5e9f2cdbc74483f62df233fc6be3e 100644 (file)
@@ -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;
 }
index ea43d818f096cb3b5a7053ddadc6e213c57a738f..1a023226ac7cd330ac4edbd4aae72e71783ead6c 100644 (file)
@@ -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 */
index 5bdd04292253971fdfc3cb60fb9f1201a6075f2e..2545bd81d448b0b0bdc3689d30a036bb3d7a5247 100644 (file)
@@ -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,
index 854fda06f576e49ac7f3c3427b583cb71b62c37a..d52f0533ce3ee8608198f2abcec710edaf2bfe76 100644 (file)
@@ -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