Merge branch 'mh/import-transport-fd-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 13 Jun 2019 20:19:43 +0000 (13:19 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 13 Jun 2019 20:19:43 +0000 (13:19 -0700)
The ownership rule for the file descriptor to fast-import remote
backend was mixed up, leading to unrelated file descriptor getting
closed, which has been fixed.

* mh/import-transport-fd-fix:
Use xmmap_gently instead of xmmap in use_pack
dup() the input fd for fast-import used for remote helpers

1  2 
packfile.c
transport-helper.c
diff --combined packfile.c
index 49c8544ff4591e71e1845cd1b275d5fdb898b400,6a66b605e90f27c2e58949d4fe218ddafd1fbd01..d786ec731202e5d623a7558bec2168194db11514
@@@ -235,7 -235,7 +235,7 @@@ struct packed_git *parse_pack_index(uns
        struct packed_git *p = alloc_packed_git(alloc);
  
        memcpy(p->pack_name, path, alloc); /* includes NUL */
 -      hashcpy(p->sha1, sha1);
 +      hashcpy(p->hash, sha1);
        if (check_packed_git_idx(idx_path, p)) {
                free(p);
                return NULL;
@@@ -309,7 -309,7 +309,7 @@@ void close_pack_windows(struct packed_g
        }
  }
  
 -static int close_pack_fd(struct packed_git *p)
 +int close_pack_fd(struct packed_git *p)
  {
        if (p->pack_fd < 0)
                return 0;
@@@ -466,16 -466,6 +466,16 @@@ static unsigned int get_max_fd_limit(vo
  #endif
  }
  
 +const char *pack_basename(struct packed_git *p)
 +{
 +      const char *ret = strrchr(p->pack_name, '/');
 +      if (ret)
 +              ret = ret + 1; /* skip past slash */
 +      else
 +              ret = p->pack_name; /* we only have a base */
 +      return ret;
 +}
 +
  /*
   * Do not call this directly as this leaks p->pack_fd on error return;
   * call open_packed_git() instead.
@@@ -492,7 -482,7 +492,7 @@@ static int open_packed_git_1(struct pac
  
        if (!p->index_data) {
                struct multi_pack_index *m;
 -              const char *pack_name = strrchr(p->pack_name, '/');
 +              const char *pack_name = pack_basename(p);
  
                for (m = the_repository->objects->multi_pack_index;
                     m; m = m->next) {
@@@ -640,7 -630,7 +640,7 @@@ unsigned char *use_pack(struct packed_g
                        while (packed_git_limit < pack_mapped
                                && unuse_one_window(p))
                                ; /* nothing */
-                       win->base = xmmap(NULL, win->len,
+                       win->base = xmmap_gently(NULL, win->len,
                                PROT_READ, MAP_PRIVATE,
                                p->pack_fd, win->offset);
                        if (win->base == MAP_FAILED)
@@@ -732,8 -722,8 +732,8 @@@ struct packed_git *add_packed_git(cons
        p->pack_local = local;
        p->mtime = st.st_mtime;
        if (path_len < the_hash_algo->hexsz ||
 -          get_sha1_hex(path + path_len - the_hash_algo->hexsz, p->sha1))
 -              hashclr(p->sha1);
 +          get_sha1_hex(path + path_len - the_hash_algo->hexsz, p->hash))
 +              hashclr(p->hash);
        return p;
  }
  
@@@ -903,25 -893,25 +903,25 @@@ static void prepare_packed_git(struct r
   * all unreachable objects about to be pruned, in which case they're not really
   * interesting as a measure of repo size in the first place.
   */
 -unsigned long approximate_object_count(void)
 +unsigned long repo_approximate_object_count(struct repository *r)
  {
 -      if (!the_repository->objects->approximate_object_count_valid) {
 +      if (!r->objects->approximate_object_count_valid) {
                unsigned long count;
                struct multi_pack_index *m;
                struct packed_git *p;
  
 -              prepare_packed_git(the_repository);
 +              prepare_packed_git(r);
                count = 0;
 -              for (m = get_multi_pack_index(the_repository); m; m = m->next)
 +              for (m = get_multi_pack_index(r); m; m = m->next)
                        count += m->num_objects;
 -              for (p = the_repository->objects->packed_git; p; p = p->next) {
 +              for (p = r->objects->packed_git; p; p = p->next) {
                        if (open_pack_index(p))
                                continue;
                        count += p->num_objects;
                }
 -              the_repository->objects->approximate_object_count = count;
 +              r->objects->approximate_object_count = count;
        }
 -      return the_repository->objects->approximate_object_count;
 +      return r->objects->approximate_object_count;
  }
  
  static void *get_next_packed_git(const void *p)
@@@ -994,6 -984,8 +994,6 @@@ static void prepare_packed_git(struct r
        }
        rearrange_packed_git(r);
  
 -      r->objects->all_packs = NULL;
 -
        prepare_packed_git_mru(r);
        r->objects->packed_git_initialized = 1;
  }
@@@ -1024,16 -1016,26 +1024,16 @@@ struct multi_pack_index *get_multi_pack
  
  struct packed_git *get_all_packs(struct repository *r)
  {
 -      prepare_packed_git(r);
 -
 -      if (!r->objects->all_packs) {
 -              struct packed_git *p = r->objects->packed_git;
 -              struct multi_pack_index *m;
 -
 -              for (m = r->objects->multi_pack_index; m; m = m->next) {
 -                      uint32_t i;
 -                      for (i = 0; i < m->num_packs; i++) {
 -                              if (!prepare_midx_pack(m, i)) {
 -                                      m->packs[i]->next = p;
 -                                      p = m->packs[i];
 -                              }
 -                      }
 -              }
 +      struct multi_pack_index *m;
  
 -              r->objects->all_packs = p;
 +      prepare_packed_git(r);
 +      for (m = r->objects->multi_pack_index; m; m = m->next) {
 +              uint32_t i;
 +              for (i = 0; i < m->num_packs; i++)
 +                      prepare_midx_pack(r, m, i);
        }
  
 -      return r->objects->all_packs;
 +      return r->objects->packed_git;
  }
  
  struct list_head *get_packed_git_mru(struct repository *r)
@@@ -1986,13 -1988,13 +1986,13 @@@ int find_pack_entry(struct repository *
                return 0;
  
        for (m = r->objects->multi_pack_index; m; m = m->next) {
 -              if (fill_midx_entry(oid, e, m))
 +              if (fill_midx_entry(r, oid, e, m))
                        return 1;
        }
  
        list_for_each(pos, &r->objects->packed_git_mru) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
 -              if (fill_pack_entry(oid, e, p)) {
 +              if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) {
                        list_move(&p->mru, &r->objects->packed_git_mru);
                        return 1;
                }
@@@ -2021,10 -2023,8 +2021,10 @@@ int for_each_object_in_pack(struct pack
        uint32_t i;
        int r = 0;
  
 -      if (flags & FOR_EACH_OBJECT_PACK_ORDER)
 -              load_pack_revindex(p);
 +      if (flags & FOR_EACH_OBJECT_PACK_ORDER) {
 +              if (load_pack_revindex(p))
 +                      return -1;
 +      }
  
        for (i = 0; i < p->num_objects; i++) {
                uint32_t pos;
diff --combined transport-helper.c
index cec83bd663d0f27589bd09176e38b084270f56c4,29787b749ec9825a7c2e25e4dad1c138d1012834..c7e17ec9cb61e6782bc255e6b90381054255c269
@@@ -127,8 -127,6 +127,8 @@@ static struct child_process *get_helper
                argv_array_pushf(&helper->env_array, "%s=%s",
                                 GIT_DIR_ENVIRONMENT, get_git_dir());
  
 +      helper->trace2_child_class = helper->args.argv[0]; /* "remote-<name>" */
 +
        code = start_command(helper);
        if (code < 0 && errno == ENOENT)
                die(_("unable to find remote helper for '%s'"), data->name);
@@@ -423,7 -421,7 +423,7 @@@ static int get_importer(struct transpor
        struct helper_data *data = transport->data;
        int cat_blob_fd, code;
        child_process_init(fastimport);
-       fastimport->in = helper->out;
+       fastimport->in = xdup(helper->out);
        argv_array_push(&fastimport->args, "fast-import");
        argv_array_push(&fastimport->args, debug ? "--stats" : "--quiet");