Skip to content

Commit 04d3975

Browse files
torvaldsgitster
authored andcommitted
fsck: reduce stack footprint
The logic to mark all objects that are reachable from tips of refs were implemented as a set of recursive functions. In a repository with a deep enough history, this can easily eat up all the available stack space. Restructure the code to require less stackspace by using an object array to keep track of the objects that still need to be processed. Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c74faea commit 04d3975

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

builtin-fsck.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ static int fsck_error_func(struct object *obj, int type, const char *err, ...)
6464
return (type == FSCK_WARN) ? 0 : 1;
6565
}
6666

67+
static struct object_array pending;
68+
6769
static int mark_object(struct object *obj, int type, void *data)
6870
{
69-
struct tree *tree = NULL;
7071
struct object *parent = data;
71-
int result;
7272

7373
if (!obj) {
7474
printf("broken link from %7s %s\n",
@@ -96,6 +96,20 @@ static int mark_object(struct object *obj, int type, void *data)
9696
return 1;
9797
}
9898

99+
add_object_array(obj, (void *) parent, &pending);
100+
return 0;
101+
}
102+
103+
static void mark_object_reachable(struct object *obj)
104+
{
105+
mark_object(obj, OBJ_ANY, 0);
106+
}
107+
108+
static int traverse_one_object(struct object *obj, struct object *parent)
109+
{
110+
int result;
111+
struct tree *tree = NULL;
112+
99113
if (obj->type == OBJ_TREE) {
100114
obj->parsed = 0;
101115
tree = (struct tree *)obj;
@@ -107,15 +121,22 @@ static int mark_object(struct object *obj, int type, void *data)
107121
free(tree->buffer);
108122
tree->buffer = NULL;
109123
}
110-
if (result < 0)
111-
result = 1;
112-
113124
return result;
114125
}
115126

116-
static void mark_object_reachable(struct object *obj)
127+
static int traverse_reachable(void)
117128
{
118-
mark_object(obj, OBJ_ANY, 0);
129+
int result = 0;
130+
while (pending.nr) {
131+
struct object_array_entry *entry;
132+
struct object *obj, *parent;
133+
134+
entry = pending.objects + --pending.nr;
135+
obj = entry->item;
136+
parent = (struct object *) entry->name;
137+
result |= traverse_one_object(obj, parent);
138+
}
139+
return !!result;
119140
}
120141

121142
static int mark_used(struct object *obj, int type, void *data)
@@ -233,6 +254,9 @@ static void check_connectivity(void)
233254
{
234255
int i, max;
235256

257+
/* Traverse the pending reachable objects */
258+
traverse_reachable();
259+
236260
/* Look up all the requirements, warn about missing objects.. */
237261
max = get_max_object_index();
238262
if (verbose)

0 commit comments

Comments
 (0)