Coverage Report

Created: 2026-10-17 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/odb/source-loose.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "abspath.h"
3
#include "chdir-notify.h"
4
#include "gettext.h"
5
#include "hex.h"
6
#include "loose.h"
7
#include "object-file.h"
8
#include "object-file-convert.h"
9
#include "odb.h"
10
#include "odb/source-files.h"
11
#include "odb/source-loose.h"
12
#include "odb/streaming.h"
13
#include "oidtree.h"
14
#include "path.h"
15
#include "progress.h"
16
#include "repository.h"
17
#include "strbuf.h"
18
#include "tempfile.h"
19
#include "write-or-die.h"
20
21
static int append_loose_object(const struct object_id *oid,
22
             const char *path UNUSED,
23
             void *data)
24
0
{
25
0
  oidtree_insert(data, oid, NULL);
26
0
  return 0;
27
0
}
28
29
static struct oidtree *odb_source_loose_cache(struct odb_source_loose *loose,
30
                const struct object_id *oid)
31
0
{
32
0
  int subdir_nr = oid->hash[0];
33
0
  struct strbuf buf = STRBUF_INIT;
34
0
  size_t word_bits = bitsizeof(loose->subdir_seen[0]);
35
0
  size_t word_index = subdir_nr / word_bits;
36
0
  size_t mask = (size_t)1u << (subdir_nr % word_bits);
37
0
  uint32_t *bitmap;
38
39
0
  if (subdir_nr < 0 ||
40
0
      (size_t) subdir_nr >= bitsizeof(loose->subdir_seen))
41
0
    BUG("subdir_nr out of range");
42
43
0
  bitmap = &loose->subdir_seen[word_index];
44
0
  if (*bitmap & mask)
45
0
    return loose->cache;
46
0
  if (!loose->cache) {
47
0
    ALLOC_ARRAY(loose->cache, 1);
48
0
    oidtree_init(loose->cache);
49
0
  }
50
0
  strbuf_addstr(&buf, loose->base.path);
51
0
  for_each_file_in_obj_subdir(subdir_nr, &buf,
52
0
            loose->base.odb->repo->hash_algo,
53
0
            append_loose_object,
54
0
            NULL, NULL,
55
0
            loose->cache);
56
0
  *bitmap |= mask;
57
0
  strbuf_release(&buf);
58
0
  return loose->cache;
59
0
}
60
61
static int quick_has_loose(struct odb_source_loose *loose,
62
         const struct object_id *oid)
63
0
{
64
0
  return !!oidtree_contains(odb_source_loose_cache(loose, oid), oid);
65
0
}
66
67
static int read_object_info_from_path(struct odb_source_loose *loose,
68
              const char *path,
69
              const struct object_id *oid,
70
              struct object_info *oi,
71
              enum object_info_flags flags,
72
              struct strbuf *errmsg)
73
0
{
74
0
  int ret;
75
0
  int fd;
76
0
  unsigned long mapsize;
77
0
  void *map = NULL;
78
0
  git_zstream stream, *stream_to_end = NULL;
79
0
  char hdr[MAX_HEADER_LEN];
80
0
  size_t size_scratch;
81
0
  enum object_type type_scratch;
82
0
  struct stat st;
83
84
  /*
85
   * If we don't care about type or size, then we don't
86
   * need to look inside the object at all. Note that we
87
   * do not optimize out the stat call, even if the
88
   * caller doesn't care about the disk-size, since our
89
   * return value implicitly indicates whether the
90
   * object even exists.
91
   */
92
0
  if (!oi || (!oi->typep && !oi->sizep && !oi->contentp)) {
93
0
    struct stat st;
94
95
0
    if ((!oi || (!oi->disk_sizep && !oi->mtimep)) && (flags & OBJECT_INFO_QUICK)) {
96
0
      ret = quick_has_loose(loose, oid) ? 0 : ODB_READ_NOT_FOUND;
97
0
      goto out;
98
0
    }
99
100
0
    if (lstat(path, &st) < 0) {
101
0
      if (errno == ENOENT) {
102
0
        ret = ODB_READ_NOT_FOUND;
103
0
        goto out;
104
0
      }
105
106
0
      ret = -1;
107
0
      goto out;
108
0
    }
109
110
0
    if (oi) {
111
0
      if (oi->disk_sizep)
112
0
        *oi->disk_sizep = st.st_size;
113
0
      if (oi->mtimep)
114
0
        *oi->mtimep = st.st_mtime;
115
0
    }
116
117
0
    ret = 0;
118
0
    goto out;
119
0
  }
120
121
0
  fd = git_open(path);
122
0
  if (fd < 0) {
123
0
    if (errno == ENOENT) {
124
0
      ret = ODB_READ_NOT_FOUND;
125
0
      goto out;
126
0
    }
127
128
0
    ret = error_errno(_("unable to open loose object %s"), oid_to_hex(oid));
129
0
    goto out;
130
0
  }
131
132
0
  if (fstat(fd, &st)) {
133
0
    close(fd);
134
0
    ret = -1;
135
0
    goto out;
136
0
  }
137
138
0
  mapsize = xsize_t(st.st_size);
139
0
  if (!mapsize) {
140
0
    close(fd);
141
0
    ret = error(_("object file %s is empty"), path);
142
0
    goto out;
143
0
  }
144
145
0
  map = xmmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
146
0
  close(fd);
147
0
  if (!map) {
148
0
    ret = -1;
149
0
    goto out;
150
0
  }
151
152
0
  if (oi->disk_sizep)
153
0
    *oi->disk_sizep = mapsize;
154
0
  if (oi->mtimep)
155
0
    *oi->mtimep = st.st_mtime;
156
157
0
  stream_to_end = &stream;
158
159
0
  switch (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr))) {
160
0
  case ULHR_OK:
161
0
    if (!oi->sizep)
162
0
      oi->sizep = &size_scratch;
163
0
    if (!oi->typep)
164
0
      oi->typep = &type_scratch;
165
166
0
    if (parse_loose_header(hdr, oi) < 0) {
167
0
      ret = error(_("unable to parse %s header"), oid_to_hex(oid));
168
0
      goto out;
169
0
    }
170
171
0
    if (*oi->typep < 0)
172
0
      die(_("invalid object type"));
173
174
0
    if (oi->contentp) {
175
0
      *oi->contentp = unpack_loose_rest(&stream, hdr, *oi->sizep, oid);
176
0
      if (!*oi->contentp) {
177
0
        ret = -1;
178
0
        goto out;
179
0
      }
180
0
    }
181
182
0
    break;
183
0
  case ULHR_BAD:
184
0
    ret = error(_("unable to unpack %s header"),
185
0
          oid_to_hex(oid));
186
0
    goto out;
187
0
  case ULHR_TOO_LONG:
188
0
    ret = error(_("header for %s too long, exceeds %d bytes"),
189
0
          oid_to_hex(oid), MAX_HEADER_LEN);
190
0
    goto out;
191
0
  }
192
193
0
  ret = 0;
194
195
0
out:
196
0
  if (ret && ret != ODB_READ_NOT_FOUND && errmsg)
197
0
    strbuf_addf(errmsg, _("loose object %s (stored in %s) is corrupt"),
198
0
          oid_to_hex(oid), path);
199
0
  if (stream_to_end)
200
0
    git_inflate_end(stream_to_end);
201
0
  if (map)
202
0
    munmap(map, mapsize);
203
0
  if (oi) {
204
0
    if (oi->sizep == &size_scratch)
205
0
      oi->sizep = NULL;
206
0
    if (oi->typep == &type_scratch)
207
0
      oi->typep = NULL;
208
0
    if (oi->delta_base_oid)
209
0
      oidclr(oi->delta_base_oid, loose->base.odb->repo->hash_algo);
210
0
    if (oi->source_infop && !ret)
211
0
      oi->source_infop->source = &loose->base;
212
0
  }
213
214
0
  return ret;
215
0
}
216
217
static enum odb_read_status odb_source_loose_read_object_info(struct odb_source *source,
218
                    const struct object_id *oid,
219
                    struct object_info *oi,
220
                    enum object_info_flags flags,
221
                    struct strbuf *errmsg)
222
0
{
223
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
224
0
  static struct strbuf buf = STRBUF_INIT;
225
226
  /*
227
   * The second read shouldn't cause new loose objects to show up, unless
228
   * there was a race condition with a secondary process. We don't care
229
   * about this case though, so we simply skip reading loose objects a
230
   * second time.
231
   */
232
0
  if (flags & OBJECT_INFO_SECOND_READ)
233
0
    return ODB_READ_NOT_FOUND;
234
235
0
  odb_loose_path(loose, &buf, oid);
236
0
  return read_object_info_from_path(loose, buf.buf, oid, oi, flags, errmsg);
237
0
}
238
239
/*
240
 * Find "oid" as a loose object in given source, open the object and return its
241
 * file descriptor. Returns the file descriptor on success, negative on failure.
242
 *
243
 * The "path" out-parameter will give the path of the object we found (if any).
244
 * Note that it may point to static storage and is only valid until another
245
 * call to open_loose_object().
246
 */
247
static int open_loose_object(struct odb_source_loose *loose,
248
           const struct object_id *oid, const char **path)
249
0
{
250
0
  static struct strbuf buf = STRBUF_INIT;
251
0
  int fd;
252
253
0
  *path = odb_loose_path(loose, &buf, oid);
254
0
  fd = git_open(*path);
255
0
  if (fd >= 0)
256
0
    return fd;
257
258
0
  return -1;
259
0
}
260
261
static void *odb_source_loose_map_object(struct odb_source_loose *loose,
262
           const struct object_id *oid,
263
           unsigned long *size)
264
0
{
265
0
  const char *p;
266
0
  int fd = open_loose_object(loose, oid, &p);
267
0
  void *map = NULL;
268
0
  struct stat st;
269
270
0
  if (fd < 0)
271
0
    return NULL;
272
273
0
  if (!fstat(fd, &st)) {
274
0
    *size = xsize_t(st.st_size);
275
0
    if (!*size) {
276
      /* mmap() is forbidden on empty files */
277
0
      error(_("object file %s is empty"), p);
278
0
      goto out;
279
0
    }
280
281
0
    map = xmmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0);
282
0
  }
283
284
0
out:
285
0
  close(fd);
286
0
  return map;
287
0
}
288
289
struct odb_loose_read_stream {
290
  struct odb_stream base;
291
  git_zstream z;
292
  enum {
293
    ODB_LOOSE_READ_STREAM_INUSE,
294
    ODB_LOOSE_READ_STREAM_DONE,
295
    ODB_LOOSE_READ_STREAM_ERROR,
296
  } z_state;
297
  void *mapped;
298
  unsigned long mapsize;
299
  char hdr[32];
300
  int hdr_avail;
301
  int hdr_used;
302
};
303
304
static ssize_t read_istream_loose(struct odb_stream *_st, char *buf, size_t sz)
305
0
{
306
0
  struct odb_loose_read_stream *st =
307
0
    container_of(_st, struct odb_loose_read_stream, base);
308
0
  size_t total_read = 0;
309
310
0
  switch (st->z_state) {
311
0
  case ODB_LOOSE_READ_STREAM_DONE:
312
0
    return 0;
313
0
  case ODB_LOOSE_READ_STREAM_ERROR:
314
0
    return -1;
315
0
  default:
316
0
    break;
317
0
  }
318
319
0
  if (st->hdr_used < st->hdr_avail) {
320
0
    size_t to_copy = st->hdr_avail - st->hdr_used;
321
0
    if (sz < to_copy)
322
0
      to_copy = sz;
323
0
    memcpy(buf, st->hdr + st->hdr_used, to_copy);
324
0
    st->hdr_used += to_copy;
325
0
    total_read += to_copy;
326
0
  }
327
328
0
  while (total_read < sz) {
329
0
    int status;
330
331
0
    st->z.next_out = (unsigned char *)buf + total_read;
332
0
    st->z.avail_out = sz - total_read;
333
0
    status = git_inflate(&st->z, Z_FINISH);
334
335
0
    total_read = st->z.next_out - (unsigned char *)buf;
336
337
0
    if (status == Z_STREAM_END) {
338
0
      git_inflate_end(&st->z);
339
0
      st->z_state = ODB_LOOSE_READ_STREAM_DONE;
340
0
      break;
341
0
    }
342
0
    if (status != Z_OK && (status != Z_BUF_ERROR || total_read < sz)) {
343
0
      git_inflate_end(&st->z);
344
0
      st->z_state = ODB_LOOSE_READ_STREAM_ERROR;
345
0
      return -1;
346
0
    }
347
0
  }
348
0
  return total_read;
349
0
}
350
351
static int close_istream_loose(struct odb_stream *_st)
352
0
{
353
0
  struct odb_loose_read_stream *st =
354
0
    container_of(_st, struct odb_loose_read_stream, base);
355
356
0
  if (st->z_state == ODB_LOOSE_READ_STREAM_INUSE)
357
0
    git_inflate_end(&st->z);
358
0
  munmap(st->mapped, st->mapsize);
359
0
  return 0;
360
0
}
361
362
static int odb_source_loose_read_object_stream(struct odb_stream **out,
363
                 struct odb_source *source,
364
                 const struct object_id *oid)
365
0
{
366
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
367
0
  struct object_info oi = OBJECT_INFO_INIT;
368
0
  struct odb_loose_read_stream *st;
369
0
  unsigned long mapsize;
370
0
  void *mapped;
371
372
0
  mapped = odb_source_loose_map_object(loose, oid, &mapsize);
373
0
  if (!mapped)
374
0
    return -1;
375
376
  /*
377
   * Note: we must allocate this structure early even though we may still
378
   * fail. This is because we need to initialize the zlib stream, and it
379
   * is not possible to copy the stream around after the fact because it
380
   * has self-referencing pointers.
381
   */
382
0
  CALLOC_ARRAY(st, 1);
383
384
0
  switch (unpack_loose_header(&st->z, mapped, mapsize, st->hdr,
385
0
            sizeof(st->hdr))) {
386
0
  case ULHR_OK:
387
0
    break;
388
0
  case ULHR_BAD:
389
0
  case ULHR_TOO_LONG:
390
0
    goto error;
391
0
  }
392
393
0
  oi.sizep = &st->base.size;
394
0
  oi.typep = &st->base.type;
395
396
0
  if (parse_loose_header(st->hdr, &oi) < 0 || st->base.type < 0)
397
0
    goto error;
398
399
0
  st->mapped = mapped;
400
0
  st->mapsize = mapsize;
401
0
  st->hdr_used = strlen(st->hdr) + 1;
402
0
  st->hdr_avail = st->z.total_out;
403
0
  st->z_state = ODB_LOOSE_READ_STREAM_INUSE;
404
0
  st->base.close = close_istream_loose;
405
0
  st->base.read = read_istream_loose;
406
407
0
  *out = &st->base;
408
409
0
  return 0;
410
0
error:
411
0
  git_inflate_end(&st->z);
412
0
  munmap(mapped, mapsize);
413
0
  free(st);
414
0
  return -1;
415
0
}
416
417
struct for_each_object_wrapper_data {
418
  struct odb_source_loose *loose;
419
  const struct object_info *request;
420
  odb_for_each_object_cb cb;
421
  void *cb_data;
422
};
423
424
static int for_each_object_wrapper_cb(const struct object_id *oid,
425
              const char *path,
426
              void *cb_data)
427
0
{
428
0
  struct for_each_object_wrapper_data *data = cb_data;
429
430
0
  if (data->request) {
431
0
    struct object_info oi = *data->request;
432
433
0
    if (read_object_info_from_path(data->loose, path, oid, &oi, 0, NULL) < 0)
434
0
      return -1;
435
436
0
    return data->cb(oid, &oi, data->cb_data);
437
0
  } else {
438
0
    return data->cb(oid, NULL, data->cb_data);
439
0
  }
440
0
}
441
442
static int for_each_prefixed_object_wrapper_cb(const struct object_id *oid,
443
                 void *node_data UNUSED,
444
                 void *cb_data)
445
0
{
446
0
  struct for_each_object_wrapper_data *data = cb_data;
447
0
  if (data->request) {
448
0
    struct object_info oi = *data->request;
449
450
0
    if (odb_source_read_object_info(&data->loose->base,
451
0
            oid, &oi, 0, NULL) < 0)
452
0
      return -1;
453
454
0
    return data->cb(oid, &oi, data->cb_data);
455
0
  } else {
456
0
    return data->cb(oid, NULL, data->cb_data);
457
0
  }
458
0
}
459
460
static int odb_source_loose_for_each_object(struct odb_source *source,
461
              const struct object_info *request,
462
              odb_for_each_object_cb cb,
463
              void *cb_data,
464
              const struct odb_for_each_object_options *opts)
465
0
{
466
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
467
0
  struct for_each_object_wrapper_data data = {
468
0
    .loose = loose,
469
0
    .request = request,
470
0
    .cb = cb,
471
0
    .cb_data = cb_data,
472
0
  };
473
474
  /* There are no loose promisor objects, so we can return immediately. */
475
0
  if ((opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY))
476
0
    return 0;
477
0
  if ((opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !source->local)
478
0
    return 0;
479
480
0
  if (opts->prefix)
481
0
    return oidtree_each(odb_source_loose_cache(loose, opts->prefix),
482
0
            opts->prefix, opts->prefix_hex_len,
483
0
            for_each_prefixed_object_wrapper_cb, &data);
484
485
0
  return for_each_loose_file_in_source(source, for_each_object_wrapper_cb,
486
0
               NULL, NULL, &data);
487
0
}
488
489
struct find_abbrev_len_data {
490
  const struct object_id *oid;
491
  unsigned len;
492
};
493
494
static int find_abbrev_len_cb(const struct object_id *oid,
495
            struct object_info *oi UNUSED,
496
            void *cb_data)
497
0
{
498
0
  struct find_abbrev_len_data *data = cb_data;
499
0
  unsigned len = oid_common_prefix_hexlen(oid, data->oid);
500
0
  if (len != hash_algos[oid->algo].hexsz && len >= data->len)
501
0
    data->len = len + 1;
502
0
  return 0;
503
0
}
504
505
static int odb_source_loose_find_abbrev_len(struct odb_source *source,
506
              const struct object_id *oid,
507
              unsigned min_len,
508
              unsigned *out)
509
0
{
510
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
511
0
  struct odb_for_each_object_options opts = {
512
0
    .prefix = oid,
513
0
    .prefix_hex_len = min_len,
514
0
  };
515
0
  struct find_abbrev_len_data data = {
516
0
    .oid = oid,
517
0
    .len = min_len,
518
0
  };
519
0
  int ret;
520
521
0
  ret = odb_source_for_each_object(&loose->base, NULL, find_abbrev_len_cb,
522
0
           &data, &opts);
523
0
  *out = data.len;
524
525
0
  return ret;
526
0
}
527
528
static int count_loose_object(const struct object_id *oid UNUSED,
529
            struct object_info *oi UNUSED,
530
            void *payload)
531
0
{
532
0
  unsigned long *count = payload;
533
0
  (*count)++;
534
0
  return 0;
535
0
}
536
537
static int odb_source_loose_count_objects(struct odb_source *source,
538
            enum odb_count_objects_flags flags,
539
            unsigned long *out)
540
0
{
541
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
542
0
  const unsigned hexsz = source->odb->repo->hash_algo->hexsz - 2;
543
0
  char *path = NULL;
544
0
  DIR *dir = NULL;
545
0
  int ret;
546
547
0
  if (flags & ODB_COUNT_OBJECTS_APPROXIMATE) {
548
0
    unsigned long count = 0;
549
0
    struct dirent *ent;
550
551
0
    path = xstrfmt("%s/17", source->path);
552
553
0
    dir = opendir(path);
554
0
    if (!dir) {
555
0
      if (errno == ENOENT) {
556
0
        *out = 0;
557
0
        ret = 0;
558
0
        goto out;
559
0
      }
560
561
0
      ret = error_errno("cannot open object shard '%s'", path);
562
0
      goto out;
563
0
    }
564
565
0
    while ((ent = readdir(dir)) != NULL) {
566
0
      if (strspn(ent->d_name, "0123456789abcdef") != hexsz ||
567
0
          ent->d_name[hexsz] != '\0')
568
0
        continue;
569
0
      count++;
570
0
    }
571
572
0
    *out = count * 256;
573
0
    ret = 0;
574
0
  } else {
575
0
    struct odb_for_each_object_options opts = { 0 };
576
0
    *out = 0;
577
0
    ret = odb_source_for_each_object(&loose->base, NULL, count_loose_object,
578
0
             out, &opts);
579
0
  }
580
581
0
out:
582
0
  if (dir)
583
0
    closedir(dir);
584
0
  free(path);
585
0
  return ret;
586
0
}
587
588
static int odb_source_loose_freshen_object(struct odb_source *source,
589
             const struct object_id *oid,
590
             const time_t *mtime)
591
0
{
592
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
593
0
  static struct strbuf path = STRBUF_INIT;
594
0
  odb_loose_path(loose, &path, oid);
595
0
  return !!check_and_freshen_file(path.buf, 1, mtime);
596
0
}
597
598
/* Finalize a file on disk, and close it. */
599
static void close_loose_object(struct odb_source_loose *loose,
600
             int fd, const char *filename)
601
0
{
602
0
  if (loose->base.will_destroy)
603
0
    goto out;
604
605
0
  if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
606
0
    odb_transaction_files_fsync(loose->base.odb->transaction, fd, filename);
607
0
  else if (fsync_object_files > 0)
608
0
    fsync_or_die(fd, filename);
609
0
  else
610
0
    fsync_component_or_die(FSYNC_COMPONENT_LOOSE_OBJECT, fd,
611
0
               filename);
612
613
0
out:
614
0
  if (close(fd) != 0)
615
0
    die_errno(_("error when closing loose object file"));
616
0
}
617
618
/* Size of directory component, including the ending '/' */
619
static inline int directory_size(const char *filename)
620
0
{
621
0
  const char *s = strrchr(filename, '/');
622
0
  if (!s)
623
0
    return 0;
624
0
  return s - filename + 1;
625
0
}
626
627
/*
628
 * This creates a temporary file in the same directory as the final
629
 * 'filename'
630
 *
631
 * We want to avoid cross-directory filename renames, because those
632
 * can have problems on various filesystems (FAT, NFS, Coda).
633
 */
634
static int create_tmpfile(struct repository *repo,
635
        struct strbuf *tmp, const char *filename)
636
0
{
637
0
  int fd, dirlen = directory_size(filename);
638
639
0
  strbuf_reset(tmp);
640
0
  strbuf_add(tmp, filename, dirlen);
641
0
  strbuf_addstr(tmp, "tmp_obj_XXXXXX");
642
0
  fd = git_mkstemp_mode(tmp->buf, 0444);
643
0
  if (fd < 0 && dirlen && errno == ENOENT) {
644
    /*
645
     * Make sure the directory exists; note that the contents
646
     * of the buffer are undefined after mkstemp returns an
647
     * error, so we have to rewrite the whole buffer from
648
     * scratch.
649
     */
650
0
    strbuf_reset(tmp);
651
0
    strbuf_add(tmp, filename, dirlen - 1);
652
0
    if (mkdir(tmp->buf, 0777) && errno != EEXIST)
653
0
      return -1;
654
0
    if (adjust_shared_perm(repo, tmp->buf))
655
0
      return -1;
656
657
    /* Try again */
658
0
    strbuf_addstr(tmp, "/tmp_obj_XXXXXX");
659
0
    fd = git_mkstemp_mode(tmp->buf, 0444);
660
0
  }
661
0
  return fd;
662
0
}
663
664
/**
665
 * Common steps for loose object writers to start writing loose
666
 * objects:
667
 *
668
 * - Create tmpfile for the loose object.
669
 * - Setup zlib stream for compression.
670
 * - Start to feed header to zlib stream.
671
 *
672
 * Returns a "fd", which should later be provided to
673
 * end_loose_object_common().
674
 */
675
static int start_loose_object_common(struct odb_source_loose *loose,
676
             struct strbuf *tmp_file,
677
             const char *filename, unsigned flags,
678
             git_zstream *stream,
679
             unsigned char *buf, size_t buflen,
680
             struct git_hash_ctx *c, struct git_hash_ctx *compat_c,
681
             char *hdr, int hdrlen)
682
0
{
683
0
  const struct git_hash_algo *algo = loose->base.odb->repo->hash_algo;
684
0
  const struct git_hash_algo *compat = loose->base.odb->repo->compat_hash_algo;
685
0
  int fd;
686
0
  struct repo_config_values *cfg = repo_config_values(loose->base.odb->repo);
687
688
0
  fd = create_tmpfile(loose->base.odb->repo, tmp_file, filename);
689
0
  if (fd < 0) {
690
0
    if (flags & ODB_WRITE_OBJECT_SILENT)
691
0
      return -1;
692
0
    else if (errno == EACCES)
693
0
      return error(_("insufficient permission for adding "
694
0
               "an object to repository database %s"),
695
0
             loose->base.path);
696
0
    else
697
0
      return error_errno(
698
0
        _("unable to create temporary file"));
699
0
  }
700
701
  /*  Setup zlib stream for compression */
702
0
  git_deflate_init(stream, cfg->zlib_compression_level);
703
0
  stream->next_out = buf;
704
0
  stream->avail_out = buflen;
705
0
  git_hash_init(c, algo);
706
0
  if (compat && compat_c)
707
0
    git_hash_init(compat_c, compat);
708
709
  /*  Start to feed header to zlib stream */
710
0
  stream->next_in = (unsigned char *)hdr;
711
0
  stream->avail_in = hdrlen;
712
0
  while (git_deflate(stream, 0) == Z_OK)
713
0
    ; /* nothing */
714
0
  git_hash_update(c, hdr, hdrlen);
715
0
  if (compat && compat_c)
716
0
    git_hash_update(compat_c, hdr, hdrlen);
717
718
0
  return fd;
719
0
}
720
721
/**
722
 * Common steps for the inner git_deflate() loop for writing loose
723
 * objects. Returns what git_deflate() returns.
724
 */
725
static int write_loose_object_common(struct odb_source_loose *loose,
726
             struct git_hash_ctx *c, struct git_hash_ctx *compat_c,
727
             git_zstream *stream, const int flush,
728
             unsigned char *in0, const int fd,
729
             unsigned char *compressed,
730
             const size_t compressed_len)
731
0
{
732
0
  const struct git_hash_algo *compat = loose->base.odb->repo->compat_hash_algo;
733
0
  int ret;
734
735
0
  ret = git_deflate(stream, flush ? Z_FINISH : 0);
736
0
  git_hash_update(c, in0, stream->next_in - in0);
737
0
  if (compat && compat_c)
738
0
    git_hash_update(compat_c, in0, stream->next_in - in0);
739
0
  if (write_in_full(fd, compressed, stream->next_out - compressed) < 0)
740
0
    die_errno(_("unable to write loose object file"));
741
0
  stream->next_out = compressed;
742
0
  stream->avail_out = compressed_len;
743
744
0
  return ret;
745
0
}
746
747
/**
748
 * Common steps for loose object writers to end writing loose objects:
749
 *
750
 * - End the compression of zlib stream.
751
 * - Get the calculated oid to "oid".
752
 */
753
static int end_loose_object_common(struct odb_source_loose *loose,
754
           struct git_hash_ctx *c, struct git_hash_ctx *compat_c,
755
           git_zstream *stream, struct object_id *oid,
756
           struct object_id *compat_oid)
757
0
{
758
0
  const struct git_hash_algo *compat = loose->base.odb->repo->compat_hash_algo;
759
0
  int ret;
760
761
0
  ret = git_deflate_end_gently(stream);
762
0
  if (ret != Z_OK)
763
0
    return ret;
764
0
  git_hash_final_oid(oid, c);
765
0
  if (compat && compat_c)
766
0
    git_hash_final_oid(compat_oid, compat_c);
767
768
0
  return Z_OK;
769
0
}
770
771
static int write_loose_object(struct odb_source_loose *loose,
772
            const struct object_id *oid, char *hdr,
773
            int hdrlen, const void *buf, unsigned long len,
774
            const time_t *mtime, unsigned flags)
775
0
{
776
0
  int fd, ret;
777
0
  unsigned char compressed[4096];
778
0
  git_zstream stream;
779
0
  struct git_hash_ctx c;
780
0
  struct object_id parano_oid;
781
0
  static struct strbuf tmp_file = STRBUF_INIT;
782
0
  static struct strbuf filename = STRBUF_INIT;
783
784
0
  if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
785
0
    odb_transaction_files_prepare(loose->base.odb->transaction);
786
787
0
  odb_loose_path(loose, &filename, oid);
788
789
0
  fd = start_loose_object_common(loose, &tmp_file, filename.buf, flags,
790
0
               &stream, compressed, sizeof(compressed),
791
0
               &c, NULL, hdr, hdrlen);
792
0
  if (fd < 0)
793
0
    return -1;
794
795
  /* Then the data itself.. */
796
0
  stream.next_in = (void *)buf;
797
0
  stream.avail_in = len;
798
0
  do {
799
0
    unsigned char *in0 = stream.next_in;
800
801
0
    ret = write_loose_object_common(loose, &c, NULL, &stream, 1, in0, fd,
802
0
            compressed, sizeof(compressed));
803
0
  } while (ret == Z_OK);
804
805
0
  if (ret != Z_STREAM_END)
806
0
    die(_("unable to deflate new object %s (%d)"), oid_to_hex(oid),
807
0
        ret);
808
0
  ret = end_loose_object_common(loose, &c, NULL, &stream, &parano_oid, NULL);
809
0
  if (ret != Z_OK)
810
0
    die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid),
811
0
        ret);
812
0
  if (!oideq(oid, &parano_oid))
813
0
    die(_("confused by unstable object source data for %s"),
814
0
        oid_to_hex(oid));
815
816
0
  close_loose_object(loose, fd, tmp_file.buf);
817
818
0
  if (mtime) {
819
0
    struct utimbuf utb = {
820
0
      .actime = *mtime,
821
0
      .modtime = *mtime,
822
0
    };
823
824
0
    if (utime(tmp_file.buf, &utb) < 0 &&
825
0
        !(flags & ODB_WRITE_OBJECT_SILENT))
826
0
      warning_errno(_("failed utime() on %s"), tmp_file.buf);
827
0
  }
828
829
0
  return finalize_object_file_flags(loose->base.odb->repo, tmp_file.buf, filename.buf,
830
0
            FOF_SKIP_COLLISION_CHECK);
831
0
}
832
833
static int odb_source_loose_write_object(struct odb_source *source,
834
           const void *buf, size_t len,
835
           enum object_type type,
836
           const struct object_id *oid,
837
           const struct object_id *compat_oid,
838
           const time_t *mtime,
839
           enum odb_write_object_flags flags)
840
0
{
841
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
842
0
  char hdr[MAX_HEADER_LEN];
843
0
  int hdrlen;
844
845
0
  hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
846
847
0
  if (write_loose_object(loose, oid, hdr, hdrlen, buf, len, mtime, flags))
848
0
    return -1;
849
850
0
  if (compat_oid)
851
0
    return repo_add_loose_object_map(loose, oid, compat_oid);
852
853
0
  return 0;
854
0
}
855
856
static int odb_source_loose_write_object_stream(struct odb_source *source,
857
            struct odb_stream *in_stream,
858
            struct object_id *oid)
859
0
{
860
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
861
0
  const struct git_hash_algo *compat = loose->base.odb->repo->compat_hash_algo;
862
0
  struct object_id compat_oid;
863
0
  int fd, ret, err = 0, flush = 0;
864
0
  unsigned char compressed[4096];
865
0
  git_zstream stream;
866
0
  struct git_hash_ctx c, compat_c;
867
0
  struct strbuf tmp_file = STRBUF_INIT;
868
0
  struct strbuf filename = STRBUF_INIT;
869
0
  unsigned char buf[8192];
870
0
  int dirlen;
871
0
  bool is_finished = false;
872
0
  char hdr[MAX_HEADER_LEN];
873
0
  int hdrlen;
874
875
0
  if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
876
0
    odb_transaction_files_prepare(loose->base.odb->transaction);
877
878
  /* Since oid is not determined, save tmp file to odb path. */
879
0
  strbuf_addf(&filename, "%s/", loose->base.path);
880
0
  hdrlen = format_object_header(hdr, sizeof(hdr), in_stream->type, in_stream->size);
881
882
  /*
883
   * Common steps for write_loose_object and stream_loose_object to
884
   * start writing loose objects:
885
   *
886
   *  - Create tmpfile for the loose object.
887
   *  - Setup zlib stream for compression.
888
   *  - Start to feed header to zlib stream.
889
   */
890
0
  fd = start_loose_object_common(loose, &tmp_file, filename.buf, 0,
891
0
               &stream, compressed, sizeof(compressed),
892
0
               &c, &compat_c, hdr, hdrlen);
893
0
  if (fd < 0) {
894
0
    err = -1;
895
0
    goto cleanup;
896
0
  }
897
898
  /* Then the data itself.. */
899
0
  do {
900
0
    unsigned char *in0 = stream.next_in;
901
902
0
    if (!stream.avail_in && !is_finished) {
903
0
      ssize_t read_len = odb_stream_read(in_stream, buf,
904
0
                 sizeof(buf));
905
0
      if (read_len < 0) {
906
0
        close(fd);
907
0
        err = -1;
908
0
        goto cleanup;
909
0
      }
910
911
      /* All data has been read. */
912
0
      if (!read_len) {
913
0
        is_finished = true;
914
0
        flush = 1;
915
0
      }
916
917
0
      stream.avail_in = read_len;
918
0
      stream.next_in = buf;
919
0
      in0 = buf;
920
0
    }
921
0
    ret = write_loose_object_common(loose, &c, &compat_c, &stream, flush, in0, fd,
922
0
            compressed, sizeof(compressed));
923
    /*
924
     * Unlike write_loose_object(), we do not have the entire
925
     * buffer. If we get Z_BUF_ERROR due to too few input bytes,
926
     * then we'll replenish them in the next input_stream->read()
927
     * call when we loop.
928
     */
929
0
  } while (ret == Z_OK || ret == Z_BUF_ERROR);
930
931
0
  if (stream.total_in != in_stream->size + hdrlen)
932
0
    die(_("write stream object %"PRIuMAX" != %"PRIuMAX), (uintmax_t)stream.total_in,
933
0
        (uintmax_t)in_stream->size + hdrlen);
934
935
  /*
936
   * Common steps for write_loose_object and stream_loose_object to
937
   * end writing loose object:
938
   *
939
   *  - End the compression of zlib stream.
940
   *  - Get the calculated oid.
941
   */
942
0
  if (ret != Z_STREAM_END)
943
0
    die(_("unable to stream deflate new object (%d)"), ret);
944
0
  ret = end_loose_object_common(loose, &c, &compat_c, &stream, oid, &compat_oid);
945
0
  if (ret != Z_OK)
946
0
    die(_("deflateEnd on stream object failed (%d)"), ret);
947
0
  close_loose_object(loose, fd, tmp_file.buf);
948
949
0
  if (odb_freshen_object(loose->base.odb, oid)) {
950
0
    unlink_or_warn(tmp_file.buf);
951
0
    goto cleanup;
952
0
  }
953
0
  odb_loose_path(loose, &filename, oid);
954
955
  /* We finally know the object path, and create the missing dir. */
956
0
  dirlen = directory_size(filename.buf);
957
0
  if (dirlen) {
958
0
    struct strbuf dir = STRBUF_INIT;
959
0
    strbuf_add(&dir, filename.buf, dirlen);
960
961
0
    if (safe_create_dir_in_gitdir(loose->base.odb->repo, dir.buf) &&
962
0
        errno != EEXIST) {
963
0
      err = error_errno(_("unable to create directory %s"), dir.buf);
964
0
      strbuf_release(&dir);
965
0
      goto cleanup;
966
0
    }
967
0
    strbuf_release(&dir);
968
0
  }
969
970
0
  err = finalize_object_file_flags(loose->base.odb->repo, tmp_file.buf, filename.buf,
971
0
           FOF_SKIP_COLLISION_CHECK);
972
0
  if (!err && compat)
973
0
    err = repo_add_loose_object_map(loose, oid, &compat_oid);
974
0
cleanup:
975
0
  strbuf_release(&tmp_file);
976
0
  strbuf_release(&filename);
977
0
  return err;
978
0
}
979
980
static int odb_source_loose_begin_transaction(struct odb_source *source UNUSED,
981
                struct odb_transaction **out UNUSED,
982
                enum odb_transaction_flags flags UNUSED)
983
0
{
984
  /* TODO: this is a known omission that we'll want to address eventually. */
985
0
  return error("loose source does not support transactions");
986
0
}
987
988
static int odb_source_loose_read_alternates(struct odb_source *source UNUSED,
989
              struct strvec *out UNUSED)
990
0
{
991
0
  return 0;
992
0
}
993
994
static void odb_source_loose_clear_cache(struct odb_source_loose *loose)
995
0
{
996
0
  oidtree_clear(loose->cache);
997
0
  FREE_AND_NULL(loose->cache);
998
0
  memset(&loose->subdir_seen, 0,
999
0
         sizeof(loose->subdir_seen));
1000
0
}
1001
1002
static void odb_source_loose_prepare(struct odb_source *source,
1003
             enum odb_prepare_flags flags)
1004
0
{
1005
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
1006
0
  if (flags & ODB_PREPARE_FLUSH_CACHES)
1007
0
    odb_source_loose_clear_cache(loose);
1008
0
}
1009
1010
static void odb_source_loose_close(struct odb_source *source UNUSED)
1011
0
{
1012
  /* Nothing to do. */
1013
0
}
1014
1015
static void odb_source_loose_reparent(const char *old_cwd,
1016
              const char *new_cwd,
1017
              void *cb_data)
1018
0
{
1019
0
  struct odb_source_loose *loose = cb_data;
1020
0
  char *path = reparent_relative_path(old_cwd, new_cwd,
1021
0
              loose->base.path);
1022
0
  free(loose->base.path);
1023
0
  loose->base.path = path;
1024
0
}
1025
1026
static void odb_source_loose_free(struct odb_source *source)
1027
0
{
1028
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
1029
0
  odb_source_loose_clear_cache(loose);
1030
0
  loose_object_map_clear(&loose->map);
1031
0
  chdir_notify_unregister(odb_source_loose_reparent, loose);
1032
0
  odb_source_release(&loose->base);
1033
0
  free(loose);
1034
0
}
1035
1036
struct fsck_loose_data {
1037
  struct odb_source_loose *source;
1038
  struct odb_fsck_options *opts;
1039
  struct progress *progress;
1040
  bool error_found;
1041
};
1042
1043
static int fsck_loose(const struct object_id *oid, const char *path,
1044
          void *cb_data)
1045
0
{
1046
0
  struct fsck_loose_data *data = cb_data;
1047
0
  enum object_type type = OBJ_NONE;
1048
0
  size_t size;
1049
0
  void *contents = NULL;
1050
0
  int eaten = 0;
1051
0
  struct object_info oi = OBJECT_INFO_INIT;
1052
0
  struct object_id real_oid = *null_oid(data->source->base.odb->repo->hash_algo);
1053
0
  int err = 0;
1054
1055
0
  oi.sizep = &size;
1056
0
  oi.typep = &type;
1057
1058
0
  if (read_loose_object(data->source->base.odb->repo,
1059
0
            path, oid, &real_oid, &contents, &oi) < 0) {
1060
0
    if (contents && !oideq(&real_oid, oid))
1061
0
      err = error(_("%s: hash-path mismatch, found at: %s"),
1062
0
            oid_to_hex(&real_oid), path);
1063
0
    else
1064
0
      err = error(_("%s: object corrupt or missing: %s"),
1065
0
            oid_to_hex(oid), path);
1066
0
  }
1067
0
  if (err < 0)
1068
0
    goto out;
1069
1070
0
  if (!contents && type != OBJ_BLOB)
1071
0
    BUG("read_loose_object streamed a non-blob");
1072
1073
0
  if (data->opts->object_cb(oid, type, size, contents, &eaten,
1074
0
          data->opts->object_payload)) {
1075
0
    err = -1;
1076
0
    goto out;
1077
0
  }
1078
1079
0
out:
1080
0
  if (err)
1081
0
    data->error_found = true;
1082
0
  if (!eaten)
1083
0
    free(contents);
1084
0
  return 0; /* keep checking other objects, even if we saw an error */
1085
0
}
1086
1087
static int fsck_cruft(const char *basename, const char *path,
1088
          void *data UNUSED)
1089
0
{
1090
0
  if (!starts_with(basename, "tmp_obj_"))
1091
0
    fprintf_ln(stderr, _("bad sha1 file: %s"), path);
1092
0
  return 0;
1093
0
}
1094
1095
static int fsck_subdir(unsigned int nr, const char *path UNUSED, void *cb_data)
1096
0
{
1097
0
  struct fsck_loose_data *data = cb_data;
1098
0
  display_progress(data->progress, nr + 1);
1099
0
  return 0;
1100
0
}
1101
1102
static int odb_source_loose_fsck(struct odb_source *source,
1103
         struct odb_fsck_options *opts)
1104
0
{
1105
0
  struct odb_source_loose *loose = odb_source_loose_downcast(source);
1106
0
  struct fsck_loose_data data = {
1107
0
    .source = loose,
1108
0
    .opts = opts,
1109
0
  };
1110
1111
0
  if (opts->flags & ODB_FSCK_VERBOSE)
1112
0
    fprintf_ln(stderr, _("Checking object directory"));
1113
1114
0
  if (opts->flags & ODB_FSCK_PROGRESS)
1115
0
    data.progress = start_progress(source->odb->repo,
1116
0
                 _("Checking object directories"), 256);
1117
1118
0
  for_each_loose_file_in_source(source, fsck_loose,
1119
0
              fsck_cruft, fsck_subdir, &data);
1120
0
  display_progress(data.progress, 256);
1121
0
  stop_progress(&data.progress);
1122
1123
0
  return data.error_found ? -1 : 0;
1124
0
}
1125
1126
struct odb_source_loose *odb_source_loose_new(struct object_database *odb,
1127
                const char *path,
1128
                bool local)
1129
0
{
1130
0
  struct odb_source_loose *loose;
1131
1132
0
  CALLOC_ARRAY(loose, 1);
1133
0
  odb_source_init(&loose->base, odb, ODB_SOURCE_LOOSE, path, local);
1134
1135
0
  loose->base.free = odb_source_loose_free;
1136
0
  loose->base.close = odb_source_loose_close;
1137
0
  loose->base.prepare = odb_source_loose_prepare;
1138
0
  loose->base.fsck = odb_source_loose_fsck;
1139
0
  loose->base.read_object_info = odb_source_loose_read_object_info;
1140
0
  loose->base.read_object_stream = odb_source_loose_read_object_stream;
1141
0
  loose->base.for_each_object = odb_source_loose_for_each_object;
1142
0
  loose->base.find_abbrev_len = odb_source_loose_find_abbrev_len;
1143
0
  loose->base.count_objects = odb_source_loose_count_objects;
1144
0
  loose->base.freshen_object = odb_source_loose_freshen_object;
1145
0
  loose->base.write_object = odb_source_loose_write_object;
1146
0
  loose->base.write_object_stream = odb_source_loose_write_object_stream;
1147
0
  loose->base.begin_transaction = odb_source_loose_begin_transaction;
1148
0
  loose->base.read_alternates = odb_source_loose_read_alternates;
1149
1150
0
  if (!is_absolute_path(loose->base.path))
1151
0
    chdir_notify_register(odb_source_loose_reparent, loose);
1152
1153
0
  loose_object_map_load(loose);
1154
1155
0
  return loose;
1156
0
}