Skip to content

Commit 1c04a96

Browse files
author
Edward Thomson
committed
Honor core.fsyncObjectFiles
1 parent 3ac05d1 commit 1c04a96

File tree

13 files changed

+173
-55
lines changed

13 files changed

+173
-55
lines changed

src/config_cache.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static struct map_data _cvar_maps[] = {
7878
{"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
7979
{"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
8080
{"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
81+
{"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },
8182
};
8283

8384
int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)

src/indexer.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ struct git_indexer {
3434
unsigned int parsed_header :1,
3535
pack_committed :1,
3636
have_stream :1,
37-
have_delta :1;
37+
have_delta :1,
38+
do_fsync :1;
3839
struct git_pack_header hdr;
3940
struct git_pack_file *pack;
4041
unsigned int mode;
@@ -124,6 +125,9 @@ int git_indexer_new(
124125
git_hash_ctx_init(&idx->hash_ctx);
125126
git_hash_ctx_init(&idx->trailer);
126127

128+
if (git_object__synchronous_writing)
129+
idx->do_fsync = 1;
130+
127131
error = git_buf_joinpath(&path, prefix, suff);
128132
if (error < 0)
129133
goto cleanup;
@@ -162,6 +166,11 @@ int git_indexer_new(
162166
return -1;
163167
}
164168

169+
void git_indexer__set_fsync(git_indexer *idx, int do_fsync)
170+
{
171+
idx->do_fsync = !!do_fsync;
172+
}
173+
165174
/* Try to store the delta so we can try to resolve it later */
166175
static int store_delta(git_indexer *idx)
167176
{
@@ -991,7 +1000,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
9911000

9921001
if (git_filebuf_open(&index_file, filename.ptr,
9931002
GIT_FILEBUF_HASH_CONTENTS |
994-
(git_object__synchronous_writing ? GIT_FILEBUF_FSYNC : 0),
1003+
(idx->do_fsync ? GIT_FILEBUF_FSYNC : 0),
9951004
idx->mode) < 0)
9961005
goto on_error;
9971006

@@ -1069,7 +1078,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
10691078
return -1;
10701079
}
10711080

1072-
if (git_object__synchronous_writing && p_fsync(idx->pack->mwf.fd) < 0) {
1081+
if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
10731082
giterr_set(GITERR_OS, "failed to fsync packfile");
10741083
goto on_error;
10751084
}
@@ -1090,7 +1099,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
10901099
goto on_error;
10911100

10921101
/* And fsync the parent directory if we're asked to. */
1093-
if (git_object__synchronous_writing &&
1102+
if (idx->do_fsync &&
10941103
git_futils_fsync_parent(git_buf_cstr(&filename)) < 0)
10951104
goto on_error;
10961105

src/indexer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
#ifndef INCLUDE_indexer_h__
8+
#define INCLUDE_indexer_h__
9+
10+
extern int git_indexer__set_fsync(git_indexer *idx, int do_fsync);
11+
12+
#endif

src/odb.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
496496
return GIT_ENOTFOUND;
497497
}
498498

499-
static int add_default_backends(
499+
int git_odb__add_default_backends(
500500
git_odb *db, const char *objects_dir,
501501
bool as_alternates, int alternate_depth)
502502
{
@@ -531,7 +531,7 @@ static int add_default_backends(
531531
#endif
532532

533533
/* add the loose object backend */
534-
if (git_odb_backend_loose(&loose, objects_dir, -1, 0, 0, 0) < 0 ||
534+
if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
535535
add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0)
536536
return -1;
537537

@@ -586,7 +586,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_
586586
alternate = git_buf_cstr(&alternates_path);
587587
}
588588

589-
if ((result = add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0)
589+
if ((result = git_odb__add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0)
590590
break;
591591
}
592592

@@ -598,7 +598,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_
598598

599599
int git_odb_add_disk_alternate(git_odb *odb, const char *path)
600600
{
601-
return add_default_backends(odb, path, true, 0);
601+
return git_odb__add_default_backends(odb, path, true, 0);
602602
}
603603

604604
int git_odb_open(git_odb **out, const char *objects_dir)
@@ -612,7 +612,7 @@ int git_odb_open(git_odb **out, const char *objects_dir)
612612
if (git_odb_new(&db) < 0)
613613
return -1;
614614

615-
if (add_default_backends(db, objects_dir, 0, 0) < 0) {
615+
if (git_odb__add_default_backends(db, objects_dir, 0, 0) < 0) {
616616
git_odb_free(db);
617617
return -1;
618618
}
@@ -621,6 +621,24 @@ int git_odb_open(git_odb **out, const char *objects_dir)
621621
return 0;
622622
}
623623

624+
int git_odb__set_caps(git_odb *odb, int caps)
625+
{
626+
if (caps == GIT_ODB_CAP_FROM_OWNER) {
627+
git_repository *repo = odb->rc.owner;
628+
int val;
629+
630+
if (!repo) {
631+
giterr_set(GITERR_ODB, "cannot access repository to set odb caps");
632+
return -1;
633+
}
634+
635+
if (!git_repository__cvar(&val, repo, GIT_CVAR_FSYNCOBJECTFILES))
636+
odb->do_fsync = !!val;
637+
}
638+
639+
return 0;
640+
}
641+
624642
static void odb_free(git_odb *db)
625643
{
626644
size_t i;

src/odb.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,25 @@ struct git_odb {
3838
git_refcount rc;
3939
git_vector backends;
4040
git_cache own_cache;
41+
unsigned int do_fsync :1;
4142
};
4243

44+
typedef enum {
45+
GIT_ODB_CAP_FROM_OWNER = -1,
46+
} git_odb_cap_t;
47+
48+
/*
49+
* Set the capabilities for the object database.
50+
*/
51+
int git_odb__set_caps(git_odb *odb, int caps);
52+
53+
/*
54+
* Add the default loose and packed backends for a database.
55+
*/
56+
int git_odb__add_default_backends(
57+
git_odb *db, const char *objects_dir,
58+
bool as_alternates, int alternate_depth);
59+
4360
/*
4461
* Hash a git_rawobj internally.
4562
* The `git_rawobj` is supposed to be previously initialized

src/pack-objects.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,13 +1385,17 @@ int git_packbuilder_write(
13851385
git_indexer *indexer;
13861386
git_transfer_progress stats;
13871387
struct pack_write_context ctx;
1388+
int t;
13881389

13891390
PREPARE_PACK;
13901391

13911392
if (git_indexer_new(
13921393
&indexer, path, mode, pb->odb, progress_cb, progress_cb_payload) < 0)
13931394
return -1;
13941395

1396+
if (!git_repository__cvar(&t, pb->repo, GIT_CVAR_FSYNCOBJECTFILES) && t)
1397+
git_indexer__set_fsync(indexer, 1);
1398+
13951399
ctx.indexer = indexer;
13961400
ctx.stats = &stats;
13971401

src/pack-objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "netops.h"
1717
#include "zstream.h"
1818
#include "pool.h"
19+
#include "indexer.h"
1920

2021
#include "git2/oid.h"
2122
#include "git2/pack.h"

src/refdb_fs.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typedef struct refdb_fs_backend {
6262
int peeling_mode;
6363
git_iterator_flag_t iterator_flags;
6464
uint32_t direach_flags;
65+
int fsync;
6566
} refdb_fs_backend;
6667

6768
static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name);
@@ -756,7 +757,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
756757
return -1;
757758

758759
filebuf_flags = GIT_FILEBUF_FORCE;
759-
if (git_object__synchronous_writing)
760+
if (backend->fsync)
760761
filebuf_flags |= GIT_FILEBUF_FSYNC;
761762

762763
error = git_filebuf_open(file, ref_path.ptr, filebuf_flags, GIT_REFS_FILE_MODE);
@@ -1001,7 +1002,7 @@ static int packed_write(refdb_fs_backend *backend)
10011002
if ((error = git_sortedcache_wlock(refcache)) < 0)
10021003
return error;
10031004

1004-
if (git_object__synchronous_writing)
1005+
if (backend->fsync)
10051006
open_flags = GIT_FILEBUF_FSYNC;
10061007

10071008
/* Open the file! */
@@ -1861,7 +1862,7 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co
18611862

18621863
open_flags = O_WRONLY | O_CREAT | O_APPEND;
18631864

1864-
if (git_object__synchronous_writing)
1865+
if (backend->fsync)
18651866
open_flags |= O_FSYNC;
18661867

18671868
error = git_futils_writebuffer(&buf, git_buf_cstr(&path), open_flags, GIT_REFLOG_FILE_MODE);
@@ -2014,6 +2015,9 @@ int git_refdb_backend_fs(
20142015
backend->iterator_flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE;
20152016
backend->direach_flags |= GIT_PATH_DIR_PRECOMPOSE_UNICODE;
20162017
}
2018+
if ((!git_repository__cvar(&t, backend->repo, GIT_CVAR_FSYNCOBJECTFILES) && t) ||
2019+
git_object__synchronous_writing)
2020+
backend->fsync = 1;
20172021

20182022
backend->parent.exists = &refdb_fs_backend__exists;
20192023
backend->parent.lookup = &refdb_fs_backend__lookup;

src/repository.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,18 +1055,22 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
10551055
git_odb *odb;
10561056

10571057
if ((error = git_repository_item_path(&odb_path, repo,
1058-
GIT_REPOSITORY_ITEM_OBJECTS)) < 0)
1058+
GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
1059+
(error = git_odb_new(&odb)) < 0)
10591060
return error;
10601061

1061-
error = git_odb_open(&odb, odb_path.ptr);
1062-
if (!error) {
1063-
GIT_REFCOUNT_OWN(odb, repo);
1062+
GIT_REFCOUNT_OWN(odb, repo);
10641063

1065-
odb = git__compare_and_swap(&repo->_odb, NULL, odb);
1066-
if (odb != NULL) {
1067-
GIT_REFCOUNT_OWN(odb, NULL);
1068-
git_odb_free(odb);
1069-
}
1064+
if ((error = git_odb__set_caps(odb, GIT_ODB_CAP_FROM_OWNER)) < 0 ||
1065+
(error = git_odb__add_default_backends(odb, odb_path.ptr, 0, 0)) < 0) {
1066+
git_odb_free(odb);
1067+
return error;
1068+
}
1069+
1070+
odb = git__compare_and_swap(&repo->_odb, NULL, odb);
1071+
if (odb != NULL) {
1072+
GIT_REFCOUNT_OWN(odb, NULL);
1073+
git_odb_free(odb);
10701074
}
10711075

10721076
git_buf_free(&odb_path);

src/repository.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef enum {
4646
GIT_CVAR_LOGALLREFUPDATES, /* core.logallrefupdates */
4747
GIT_CVAR_PROTECTHFS, /* core.protectHFS */
4848
GIT_CVAR_PROTECTNTFS, /* core.protectNTFS */
49+
GIT_CVAR_FSYNCOBJECTFILES, /* core.fsyncObjectFiles */
4950
GIT_CVAR_CACHE_MAX
5051
} git_cvar_cached;
5152

@@ -106,6 +107,8 @@ typedef enum {
106107
GIT_PROTECTHFS_DEFAULT = GIT_CVAR_FALSE,
107108
/* core.protectNTFS */
108109
GIT_PROTECTNTFS_DEFAULT = GIT_CVAR_FALSE,
110+
/* core.fsyncObjectFiles */
111+
GIT_FSYNCOBJECTFILES_DEFAULT = GIT_CVAR_FALSE,
109112
} git_cvar_value;
110113

111114
/* internal repository init flags */

0 commit comments

Comments
 (0)