Coverage Report

Created: 2026-10-17 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/odb/source-packed.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "abspath.h"
3
#include "chdir-notify.h"
4
#include "dir.h"
5
#include "gettext.h"
6
#include "fsck.h"
7
#include "git-zlib.h"
8
#include "hex.h"
9
#include "list-objects-filter-options.h"
10
#include "mergesort.h"
11
#include "midx.h"
12
#include "odb/source-packed.h"
13
#include "odb/streaming.h"
14
#include "pack.h"
15
#include "pack-revindex.h"
16
#include "packfile.h"
17
#include "pack-bitmap.h"
18
#include "strbuf.h"
19
#include "progress.h"
20
#include "run-command.h"
21
22
static int find_pack_entry(struct odb_source_packed *store,
23
         const struct object_id *oid,
24
         struct pack_entry *e,
25
         enum object_info_flags flags,
26
         struct packed_git **bad_pack)
27
0
{
28
0
  struct packfile_list_entry *l;
29
0
  enum midx_fill_result midx_result = MIDX_FILL_MISS;
30
31
0
  odb_source_prepare(&store->base, 0);
32
0
  if (store->midx) {
33
0
    midx_result = midx_fill_entry(store->midx, oid, e, bad_pack);
34
0
    if (midx_result == MIDX_FILL_HIT)
35
0
      return 1;
36
0
  }
37
38
0
  for (l = store->packs.head; l; l = l->next) {
39
0
    struct packed_git *p = l->pack;
40
41
0
    if (!p->multi_pack_index && packfile_fill_entry(p, oid, e, bad_pack)) {
42
0
      if (!store->skip_mru_updates)
43
0
        packfile_list_prepend(&store->packs, p);
44
0
      return 1;
45
0
    }
46
0
  }
47
48
  /*
49
   * Recovery for a concurrent-repack race: a stale MIDX may still name a
50
   * vanished owning pack even though the object survives in another pack
51
   * the same MIDX covers.  The regular fallback above skips MIDX-covered
52
   * packs, and repreparing the on-disk pack set does not reload the
53
   * borrowed, cached MIDX, so scan its packs directly for the survivor.
54
   *
55
   * Do this only on the second read, by which point repreparing packs has
56
   * already had a chance to find an object merely relocated into a new,
57
   * uncovered pack; only a genuine hidden duplicate reaches here.
58
   */
59
0
  if (midx_result == MIDX_FILL_OWNER_UNAVAILABLE &&
60
0
      (flags & OBJECT_INFO_SECOND_READ)) {
61
0
    struct multi_pack_index *m = store->midx;
62
0
    uint32_t i;
63
64
0
    for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
65
0
      struct packed_git *p;
66
67
0
      if (prepare_midx_pack(m, i))
68
0
        continue;
69
0
      p = nth_midxed_pack(m, i);
70
0
      if (p && packfile_fill_entry(p, oid, e, bad_pack))
71
0
        return 1;
72
0
    }
73
0
  }
74
75
0
  return 0;
76
0
}
77
78
static enum odb_read_status odb_source_packed_read_object_info(struct odb_source *source,
79
                     const struct object_id *oid,
80
                     struct object_info *oi,
81
                     enum object_info_flags flags,
82
                     struct strbuf *errmsg)
83
0
{
84
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
85
0
  struct packed_git *bad_pack = NULL;
86
0
  struct pack_entry e;
87
0
  int ret;
88
89
  /*
90
   * In case the first read didn't surface the object, we have to reload
91
   * packfiles. This may cause us to discover new packfiles that have
92
   * been added since the last time we have prepared the packfile store.
93
   */
94
0
  if (flags & OBJECT_INFO_SECOND_READ)
95
0
    odb_source_prepare(source, ODB_PREPARE_FLUSH_CACHES);
96
97
0
  if (!find_pack_entry(packed, oid, &e, flags, &bad_pack)) {
98
    /*
99
     * The lookup may have failed because the object is known to be
100
     * corrupt in one of the packfiles. Report the object as
101
     * corrupt instead of missing in that case.
102
     */
103
0
    if (bad_pack) {
104
0
      ret = -1;
105
0
      goto out;
106
0
    }
107
108
0
    ret = ODB_READ_NOT_FOUND;
109
0
    goto out;
110
0
  }
111
112
  /*
113
   * We know that the caller doesn't actually need the
114
   * information below, so return early.
115
   */
116
0
  if (!oi) {
117
0
    ret = 0;
118
0
    goto out;
119
0
  }
120
121
0
  ret = packed_object_info(packed, e.p, e.offset, oi);
122
0
  if (ret < 0) {
123
0
    bad_pack = e.p;
124
0
    mark_bad_packed_object(e.p, oid);
125
0
    goto out;
126
0
  }
127
128
0
  ret = 0;
129
130
0
out:
131
0
  if (ret < 0 && bad_pack && errmsg)
132
0
    strbuf_addf(errmsg, _("packed object %s (stored in %s) is corrupt"),
133
0
          oid_to_hex(oid), bad_pack->pack_name);
134
135
0
  return ret;
136
0
}
137
138
static int odb_source_packed_read_object_stream(struct odb_stream **out,
139
            struct odb_source *source,
140
            const struct object_id *oid)
141
0
{
142
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
143
0
  struct pack_entry e;
144
145
0
  if (!find_pack_entry(packed, oid, &e, 0, NULL))
146
0
    return -1;
147
148
0
  return packfile_read_object_stream(out, oid, e.p, e.offset);
149
0
}
150
151
struct odb_source_packed_for_each_object_wrapper_data {
152
  struct odb_source_packed *store;
153
  const struct object_info *request;
154
  odb_for_each_object_cb cb;
155
  void *cb_data;
156
};
157
158
static int odb_source_packed_for_each_object_wrapper(const struct object_id *oid,
159
                 struct packed_git *pack,
160
                 uint32_t index_pos,
161
                 void *cb_data)
162
0
{
163
0
  struct odb_source_packed_for_each_object_wrapper_data *data = cb_data;
164
165
0
  if (data->request) {
166
0
    off_t offset = nth_packed_object_offset(pack, index_pos);
167
0
    struct object_info oi = *data->request;
168
169
0
    if (packed_object_info_with_index_pos(data->store, pack, offset,
170
0
                  &index_pos, &oi) < 0) {
171
0
      mark_bad_packed_object(pack, oid);
172
0
      return -1;
173
0
    }
174
175
0
    return data->cb(oid, &oi, data->cb_data);
176
0
  } else {
177
0
    return data->cb(oid, NULL, data->cb_data);
178
0
  }
179
0
}
180
181
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
182
0
{
183
0
  do {
184
0
    if (*a != *b)
185
0
      return 0;
186
0
    a++;
187
0
    b++;
188
0
    len -= 2;
189
0
  } while (len > 1);
190
0
  if (len)
191
0
    if ((*a ^ *b) & 0xf0)
192
0
      return 0;
193
0
  return 1;
194
0
}
195
196
static bool should_exclude_pack(struct packed_git *p, enum odb_for_each_object_flags flags)
197
0
{
198
0
  if ((flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
199
0
    return true;
200
0
  if ((flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
201
0
      !p->pack_promisor)
202
0
    return true;
203
0
  if ((flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
204
0
      p->pack_keep_in_core)
205
0
    return true;
206
0
  if ((flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
207
0
      p->pack_keep)
208
0
    return true;
209
0
  return false;
210
0
}
211
212
static int for_each_prefixed_object_in_midx(
213
  struct odb_source_packed *source,
214
  struct multi_pack_index *m,
215
  const struct odb_for_each_object_options *opts,
216
  struct odb_source_packed_for_each_object_wrapper_data *data)
217
0
{
218
0
  bool pack_errors = false;
219
0
  int ret;
220
221
0
  for (; m; m = m->base_midx) {
222
0
    uint32_t num, i, first = 0;
223
0
    int len = opts->prefix_hex_len > m->source->base.odb->repo->hash_algo->hexsz ?
224
0
      m->source->base.odb->repo->hash_algo->hexsz : opts->prefix_hex_len;
225
226
0
    if (!m->num_objects)
227
0
      continue;
228
229
0
    num = m->num_objects + m->num_objects_in_base;
230
231
0
    bsearch_one_midx(opts->prefix, m, &first);
232
233
    /*
234
     * At this point, "first" is the location of the lowest
235
     * object with an object name that could match "opts->prefix".
236
     * See if we have 0, 1 or more objects that actually match(es).
237
     */
238
0
    for (i = first; i < num; i++) {
239
0
      const struct object_id *current = NULL;
240
0
      struct packed_git *pack;
241
0
      struct object_id oid;
242
243
0
      current = nth_midxed_object_oid(&oid, m, i);
244
245
0
      if (!match_hash(len, opts->prefix->hash, current->hash))
246
0
        break;
247
248
0
      if (opts->flags || data->request) {
249
0
        uint32_t pack_id = nth_midxed_pack_int_id(m, i);
250
251
0
        if (prepare_midx_pack(m, pack_id)) {
252
0
          pack_errors = true;
253
0
          continue;
254
0
        }
255
256
0
        pack = nth_midxed_pack(m, pack_id);
257
0
        if (should_exclude_pack(pack, opts->flags))
258
0
          continue;
259
0
      }
260
261
0
      if (data->request) {
262
0
        struct object_info oi = *data->request;
263
0
        off_t offset = nth_midxed_offset(m, i);
264
265
0
        ret = packed_object_info(source, pack, offset, &oi);
266
0
        if (ret)
267
0
          goto out;
268
269
0
        ret = data->cb(&oid, &oi, data->cb_data);
270
0
        if (ret)
271
0
          goto out;
272
0
      } else {
273
0
        ret = data->cb(&oid, NULL, data->cb_data);
274
0
        if (ret)
275
0
          goto out;
276
0
      }
277
0
    }
278
0
  }
279
280
0
  ret = 0;
281
282
0
out:
283
0
  if (!ret && pack_errors)
284
0
    ret = -1;
285
0
  return ret;
286
0
}
287
288
static int for_each_prefixed_object_in_pack(
289
  struct odb_source_packed *source,
290
  struct packed_git *p,
291
  const struct odb_for_each_object_options *opts,
292
  struct odb_source_packed_for_each_object_wrapper_data *data)
293
0
{
294
0
  uint32_t num, i, first = 0;
295
0
  int len = opts->prefix_hex_len > p->repo->hash_algo->hexsz ?
296
0
    p->repo->hash_algo->hexsz : opts->prefix_hex_len;
297
0
  int ret;
298
299
0
  num = p->num_objects;
300
0
  bsearch_pack(opts->prefix, p, &first);
301
302
  /*
303
   * At this point, "first" is the location of the lowest object
304
   * with an object name that could match "bin_pfx".  See if we have
305
   * 0, 1 or more objects that actually match(es).
306
   */
307
0
  for (i = first; i < num; i++) {
308
0
    struct object_id oid;
309
310
0
    nth_packed_object_id(&oid, p, i);
311
0
    if (!match_hash(len, opts->prefix->hash, oid.hash))
312
0
      break;
313
314
0
    if (data->request) {
315
0
      struct object_info oi = *data->request;
316
0
      off_t offset = nth_packed_object_offset(p, i);
317
318
0
      ret = packed_object_info(source, p, offset, &oi);
319
0
      if (ret)
320
0
        goto out;
321
322
0
      ret = data->cb(&oid, &oi, data->cb_data);
323
0
      if (ret)
324
0
        goto out;
325
0
    } else {
326
0
      ret = data->cb(&oid, NULL, data->cb_data);
327
0
      if (ret)
328
0
        goto out;
329
0
    }
330
0
  }
331
332
0
  ret = 0;
333
334
0
out:
335
0
  return ret;
336
0
}
337
338
static int odb_source_packed_for_each_prefixed_object(
339
  struct odb_source_packed *store,
340
  const struct odb_for_each_object_options *opts,
341
  struct odb_source_packed_for_each_object_wrapper_data *data)
342
0
{
343
0
  struct packfile_list_entry *e;
344
0
  struct multi_pack_index *m;
345
0
  bool pack_errors = false;
346
0
  int ret;
347
348
0
  store->skip_mru_updates = true;
349
350
0
  m = get_multi_pack_index(store);
351
0
  if (m) {
352
0
    ret = for_each_prefixed_object_in_midx(store, m, opts, data);
353
0
    if (ret)
354
0
      goto out;
355
0
  }
356
357
0
  for (e = packfile_store_get_packs(store); e; e = e->next) {
358
0
    if (e->pack->multi_pack_index)
359
0
      continue;
360
0
    if (should_exclude_pack(e->pack, opts->flags))
361
0
      continue;
362
363
0
    if (open_pack_index(e->pack)) {
364
0
      pack_errors = true;
365
0
      continue;
366
0
    }
367
368
0
    if (!e->pack->num_objects)
369
0
      continue;
370
371
0
    ret = for_each_prefixed_object_in_pack(store, e->pack, opts, data);
372
0
    if (ret)
373
0
      goto out;
374
0
  }
375
376
0
  ret = 0;
377
378
0
out:
379
0
  store->skip_mru_updates = false;
380
0
  if (!ret && pack_errors)
381
0
    ret = -1;
382
0
  return ret;
383
0
}
384
385
struct bitmapped_for_each_object_data {
386
  struct odb_source_packed *packed;
387
  const struct object_info *request;
388
  const struct odb_for_each_object_options *opts;
389
  odb_for_each_object_cb cb;
390
  void *cb_data;
391
};
392
393
static int bitmapped_for_each_object(const struct object_id *oid,
394
             enum object_type type UNUSED,
395
             int flags UNUSED,
396
             uint32_t hash UNUSED,
397
             struct packed_git *pack,
398
             off_t offset,
399
             void *cb_data)
400
0
{
401
0
  struct bitmapped_for_each_object_data *data = cb_data;
402
403
0
  if (should_exclude_pack(pack, data->opts->flags))
404
0
    return 0;
405
406
0
  if (data->request) {
407
0
    struct object_info oi = *data->request;
408
0
    if (packed_object_info(data->packed, pack, offset, &oi) < 0)
409
0
      return -1;
410
0
    return data->cb(oid, &oi, data->cb_data);
411
0
  }
412
413
0
  return data->cb(oid, NULL, data->cb_data);
414
0
}
415
416
static int odb_source_packed_for_each_object(struct odb_source *source,
417
               const struct object_info *request,
418
               odb_for_each_object_cb cb,
419
               void *cb_data,
420
               const struct odb_for_each_object_options *opts)
421
0
{
422
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
423
0
  struct odb_source_packed_for_each_object_wrapper_data data = {
424
0
    .store = packed,
425
0
    .request = request,
426
0
    .cb = cb,
427
0
    .cb_data = cb_data,
428
0
  };
429
0
  struct bitmap_index *bitmap = NULL;
430
0
  struct packfile_list_entry *e;
431
0
  int pack_errors = 0, ret;
432
433
0
  if (opts->prefix)
434
0
    return odb_source_packed_for_each_prefixed_object(packed, opts, &data);
435
436
0
  if (opts->filter &&
437
0
      opts->filter->choice != LOFC_DISABLED &&
438
0
      can_filter_bitmap(opts->filter))
439
0
    bitmap = prepare_bitmap_git_for_source(packed);
440
0
  if (bitmap) {
441
0
    struct bitmapped_for_each_object_data bitmap_data = {
442
0
      .packed = packed,
443
0
      .request = request,
444
0
      .opts = opts,
445
0
      .cb = cb,
446
0
      .cb_data = cb_data,
447
0
    };
448
449
0
    ret = for_each_bitmapped_object(bitmap, opts->filter,
450
0
            bitmapped_for_each_object,
451
0
            &bitmap_data);
452
0
    if (ret)
453
0
      goto out;
454
0
  }
455
456
0
  packed->skip_mru_updates = true;
457
458
0
  for (e = packfile_store_get_packs(packed); e; e = e->next) {
459
0
    struct packed_git *p = e->pack;
460
461
0
    if (should_exclude_pack(p, opts->flags))
462
0
      continue;
463
464
    /*
465
     * Objects covered by the bitmap have already been yielded
466
     * above; skip them here to avoid duplicates.
467
     */
468
0
    if (bitmap && bitmap_index_contains_pack(bitmap, p))
469
0
      continue;
470
471
0
    if (open_pack_index(p)) {
472
0
      pack_errors = 1;
473
0
      continue;
474
0
    }
475
476
0
    ret = for_each_object_in_pack(p, odb_source_packed_for_each_object_wrapper,
477
0
                &data, opts->flags);
478
0
    if (ret)
479
0
      goto out;
480
0
  }
481
482
0
  ret = 0;
483
484
0
out:
485
0
  packed->skip_mru_updates = false;
486
0
  free_bitmap_index(bitmap);
487
488
0
  if (!ret && pack_errors)
489
0
    ret = -1;
490
0
  return ret;
491
0
}
492
493
static int odb_source_packed_count_objects(struct odb_source *source,
494
             enum odb_count_objects_flags flags UNUSED,
495
             unsigned long *out)
496
0
{
497
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
498
0
  struct packfile_list_entry *e;
499
0
  struct multi_pack_index *m;
500
0
  unsigned long count = 0;
501
0
  int ret;
502
503
0
  m = get_multi_pack_index(packed);
504
0
  if (m)
505
0
    count += m->num_objects + m->num_objects_in_base;
506
507
0
  for (e = packfile_store_get_packs(packed); e; e = e->next) {
508
0
    if (e->pack->multi_pack_index)
509
0
      continue;
510
0
    if (open_pack_index(e->pack)) {
511
0
      ret = -1;
512
0
      goto out;
513
0
    }
514
515
0
    count += e->pack->num_objects;
516
0
  }
517
518
0
  *out = count;
519
0
  ret = 0;
520
521
0
out:
522
0
  return ret;
523
0
}
524
525
static int extend_abbrev_len(const struct object_id *a,
526
           const struct object_id *b,
527
           unsigned *out)
528
0
{
529
0
  unsigned len = oid_common_prefix_hexlen(a, b);
530
0
  if (len != hash_algos[a->algo].hexsz && len >= *out)
531
0
    *out = len + 1;
532
0
  return 0;
533
0
}
534
535
static void find_abbrev_len_for_midx(struct multi_pack_index *m,
536
             const struct object_id *oid,
537
             unsigned min_len,
538
             unsigned *out)
539
0
{
540
0
  unsigned len = min_len;
541
542
0
  for (; m; m = m->base_midx) {
543
0
    int match = 0;
544
0
    uint32_t num, first = 0;
545
0
    struct object_id found_oid;
546
547
0
    if (!m->num_objects)
548
0
      continue;
549
550
0
    num = m->num_objects + m->num_objects_in_base;
551
0
    match = bsearch_one_midx(oid, m, &first);
552
553
    /*
554
     * first is now the position in the packfile where we
555
     * would insert the object ID if it does not exist (or the
556
     * position of the object ID if it does exist). Hence, we
557
     * consider a maximum of two objects nearby for the
558
     * abbreviation length.
559
     */
560
561
0
    if (!match) {
562
0
      if (nth_midxed_object_oid(&found_oid, m, first))
563
0
        extend_abbrev_len(&found_oid, oid, &len);
564
0
    } else if (first < num - 1) {
565
0
      if (nth_midxed_object_oid(&found_oid, m, first + 1))
566
0
        extend_abbrev_len(&found_oid, oid, &len);
567
0
    }
568
0
    if (first > 0) {
569
0
      if (nth_midxed_object_oid(&found_oid, m, first - 1))
570
0
        extend_abbrev_len(&found_oid, oid, &len);
571
0
    }
572
0
  }
573
574
0
  *out = len;
575
0
}
576
577
static void find_abbrev_len_for_pack(struct packed_git *p,
578
             const struct object_id *oid,
579
             unsigned min_len,
580
             unsigned *out)
581
0
{
582
0
  int match;
583
0
  uint32_t num, first = 0;
584
0
  struct object_id found_oid;
585
0
  unsigned len = min_len;
586
587
0
  num = p->num_objects;
588
0
  match = bsearch_pack(oid, p, &first);
589
590
  /*
591
   * first is now the position in the packfile where we would insert
592
   * the object ID if it does not exist (or the position of mad->hash if
593
   * it does exist). Hence, we consider a maximum of two objects
594
   * nearby for the abbreviation length.
595
   */
596
0
  if (!match) {
597
0
    if (!nth_packed_object_id(&found_oid, p, first))
598
0
      extend_abbrev_len(&found_oid, oid, &len);
599
0
  } else if (first < num - 1) {
600
0
    if (!nth_packed_object_id(&found_oid, p, first + 1))
601
0
      extend_abbrev_len(&found_oid, oid, &len);
602
0
  }
603
0
  if (first > 0) {
604
0
    if (!nth_packed_object_id(&found_oid, p, first - 1))
605
0
      extend_abbrev_len(&found_oid, oid, &len);
606
0
  }
607
608
0
  *out = len;
609
0
}
610
611
static int odb_source_packed_find_abbrev_len(struct odb_source *source,
612
               const struct object_id *oid,
613
               unsigned min_len,
614
               unsigned *out)
615
0
{
616
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
617
0
  struct packfile_list_entry *e;
618
0
  struct multi_pack_index *m;
619
620
0
  m = get_multi_pack_index(packed);
621
0
  if (m)
622
0
    find_abbrev_len_for_midx(m, oid, min_len, &min_len);
623
624
0
  for (e = packfile_store_get_packs(packed); e; e = e->next) {
625
0
    if (e->pack->multi_pack_index)
626
0
      continue;
627
0
    if (open_pack_index(e->pack) || !e->pack->num_objects)
628
0
      continue;
629
630
0
    find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len);
631
0
  }
632
633
0
  *out = min_len;
634
0
  return 0;
635
0
}
636
637
static int odb_source_packed_freshen_object(struct odb_source *source,
638
              const struct object_id *oid,
639
              const time_t *mtime)
640
0
{
641
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
642
0
  struct utimbuf times, *timesp = NULL;
643
0
  struct pack_entry e;
644
645
0
  if (mtime) {
646
0
    times.actime = *mtime;
647
0
    times.modtime = *mtime;
648
0
    timesp = &times;
649
0
  }
650
651
0
  if (!find_pack_entry(packed, oid, &e, 0, NULL))
652
0
    return 0;
653
0
  if (e.p->is_cruft)
654
0
    return 0;
655
0
  if (e.p->freshened)
656
0
    return 1;
657
0
  if (utime(e.p->pack_name, timesp))
658
0
    return 0;
659
0
  e.p->freshened = 1;
660
661
0
  return 1;
662
0
}
663
664
static int odb_source_packed_write_object(struct odb_source *source UNUSED,
665
            const void *buf UNUSED,
666
            size_t len UNUSED,
667
            enum object_type type UNUSED,
668
            const struct object_id *oid UNUSED,
669
            const struct object_id *compat_oid UNUSED,
670
            const time_t *mtime UNUSED,
671
            unsigned flags UNUSED)
672
0
{
673
0
  return error("packed backend cannot write objects");
674
0
}
675
676
static int odb_source_packed_write_object_stream(struct odb_source *source UNUSED,
677
             struct odb_stream *stream UNUSED,
678
             struct object_id *oid UNUSED)
679
0
{
680
0
  return error("packed backend cannot write object streams");
681
0
}
682
683
static int odb_source_packed_begin_transaction(struct odb_source *source UNUSED,
684
                 struct odb_transaction **out UNUSED,
685
                 enum odb_transaction_flags flags UNUSED)
686
0
{
687
0
  return error("packed backend cannot begin transactions");
688
0
}
689
690
static int odb_source_packed_read_alternates(struct odb_source *source UNUSED,
691
               struct strvec *out UNUSED)
692
0
{
693
0
  return 0;
694
0
}
695
696
void (*report_garbage)(unsigned seen_bits, const char *path);
697
698
static void report_helper(const struct string_list *list,
699
        int seen_bits, int first, int last)
700
0
{
701
0
  if (seen_bits == (PACKDIR_FILE_PACK|PACKDIR_FILE_IDX))
702
0
    return;
703
704
0
  for (; first < last; first++)
705
0
    report_garbage(seen_bits, list->items[first].string);
706
0
}
707
708
static void report_pack_garbage(struct string_list *list)
709
0
{
710
0
  int baselen = -1, first = 0, seen_bits = 0;
711
712
0
  if (!report_garbage)
713
0
    return;
714
715
0
  string_list_sort(list);
716
717
0
  for (size_t i = 0; i < list->nr; i++) {
718
0
    const char *path = list->items[i].string;
719
0
    if (baselen != -1 &&
720
0
        strncmp(path, list->items[first].string, baselen)) {
721
0
      report_helper(list, seen_bits, first, i);
722
0
      baselen = -1;
723
0
      seen_bits = 0;
724
0
    }
725
0
    if (baselen == -1) {
726
0
      const char *dot = strrchr(path, '.');
727
0
      if (!dot) {
728
0
        report_garbage(PACKDIR_FILE_GARBAGE, path);
729
0
        continue;
730
0
      }
731
0
      baselen = dot - path + 1;
732
0
      first = i;
733
0
    }
734
0
    if (!strcmp(path + baselen, "pack"))
735
0
      seen_bits |= 1;
736
0
    else if (!strcmp(path + baselen, "idx"))
737
0
      seen_bits |= 2;
738
0
  }
739
0
  report_helper(list, seen_bits, first, list->nr);
740
0
}
741
742
struct prepare_pack_data {
743
  struct odb_source_packed *source;
744
  struct string_list *garbage;
745
};
746
747
static void prepare_pack(const char *full_name, size_t full_name_len,
748
       const char *file_name, void *_data)
749
0
{
750
0
  struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
751
0
  size_t base_len = full_name_len;
752
753
0
  if (strip_suffix_mem(full_name, &base_len, ".idx") &&
754
0
      !(data->source->midx &&
755
0
        midx_contains_pack(data->source->midx, file_name))) {
756
0
    char *trimmed_path = xstrndup(full_name, full_name_len);
757
0
    packfile_store_load_pack(data->source,
758
0
           trimmed_path, data->source->base.local);
759
0
    free(trimmed_path);
760
0
  }
761
762
0
  if (!report_garbage)
763
0
    return;
764
765
0
  if (!strcmp(file_name, "multi-pack-index") ||
766
0
      !strcmp(file_name, "multi-pack-index.d"))
767
0
    return;
768
0
  if (starts_with(file_name, "multi-pack-index") &&
769
0
      (ends_with(file_name, ".bitmap") || ends_with(file_name, ".rev")))
770
0
    return;
771
0
  if (ends_with(file_name, ".idx") ||
772
0
      ends_with(file_name, ".rev") ||
773
0
      ends_with(file_name, ".pack") ||
774
0
      ends_with(file_name, ".bitmap") ||
775
0
      ends_with(file_name, ".keep") ||
776
0
      ends_with(file_name, ".promisor") ||
777
0
      ends_with(file_name, ".mtimes"))
778
0
    string_list_append(data->garbage, full_name);
779
0
  else
780
0
    report_garbage(PACKDIR_FILE_GARBAGE, full_name);
781
0
}
782
783
static void prepare_packed_git_one(struct odb_source_packed *source)
784
0
{
785
0
  struct string_list garbage = STRING_LIST_INIT_DUP;
786
0
  struct prepare_pack_data data = {
787
0
    .source = source,
788
0
    .garbage = &garbage,
789
0
  };
790
791
0
  for_each_file_in_pack_dir(source->base.path, prepare_pack, &data);
792
793
0
  report_pack_garbage(data.garbage);
794
0
  string_list_clear(data.garbage, 0);
795
0
}
796
797
0
DEFINE_LIST_SORT(static, sort_packs, struct packfile_list_entry, next);
798
0
799
0
static int sort_pack(const struct packfile_list_entry *a,
800
0
         const struct packfile_list_entry *b)
801
0
{
802
0
  int st;
803
804
  /*
805
   * Local packs tend to contain objects specific to our
806
   * variant of the project than remote ones.  In addition,
807
   * remote ones could be on a network mounted filesystem.
808
   * Favor local ones for these reasons.
809
   */
810
0
  st = a->pack->pack_local - b->pack->pack_local;
811
0
  if (st)
812
0
    return -st;
813
814
  /*
815
   * Younger packs tend to contain more recent objects,
816
   * and more recent objects tend to get accessed more
817
   * often.
818
   */
819
0
  if (a->pack->mtime < b->pack->mtime)
820
0
    return 1;
821
0
  else if (a->pack->mtime == b->pack->mtime)
822
0
    return 0;
823
0
  return -1;
824
0
}
825
826
static void odb_source_packed_prepare(struct odb_source *source,
827
              enum odb_prepare_flags flags)
828
0
{
829
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
830
831
0
  if (flags & ODB_PREPARE_FLUSH_CACHES)
832
0
    packed->initialized = false;
833
0
  if (packed->initialized)
834
0
    return;
835
836
0
  prepare_multi_pack_index_one(packed);
837
0
  prepare_packed_git_one(packed);
838
839
0
  sort_packs(&packed->packs.head, sort_pack);
840
0
  for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
841
0
    if (!e->next)
842
0
      packed->packs.tail = e;
843
844
0
  packed->initialized = true;
845
0
}
846
847
static void odb_source_packed_reparent(const char *old_cwd,
848
               const char *new_cwd,
849
               void *cb_data)
850
0
{
851
0
  struct odb_source_packed *packed = cb_data;
852
0
  char *path = reparent_relative_path(old_cwd, new_cwd,
853
0
              packed->base.path);
854
0
  free(packed->base.path);
855
0
  packed->base.path = path;
856
0
}
857
858
static void odb_source_packed_close(struct odb_source *source)
859
0
{
860
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
861
862
0
  for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next) {
863
0
    if (e->pack->do_not_close)
864
0
      BUG("want to close pack marked 'do-not-close'");
865
0
    close_pack(e->pack);
866
0
  }
867
0
  if (packed->midx)
868
0
    close_midx(packed->midx);
869
0
  packed->midx = NULL;
870
0
}
871
872
static void odb_source_packed_free(struct odb_source *source)
873
0
{
874
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
875
876
0
  chdir_notify_unregister(odb_source_packed_reparent, packed);
877
878
0
  odb_source_close(source);
879
0
  for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
880
0
    free(e->pack);
881
0
  packfile_list_clear(&packed->packs);
882
883
0
  strmap_clear(&packed->packs_by_path, 0);
884
0
  odb_source_release(&packed->base);
885
0
  free(packed);
886
0
}
887
888
static int verify_packs(struct odb_source_packed *source,
889
      struct odb_fsck_options *opts)
890
0
{
891
0
  struct progress *progress = NULL;
892
0
  struct packfile_list_entry *e;
893
0
  uint32_t total = 0, count = 0;
894
0
  int ret = 0;
895
896
0
  if (opts->flags & ODB_FSCK_PROGRESS) {
897
0
    for (e = packfile_store_get_packs(source); e; e = e->next) {
898
0
      if (open_pack_index(e->pack))
899
0
        continue;
900
0
      total += e->pack->num_objects;
901
0
    }
902
903
0
    progress = start_progress(source->base.odb->repo,
904
0
            _("Checking objects"), total);
905
0
  }
906
907
0
  for (e = packfile_store_get_packs(source); e; e = e->next) {
908
    /* verify gives error messages itself */
909
0
    if (verify_pack(source->base.odb->repo, e->pack,
910
0
        opts->object_cb, opts->object_payload,
911
0
        progress, count))
912
0
      ret = -1;
913
0
    count += e->pack->num_objects;
914
0
  }
915
0
  stop_progress(&progress);
916
917
0
  return ret;
918
0
}
919
920
static int verify_reverse_indices(struct odb_source_packed *source,
921
          struct odb_fsck_options *opts)
922
0
{
923
0
  struct progress *progress = NULL;
924
0
  struct packfile_list_entry *e;
925
0
  uint32_t pack_count = 0;
926
0
  int res = 0;
927
928
0
  if (opts->flags & ODB_FSCK_PROGRESS) {
929
0
    for (e = packfile_store_get_packs(source); e; e = e->next)
930
0
      pack_count++;
931
0
    progress = start_delayed_progress(source->base.odb->repo,
932
0
              "Verifying reverse pack-indexes", pack_count);
933
0
    pack_count = 0;
934
0
  }
935
936
0
  for (e = packfile_store_get_packs(source); e; e = e->next) {
937
0
    int load_error = load_pack_revindex_from_disk(e->pack);
938
939
0
    if (load_error < 0) {
940
0
      error(_("unable to load rev-index for pack '%s'"), e->pack->pack_name);
941
0
      res = -1;
942
0
    } else if (!load_error &&
943
0
         !load_pack_revindex(source->base.odb->repo, e->pack) &&
944
0
         verify_pack_revindex(e->pack)) {
945
0
      error(_("invalid rev-index for pack '%s'"), e->pack->pack_name);
946
0
      res = -1;
947
0
    }
948
0
    display_progress(progress, ++pack_count);
949
0
  }
950
0
  stop_progress(&progress);
951
952
0
  return res;
953
0
}
954
955
static int verify_midx(struct odb_source_packed *source,
956
           struct odb_fsck_options *opts)
957
0
{
958
0
  struct child_process midx_verify = CHILD_PROCESS_INIT;
959
960
0
  prepare_repo_settings(source->base.odb->repo);
961
0
  if (!source->base.odb->repo->settings.core_multi_pack_index)
962
0
    return 0;
963
964
0
  child_process_init(&midx_verify);
965
0
  midx_verify.git_cmd = 1;
966
0
  strvec_pushl(&midx_verify.args, "multi-pack-index",
967
0
         "verify", "--object-dir", source->base.path, NULL);
968
0
  if (opts->flags & ODB_FSCK_PROGRESS)
969
0
    strvec_push(&midx_verify.args, "--progress");
970
0
  else
971
0
    strvec_push(&midx_verify.args, "--no-progress");
972
0
  if (run_command(&midx_verify))
973
0
    return -1;
974
975
0
  return 0;
976
0
}
977
978
static int odb_source_packed_fsck(struct odb_source *source,
979
          struct odb_fsck_options *opts)
980
0
{
981
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
982
0
  int ret = 0;
983
984
0
  if ((opts->flags & ODB_FSCK_FULL) && verify_packs(packed, opts) < 0)
985
0
    ret = -1;
986
987
0
  if (verify_reverse_indices(packed, opts) < 0)
988
0
    ret = -1;
989
990
0
  if (verify_bitmap_files(packed))
991
0
    ret = -1;
992
993
0
  if (verify_midx(packed, opts) < 0)
994
0
    ret = -1;
995
996
0
  return ret;
997
0
}
998
999
struct odb_source_packed *odb_source_packed_new(struct object_database *odb,
1000
            const char *path,
1001
            bool local)
1002
0
{
1003
0
  struct odb_source_packed *packed;
1004
1005
0
  CALLOC_ARRAY(packed, 1);
1006
0
  odb_source_init(&packed->base, odb, ODB_SOURCE_PACKED, path, local);
1007
0
  strmap_init(&packed->packs_by_path);
1008
1009
0
  packed->base.free = odb_source_packed_free;
1010
0
  packed->base.close = odb_source_packed_close;
1011
0
  packed->base.prepare = odb_source_packed_prepare;
1012
0
  packed->base.fsck = odb_source_packed_fsck;
1013
0
  packed->base.read_object_info = odb_source_packed_read_object_info;
1014
0
  packed->base.read_object_stream = odb_source_packed_read_object_stream;
1015
0
  packed->base.for_each_object = odb_source_packed_for_each_object;
1016
0
  packed->base.count_objects = odb_source_packed_count_objects;
1017
0
  packed->base.find_abbrev_len = odb_source_packed_find_abbrev_len;
1018
0
  packed->base.freshen_object = odb_source_packed_freshen_object;
1019
0
  packed->base.write_object = odb_source_packed_write_object;
1020
0
  packed->base.write_object_stream = odb_source_packed_write_object_stream;
1021
0
  packed->base.begin_transaction = odb_source_packed_begin_transaction;
1022
0
  packed->base.read_alternates = odb_source_packed_read_alternates;
1023
1024
0
  if (!is_absolute_path(path))
1025
0
    chdir_notify_register(odb_source_packed_reparent, packed);
1026
1027
0
  return packed;
1028
0
}