]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ps/fsync-refs-fix' into maint-2.39
authorJunio C Hamano <gitster@pobox.com>
Tue, 14 Feb 2023 22:15:50 +0000 (14:15 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 14 Feb 2023 22:15:50 +0000 (14:15 -0800)
Fix the sequence to fsync $GIT_DIR/packed-refs file that forgot to
flush its output to the disk..

* ps/fsync-refs-fix:
  refs: fix corruption by not correctly syncing packed-refs to disk

1  2 
refs/packed-backend.c

diff --combined refs/packed-backend.c
index c1c71d183ea3c0baf082b16cf18bc373a7615fe3,62b564459652db6a7a7eab2b2d9f77c8ffa69080..6f5a0709fba65e80081fdb04563019e1f1e15400
@@@ -726,7 -726,7 +726,7 @@@ static struct snapshot *get_snapshot(st
  }
  
  static int packed_read_raw_ref(struct ref_store *ref_store, const char *refname,
 -                             struct object_id *oid, struct strbuf *referent,
 +                             struct object_id *oid, struct strbuf *referent UNUSED,
                               unsigned int *type, int *failure_errno)
  {
        struct packed_ref_store *refs =
@@@ -862,7 -862,7 +862,7 @@@ static int packed_ref_iterator_advance(
  
        while ((ok = next_record(iter)) == ITER_OK) {
                if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
 -                  ref_type(iter->base.refname) != REF_TYPE_PER_WORKTREE)
 +                  !is_per_worktree_ref(iter->base.refname))
                        continue;
  
                if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
@@@ -911,9 -911,9 +911,9 @@@ static int packed_ref_iterator_abort(st
  }
  
  static struct ref_iterator_vtable packed_ref_iterator_vtable = {
 -      packed_ref_iterator_advance,
 -      packed_ref_iterator_peel,
 -      packed_ref_iterator_abort
 +      .advance = packed_ref_iterator_advance,
 +      .peel = packed_ref_iterator_peel,
 +      .abort = packed_ref_iterator_abort
  };
  
  static struct ref_iterator *packed_ref_iterator_begin(
@@@ -1078,8 -1078,7 +1078,8 @@@ int packed_refs_is_locked(struct ref_st
  static const char PACKED_REFS_HEADER[] =
        "# pack-refs with: peeled fully-peeled sorted \n";
  
 -static int packed_init_db(struct ref_store *ref_store, struct strbuf *err)
 +static int packed_init_db(struct ref_store *ref_store UNUSED,
 +                        struct strbuf *err UNUSED)
  {
        /* Nothing to do. */
        return 0;
@@@ -1263,7 -1262,8 +1263,8 @@@ static int write_with_updates(struct pa
                goto error;
        }
  
-       if (fsync_component(FSYNC_COMPONENT_REFERENCE, get_tempfile_fd(refs->tempfile)) ||
+       if (fflush(out) ||
+           fsync_component(FSYNC_COMPONENT_REFERENCE, get_tempfile_fd(refs->tempfile)) ||
            close_tempfile_gently(refs->tempfile)) {
                strbuf_addf(err, "error closing file %s: %s",
                            get_tempfile_path(refs->tempfile),
@@@ -1474,7 -1474,7 +1475,7 @@@ failure
  
  static int packed_transaction_abort(struct ref_store *ref_store,
                                    struct ref_transaction *transaction,
 -                                  struct strbuf *err)
 +                                  struct strbuf *err UNUSED)
  {
        struct packed_ref_store *refs = packed_downcast(
                        ref_store,
@@@ -1513,7 -1513,7 +1514,7 @@@ cleanup
        return ret;
  }
  
 -static int packed_initial_transaction_commit(struct ref_store *ref_store,
 +static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED,
                                            struct ref_transaction *transaction,
                                            struct strbuf *err)
  {
  static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
                             struct string_list *refnames, unsigned int flags)
  {
 +      struct packed_ref_store *refs =
 +              packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
        struct strbuf err = STRBUF_INIT;
        struct ref_transaction *transaction;
 +      struct string_list_item *item;
        int ret;
  
 +      (void)refs; /* We need the check above, but don't use the variable */
 +
        if (!refnames->nr)
                return 0;
  
         * updates into a single transaction.
         */
  
 -      transaction = ref_store_transaction_begin(ref_store, 0, &err);
 +      transaction = ref_store_transaction_begin(ref_store, &err);
        if (!transaction)
                return -1;
  
 -      ret = packed_refs_delete_refs(ref_store, transaction,
 -                                    msg, refnames, flags);
 -
 -      ref_transaction_free(transaction);
 -      return ret;
 -}
 -
 -int packed_refs_delete_refs(struct ref_store *ref_store,
 -                          struct ref_transaction *transaction,
 -                          const char *msg,
 -                          struct string_list *refnames,
 -                          unsigned int flags)
 -{
 -      struct strbuf err = STRBUF_INIT;
 -      struct string_list_item *item;
 -      int ret;
 -
 -      /* Assert that the ref store refers to a packed backend. */
 -      packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
 -
        for_each_string_list_item(item, refnames) {
                if (ref_transaction_delete(transaction, item->string, NULL,
                                           flags, msg, &err)) {
                        error(_("could not delete references: %s"), err.buf);
        }
  
 +      ref_transaction_free(transaction);
        strbuf_release(&err);
        return ret;
  }
  
 -static int packed_pack_refs(struct ref_store *ref_store, unsigned int flags)
 +static int packed_pack_refs(struct ref_store *ref_store UNUSED,
 +                          unsigned int flags UNUSED)
  {
        /*
         * Packed refs are already packed. It might be that loose refs
        return 0;
  }
  
 -static int packed_create_symref(struct ref_store *ref_store,
 -                             const char *refname, const char *target,
 -                             const char *logmsg)
 -{
 -      BUG("packed reference store does not support symrefs");
 -}
 -
 -static int packed_rename_ref(struct ref_store *ref_store,
 -                          const char *oldrefname, const char *newrefname,
 -                          const char *logmsg)
 -{
 -      BUG("packed reference store does not support renaming references");
 -}
 -
 -static int packed_copy_ref(struct ref_store *ref_store,
 -                         const char *oldrefname, const char *newrefname,
 -                         const char *logmsg)
 -{
 -      BUG("packed reference store does not support copying references");
 -}
 -
 -static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store)
 +static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store UNUSED)
  {
        return empty_ref_iterator_begin();
  }
  
 -static int packed_for_each_reflog_ent(struct ref_store *ref_store,
 -                                    const char *refname,
 -                                    each_reflog_ent_fn fn, void *cb_data)
 -{
 -      BUG("packed reference store does not support reflogs");
 -      return 0;
 -}
 -
 -static int packed_for_each_reflog_ent_reverse(struct ref_store *ref_store,
 -                                            const char *refname,
 -                                            each_reflog_ent_fn fn,
 -                                            void *cb_data)
 -{
 -      BUG("packed reference store does not support reflogs");
 -      return 0;
 -}
 -
 -static int packed_reflog_exists(struct ref_store *ref_store,
 -                             const char *refname)
 -{
 -      BUG("packed reference store does not support reflogs");
 -      return 0;
 -}
 -
 -static int packed_create_reflog(struct ref_store *ref_store,
 -                              const char *refname, struct strbuf *err)
 -{
 -      BUG("packed reference store does not support reflogs");
 -}
 -
 -static int packed_delete_reflog(struct ref_store *ref_store,
 -                             const char *refname)
 -{
 -      BUG("packed reference store does not support reflogs");
 -      return 0;
 -}
 -
 -static int packed_reflog_expire(struct ref_store *ref_store,
 -                              const char *refname,
 -                              unsigned int flags,
 -                              reflog_expiry_prepare_fn prepare_fn,
 -                              reflog_expiry_should_prune_fn should_prune_fn,
 -                              reflog_expiry_cleanup_fn cleanup_fn,
 -                              void *policy_cb_data)
 -{
 -      BUG("packed reference store does not support reflogs");
 -      return 0;
 -}
 -
  struct ref_storage_be refs_be_packed = {
 -      NULL,
 -      "packed",
 -      packed_ref_store_create,
 -      packed_init_db,
 -      packed_transaction_prepare,
 -      packed_transaction_finish,
 -      packed_transaction_abort,
 -      packed_initial_transaction_commit,
 -
 -      packed_pack_refs,
 -      packed_create_symref,
 -      packed_delete_refs,
 -      packed_rename_ref,
 -      packed_copy_ref,
 -
 -      packed_ref_iterator_begin,
 -      packed_read_raw_ref,
 -
 -      packed_reflog_iterator_begin,
 -      packed_for_each_reflog_ent,
 -      packed_for_each_reflog_ent_reverse,
 -      packed_reflog_exists,
 -      packed_create_reflog,
 -      packed_delete_reflog,
 -      packed_reflog_expire
 +      .next = NULL,
 +      .name = "packed",
 +      .init = packed_ref_store_create,
 +      .init_db = packed_init_db,
 +      .transaction_prepare = packed_transaction_prepare,
 +      .transaction_finish = packed_transaction_finish,
 +      .transaction_abort = packed_transaction_abort,
 +      .initial_transaction_commit = packed_initial_transaction_commit,
 +
 +      .pack_refs = packed_pack_refs,
 +      .create_symref = NULL,
 +      .delete_refs = packed_delete_refs,
 +      .rename_ref = NULL,
 +      .copy_ref = NULL,
 +
 +      .iterator_begin = packed_ref_iterator_begin,
 +      .read_raw_ref = packed_read_raw_ref,
 +      .read_symbolic_ref = NULL,
 +
 +      .reflog_iterator_begin = packed_reflog_iterator_begin,
 +      .for_each_reflog_ent = NULL,
 +      .for_each_reflog_ent_reverse = NULL,
 +      .reflog_exists = NULL,
 +      .create_reflog = NULL,
 +      .delete_reflog = NULL,
 +      .reflog_expire = NULL,
  };