core.fsync: add configuration parsing

This change introduces code to parse the core.fsync setting and
configure the fsync_components variable.

core.fsync is configured as a comma-separated list of component names to
sync. Each time a core.fsync variable is encountered in the
configuration heirarchy, we start off with a clean state with the
platform default value. Passing 'none' resets the value to indicate
nothing will be synced. We gather all negative and positive entries from
the comma separated list and then compute the new value by removing all
the negative entries and adding all of the positive entries.

We issue a warning for components that are not recognized so that the
configuration code is compatible with configs from future versions of
Git with more repo components.

Complete documentation for the new setting is included in a later patch
in the series so that it can be reviewed once in final form.

Signed-off-by: Neeraj Singh <neerajsi@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Neeraj Singh 2022-03-10 22:43:22 +00:00 committed by Junio C Hamano
parent 020406eaa5
commit 844a8ad4f8
3 changed files with 82 additions and 5 deletions

View File

@ -558,11 +558,12 @@ core.fsyncMethod::
core.fsyncObjectFiles::
This boolean will enable 'fsync()' when writing object files.
This setting is deprecated. Use core.fsync instead.
+
This is a total waste of time and effort on a filesystem that orders
data writes properly, but can be useful for filesystems that do not use
journalling (traditional UNIX filesystems) or that only journal metadata
and not file contents (OS X's HFS+, or Linux ext3 with "data=writeback").
This setting affects data added to the Git repository in loose-object
form. When set to true, Git will issue an fsync or similar system call
to flush caches so that loose-objects remain consistent in the face
of a unclean system shutdown.
core.preloadIndex::
Enable parallel index preload for operations like 'git diff'

View File

@ -1323,6 +1323,73 @@ static int git_parse_maybe_bool_text(const char *value)
return -1;
}
static const struct fsync_component_name {
const char *name;
enum fsync_component component_bits;
} fsync_component_names[] = {
{ "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT },
{ "pack", FSYNC_COMPONENT_PACK },
{ "pack-metadata", FSYNC_COMPONENT_PACK_METADATA },
{ "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH },
};
static enum fsync_component parse_fsync_components(const char *var, const char *string)
{
enum fsync_component current = FSYNC_COMPONENTS_DEFAULT;
enum fsync_component positive = 0, negative = 0;
while (string) {
int i;
size_t len;
const char *ep;
int negated = 0;
int found = 0;
string = string + strspn(string, ", \t\n\r");
ep = strchrnul(string, ',');
len = ep - string;
if (!strcmp(string, "none")) {
current = FSYNC_COMPONENT_NONE;
goto next_name;
}
if (*string == '-') {
negated = 1;
string++;
len--;
if (!len)
warning(_("invalid value for variable %s"), var);
}
if (!len)
break;
for (i = 0; i < ARRAY_SIZE(fsync_component_names); ++i) {
const struct fsync_component_name *n = &fsync_component_names[i];
if (strncmp(n->name, string, len))
continue;
found = 1;
if (negated)
negative |= n->component_bits;
else
positive |= n->component_bits;
}
if (!found) {
char *component = xstrndup(string, len);
warning(_("ignoring unknown core.fsync component '%s'"), component);
free(component);
}
next_name:
string = ep;
}
return (current & ~negative) | positive;
}
int git_parse_maybe_bool(const char *value)
{
int v = git_parse_maybe_bool_text(value);
@ -1600,6 +1667,13 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
return 0;
}
if (!strcmp(var, "core.fsync")) {
if (!value)
return config_error_nonbool(var);
fsync_components = parse_fsync_components(var, value);
return 0;
}
if (!strcmp(var, "core.fsyncmethod")) {
if (!value)
return config_error_nonbool(var);
@ -1613,6 +1687,8 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
}
if (!strcmp(var, "core.fsyncobjectfiles")) {
if (fsync_object_files < 0)
warning(_("core.fsyncobjectfiles is deprecated; use core.fsync instead"));
fsync_object_files = git_config_bool(var, value);
return 0;
}

View File

@ -42,7 +42,7 @@ const char *git_attributes_file;
const char *git_hooks_path;
int zlib_compression_level = Z_BEST_SPEED;
int pack_compression_level = Z_DEFAULT_COMPRESSION;
int fsync_object_files;
int fsync_object_files = -1;
int use_fsync = -1;
enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;
enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;