Skip to content

Commit b9f4bd7

Browse files
committed
Merge branch 'kn/reftable-consistency-checks' into next
The reftable backend learned to sanity check its on-disk data more carefully. * kn/reftable-consistency-checks: refs/reftable: add fsck check for checking the table name reftable: add code to facilitate consistency checks fsck: order 'fsck_msg_type' alphabetically Documentation/fsck-msgids: remove duplicate msg id reftable: check for trailing newline in 'tables.list' refs: move consistency check msg to generic layer refs: remove unused headers
2 parents 6c9690a + 466a3a1 commit b9f4bd7

File tree

16 files changed

+330
-59
lines changed

16 files changed

+330
-59
lines changed

Documentation/fsck-msgids.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
`badReferentName`::
3939
(ERROR) The referent name of a symref is invalid.
4040

41+
`badReftableTableName`::
42+
(WARN) A reftable table has an invalid name.
43+
4144
`badTagName`::
4245
(INFO) A tag has an invalid format.
4346

@@ -104,9 +107,6 @@
104107
`gitmodulesParse`::
105108
(INFO) Could not parse `.gitmodules` blob.
106109

107-
`gitmodulesLarge`;
108-
(ERROR) `.gitmodules` blob is too large to parse.
109-
110110
`gitmodulesPath`::
111111
(ERROR) `.gitmodules` path is invalid.
112112

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2767,9 +2767,10 @@ XDIFF_OBJS += xdiff/xutils.o
27672767
xdiff-objs: $(XDIFF_OBJS)
27682768

27692769
REFTABLE_OBJS += reftable/basics.o
2770-
REFTABLE_OBJS += reftable/error.o
27712770
REFTABLE_OBJS += reftable/block.o
27722771
REFTABLE_OBJS += reftable/blocksource.o
2772+
REFTABLE_OBJS += reftable/error.o
2773+
REFTABLE_OBJS += reftable/fsck.o
27732774
REFTABLE_OBJS += reftable/iter.o
27742775
REFTABLE_OBJS += reftable/merged.o
27752776
REFTABLE_OBJS += reftable/pq.o

fsck.h

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,27 @@ enum fsck_msg_type {
3333
FUNC(BAD_PACKED_REF_ENTRY, ERROR) \
3434
FUNC(BAD_PACKED_REF_HEADER, ERROR) \
3535
FUNC(BAD_PARENT_SHA1, ERROR) \
36+
FUNC(BAD_REFERENT_NAME, ERROR) \
3637
FUNC(BAD_REF_CONTENT, ERROR) \
3738
FUNC(BAD_REF_FILETYPE, ERROR) \
3839
FUNC(BAD_REF_NAME, ERROR) \
39-
FUNC(BAD_REFERENT_NAME, ERROR) \
4040
FUNC(BAD_TIMEZONE, ERROR) \
4141
FUNC(BAD_TREE, ERROR) \
4242
FUNC(BAD_TREE_SHA1, ERROR) \
4343
FUNC(BAD_TYPE, ERROR) \
4444
FUNC(DUPLICATE_ENTRIES, ERROR) \
45+
FUNC(GITATTRIBUTES_BLOB, ERROR) \
46+
FUNC(GITATTRIBUTES_LARGE, ERROR) \
47+
FUNC(GITATTRIBUTES_LINE_LENGTH, ERROR) \
48+
FUNC(GITATTRIBUTES_MISSING, ERROR) \
49+
FUNC(GITMODULES_BLOB, ERROR) \
50+
FUNC(GITMODULES_LARGE, ERROR) \
51+
FUNC(GITMODULES_MISSING, ERROR) \
52+
FUNC(GITMODULES_NAME, ERROR) \
53+
FUNC(GITMODULES_PATH, ERROR) \
54+
FUNC(GITMODULES_SYMLINK, ERROR) \
55+
FUNC(GITMODULES_UPDATE, ERROR) \
56+
FUNC(GITMODULES_URL, ERROR) \
4557
FUNC(MISSING_AUTHOR, ERROR) \
4658
FUNC(MISSING_COMMITTER, ERROR) \
4759
FUNC(MISSING_EMAIL, ERROR) \
@@ -60,39 +72,28 @@ enum fsck_msg_type {
6072
FUNC(TREE_NOT_SORTED, ERROR) \
6173
FUNC(UNKNOWN_TYPE, ERROR) \
6274
FUNC(ZERO_PADDED_DATE, ERROR) \
63-
FUNC(GITMODULES_MISSING, ERROR) \
64-
FUNC(GITMODULES_BLOB, ERROR) \
65-
FUNC(GITMODULES_LARGE, ERROR) \
66-
FUNC(GITMODULES_NAME, ERROR) \
67-
FUNC(GITMODULES_SYMLINK, ERROR) \
68-
FUNC(GITMODULES_URL, ERROR) \
69-
FUNC(GITMODULES_PATH, ERROR) \
70-
FUNC(GITMODULES_UPDATE, ERROR) \
71-
FUNC(GITATTRIBUTES_MISSING, ERROR) \
72-
FUNC(GITATTRIBUTES_LARGE, ERROR) \
73-
FUNC(GITATTRIBUTES_LINE_LENGTH, ERROR) \
74-
FUNC(GITATTRIBUTES_BLOB, ERROR) \
7575
/* warnings */ \
76+
FUNC(BAD_REFTABLE_TABLE_NAME, WARN) \
7677
FUNC(EMPTY_NAME, WARN) \
7778
FUNC(FULL_PATHNAME, WARN) \
7879
FUNC(HAS_DOT, WARN) \
7980
FUNC(HAS_DOTDOT, WARN) \
8081
FUNC(HAS_DOTGIT, WARN) \
82+
FUNC(LARGE_PATHNAME, WARN) \
8183
FUNC(NULL_SHA1, WARN) \
82-
FUNC(ZERO_PADDED_FILEMODE, WARN) \
8384
FUNC(NUL_IN_COMMIT, WARN) \
84-
FUNC(LARGE_PATHNAME, WARN) \
85+
FUNC(ZERO_PADDED_FILEMODE, WARN) \
8586
/* infos (reported as warnings, but ignored by default) */ \
8687
FUNC(BAD_FILEMODE, INFO) \
88+
FUNC(BAD_TAG_NAME, INFO) \
8789
FUNC(EMPTY_PACKED_REFS_FILE, INFO) \
88-
FUNC(GITMODULES_PARSE, INFO) \
89-
FUNC(GITIGNORE_SYMLINK, INFO) \
9090
FUNC(GITATTRIBUTES_SYMLINK, INFO) \
91+
FUNC(GITIGNORE_SYMLINK, INFO) \
92+
FUNC(GITMODULES_PARSE, INFO) \
9193
FUNC(MAILMAP_SYMLINK, INFO) \
92-
FUNC(BAD_TAG_NAME, INFO) \
9394
FUNC(MISSING_TAGGER_ENTRY, INFO) \
94-
FUNC(SYMLINK_REF, INFO) \
9595
FUNC(REF_MISSING_NEWLINE, INFO) \
96+
FUNC(SYMLINK_REF, INFO) \
9697
FUNC(SYMREF_TARGET_IS_NOT_A_REF, INFO) \
9798
FUNC(TRAILING_REF_CONTENT, INFO) \
9899
/* ignored (elevated when requested) */ \

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ libgit_sources = [
452452
'reftable/error.c',
453453
'reftable/block.c',
454454
'reftable/blocksource.c',
455+
'reftable/fsck.c',
455456
'reftable/iter.c',
456457
'reftable/merged.c',
457458
'reftable/pq.c',

refs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "commit.h"
3333
#include "wildmatch.h"
3434
#include "ident.h"
35+
#include "fsck.h"
3536

3637
/*
3738
* List of all available backends
@@ -323,6 +324,9 @@ int check_refname_format(const char *refname, int flags)
323324
int refs_fsck(struct ref_store *refs, struct fsck_options *o,
324325
struct worktree *wt)
325326
{
327+
if (o->verbose)
328+
fprintf_ln(stderr, _("Checking references consistency"));
329+
326330
return refs->be->fsck(refs, o, wt);
327331
}
328332

refs/debug.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "git-compat-util.h"
22
#include "hex.h"
33
#include "refs-internal.h"
4-
#include "string-list.h"
54
#include "trace.h"
65

76
static struct trace_key trace_refs = TRACE_KEY_INIT(REFS);

refs/files-backend.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "../dir-iterator.h"
2121
#include "../lockfile.h"
2222
#include "../object.h"
23-
#include "../object-file.h"
2423
#include "../path.h"
2524
#include "../dir.h"
2625
#include "../chdir-notify.h"
@@ -3970,8 +3969,6 @@ static int files_fsck_refs(struct ref_store *ref_store,
39703969
NULL,
39713970
};
39723971

3973-
if (o->verbose)
3974-
fprintf_ln(stderr, _("Checking references consistency"));
39753972
return files_fsck_refs_dir(ref_store, o, "refs", wt, fsck_refs_fn);
39763973
}
39773974

refs/reftable-backend.c

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@
66
#include "../config.h"
77
#include "../dir.h"
88
#include "../environment.h"
9+
#include "../fsck.h"
910
#include "../gettext.h"
1011
#include "../hash.h"
1112
#include "../hex.h"
1213
#include "../iterator.h"
1314
#include "../ident.h"
14-
#include "../lockfile.h"
1515
#include "../object.h"
1616
#include "../path.h"
1717
#include "../refs.h"
1818
#include "../reftable/reftable-basics.h"
19-
#include "../reftable/reftable-stack.h"
20-
#include "../reftable/reftable-record.h"
2119
#include "../reftable/reftable-error.h"
20+
#include "../reftable/reftable-fsck.h"
2221
#include "../reftable/reftable-iterator.h"
22+
#include "../reftable/reftable-record.h"
23+
#include "../reftable/reftable-stack.h"
2324
#include "../repo-settings.h"
2425
#include "../setup.h"
2526
#include "../strmap.h"
@@ -2714,11 +2715,56 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
27142715
return ret;
27152716
}
27162717

2717-
static int reftable_be_fsck(struct ref_store *ref_store UNUSED,
2718-
struct fsck_options *o UNUSED,
2718+
static void reftable_fsck_verbose_handler(const char *msg, void *cb_data)
2719+
{
2720+
struct fsck_options *o = cb_data;
2721+
2722+
if (o->verbose)
2723+
fprintf_ln(stderr, "%s", msg);
2724+
}
2725+
2726+
static const enum fsck_msg_id fsck_msg_id_map[] = {
2727+
[REFTABLE_FSCK_ERROR_TABLE_NAME] = FSCK_MSG_BAD_REFTABLE_TABLE_NAME,
2728+
};
2729+
2730+
static int reftable_fsck_error_handler(struct reftable_fsck_info *info,
2731+
void *cb_data)
2732+
{
2733+
struct fsck_ref_report report = { .path = info->path };
2734+
struct fsck_options *o = cb_data;
2735+
enum fsck_msg_id msg_id;
2736+
2737+
if (info->error < 0 || info->error >= REFTABLE_FSCK_MAX_VALUE)
2738+
BUG("unknown fsck error: %d", (int)info->error);
2739+
2740+
msg_id = fsck_msg_id_map[info->error];
2741+
2742+
if (!msg_id)
2743+
BUG("fsck_msg_id value missing for reftable error: %d", (int)info->error);
2744+
2745+
return fsck_report_ref(o, &report, msg_id, "%s", info->msg);
2746+
}
2747+
2748+
static int reftable_be_fsck(struct ref_store *ref_store, struct fsck_options *o,
27192749
struct worktree *wt UNUSED)
27202750
{
2721-
return 0;
2751+
struct reftable_ref_store *refs;
2752+
struct strmap_entry *entry;
2753+
struct hashmap_iter iter;
2754+
int ret = 0;
2755+
2756+
refs = reftable_be_downcast(ref_store, REF_STORE_READ, "fsck");
2757+
2758+
ret |= reftable_fsck_check(refs->main_backend.stack, reftable_fsck_error_handler,
2759+
reftable_fsck_verbose_handler, o);
2760+
2761+
strmap_for_each_entry(&refs->worktree_backends, &iter, entry) {
2762+
struct reftable_backend *b = (struct reftable_backend *)entry->value;
2763+
ret |= reftable_fsck_check(b->stack, reftable_fsck_error_handler,
2764+
reftable_fsck_verbose_handler, o);
2765+
}
2766+
2767+
return ret;
27222768
}
27232769

27242770
struct ref_storage_be refs_be_reftable = {

reftable/basics.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -195,44 +195,55 @@ size_t names_length(const char **names)
195195
return p - names;
196196
}
197197

198-
char **parse_names(char *buf, int size)
198+
int parse_names(char *buf, int size, char ***out)
199199
{
200200
char **names = NULL;
201201
size_t names_cap = 0;
202202
size_t names_len = 0;
203203
char *p = buf;
204204
char *end = buf + size;
205+
int err = 0;
205206

206207
while (p < end) {
207208
char *next = strchr(p, '\n');
208-
if (next && next < end) {
209-
*next = 0;
209+
if (!next) {
210+
err = REFTABLE_FORMAT_ERROR;
211+
goto done;
212+
} else if (next < end) {
213+
*next = '\0';
210214
} else {
211215
next = end;
212216
}
217+
213218
if (p < next) {
214219
if (REFTABLE_ALLOC_GROW(names, names_len + 1,
215-
names_cap))
216-
goto err;
220+
names_cap)) {
221+
err = REFTABLE_OUT_OF_MEMORY_ERROR;
222+
goto done;
223+
}
217224

218225
names[names_len] = reftable_strdup(p);
219-
if (!names[names_len++])
220-
goto err;
226+
if (!names[names_len++]) {
227+
err = REFTABLE_OUT_OF_MEMORY_ERROR;
228+
goto done;
229+
}
221230
}
222231
p = next + 1;
223232
}
224233

225-
if (REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap))
226-
goto err;
234+
if (REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap)) {
235+
err = REFTABLE_OUT_OF_MEMORY_ERROR;
236+
goto done;
237+
}
227238
names[names_len] = NULL;
228239

229-
return names;
230-
231-
err:
240+
*out = names;
241+
return 0;
242+
done:
232243
for (size_t i = 0; i < names_len; i++)
233244
reftable_free(names[i]);
234245
reftable_free(names);
235-
return NULL;
246+
return err;
236247
}
237248

238249
int names_equal(const char **a, const char **b)

reftable/basics.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,11 @@ void free_names(char **a);
167167

168168
/*
169169
* Parse a newline separated list of names. `size` is the length of the buffer,
170-
* without terminating '\0'. Empty names are discarded. Returns a `NULL`
171-
* pointer when allocations fail.
170+
* without terminating '\0'. Empty names are discarded.
171+
*
172+
* Returns 0 on success, a reftable error code on error.
172173
*/
173-
char **parse_names(char *buf, int size);
174+
int parse_names(char *buf, int size, char ***out);
174175

175176
/* compares two NULL-terminated arrays of strings. */
176177
int names_equal(const char **a, const char **b);

0 commit comments

Comments
 (0)