Skip to content

Commit 0ec9949

Browse files
nipunn1313gitster
authored andcommitted
fsmonitor: add assertion that fsmonitor is valid to check_removed
Validate that fsmonitor is valid to futureproof against bugs where check_removed might be called from places that haven't refreshed. Signed-off-by: Nipunn Koorapati <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f3d6d0 commit 0ec9949

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

diff-lib.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@
2828
* exists for ce that is a submodule -- it is a submodule that is not
2929
* checked out). Return negative for an error.
3030
*/
31-
static int check_removed(const struct cache_entry *ce, struct stat *st)
31+
static int check_removed(const struct index_state *istate, const struct cache_entry *ce, struct stat *st)
3232
{
33+
assert(is_fsmonitor_refreshed(istate));
3334
if (!(ce->ce_flags & CE_FSMONITOR_VALID) && lstat(ce->name, st) < 0) {
3435
if (!is_missing_file_error(errno))
3536
return -1;
@@ -136,7 +137,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
136137
memset(&(dpath->parent[0]), 0,
137138
sizeof(struct combine_diff_parent)*5);
138139

139-
changed = check_removed(ce, &st);
140+
changed = check_removed(istate, ce, &st);
140141
if (!changed)
141142
wt_mode = ce_mode_from_stat(ce, st.st_mode);
142143
else {
@@ -216,7 +217,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
216217
} else {
217218
struct stat st;
218219

219-
changed = check_removed(ce, &st);
220+
changed = check_removed(istate, ce, &st);
220221
if (changed) {
221222
if (changed < 0) {
222223
perror(ce->name);
@@ -278,7 +279,8 @@ static void diff_index_show_file(struct rev_info *revs,
278279
oid, oid_valid, ce->name, dirty_submodule);
279280
}
280281

281-
static int get_stat_data(const struct cache_entry *ce,
282+
static int get_stat_data(const struct index_state *istate,
283+
const struct cache_entry *ce,
282284
const struct object_id **oidp,
283285
unsigned int *modep,
284286
int cached, int match_missing,
@@ -290,7 +292,7 @@ static int get_stat_data(const struct cache_entry *ce,
290292
if (!cached && !ce_uptodate(ce)) {
291293
int changed;
292294
struct stat st;
293-
changed = check_removed(ce, &st);
295+
changed = check_removed(istate, ce, &st);
294296
if (changed < 0)
295297
return -1;
296298
else if (changed) {
@@ -321,12 +323,13 @@ static void show_new_file(struct rev_info *revs,
321323
const struct object_id *oid;
322324
unsigned int mode;
323325
unsigned dirty_submodule = 0;
326+
struct index_state *istate = revs->diffopt.repo->index;
324327

325328
/*
326329
* New file in the index: it might actually be different in
327330
* the working tree.
328331
*/
329-
if (get_stat_data(new_file, &oid, &mode, cached, match_missing,
332+
if (get_stat_data(istate, new_file, &oid, &mode, cached, match_missing,
330333
&dirty_submodule, &revs->diffopt) < 0)
331334
return;
332335

@@ -342,8 +345,9 @@ static int show_modified(struct rev_info *revs,
342345
unsigned int mode, oldmode;
343346
const struct object_id *oid;
344347
unsigned dirty_submodule = 0;
348+
struct index_state *istate = revs->diffopt.repo->index;
345349

346-
if (get_stat_data(new_entry, &oid, &mode, cached, match_missing,
350+
if (get_stat_data(istate, new_entry, &oid, &mode, cached, match_missing,
347351
&dirty_submodule, &revs->diffopt) < 0) {
348352
if (report_missing)
349353
diff_index_show_file(revs, "-", old_entry,

fsmonitor.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ void refresh_fsmonitor(struct index_state *istate);
4949
*/
5050
int fsmonitor_is_trivial_response(const struct strbuf *query_result);
5151

52+
/*
53+
* Check if refresh_fsmonitor has been called at least once.
54+
* refresh_fsmonitor is idempotent. Returns true if fsmonitor is
55+
* not enabled (since the state will be "fresh" w/ CE_FSMONITOR_VALID unset)
56+
* This version is useful for assertions
57+
*/
58+
static inline int is_fsmonitor_refreshed(const struct index_state *istate)
59+
{
60+
return !core_fsmonitor || istate->fsmonitor_has_run_once;
61+
}
62+
5263
/*
5364
* Set the given cache entries CE_FSMONITOR_VALID bit. This should be
5465
* called any time the cache entry has been updated to reflect the

0 commit comments

Comments
 (0)