Git fork
at reftables-rust 822 lines 26 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2#define DISABLE_SIGN_COMPARE_WARNINGS 3 4#include "git-compat-util.h" 5#include "config.h" 6#include "dir.h" 7#include "environment.h" 8#include "ewah/ewok.h" 9#include "fsmonitor.h" 10#include "fsmonitor-ipc.h" 11#include "name-hash.h" 12#include "repository.h" 13#include "run-command.h" 14#include "strbuf.h" 15#include "trace2.h" 16 17#define INDEX_EXTENSION_VERSION1 (1) 18#define INDEX_EXTENSION_VERSION2 (2) 19#define HOOK_INTERFACE_VERSION1 (1) 20#define HOOK_INTERFACE_VERSION2 (2) 21 22struct trace_key trace_fsmonitor = TRACE_KEY_INIT(FSMONITOR); 23 24static void assert_index_minimum(struct index_state *istate, size_t pos) 25{ 26 if (pos > istate->cache_nr) 27 BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", 28 (uintmax_t)pos, istate->cache_nr); 29} 30 31static void fsmonitor_ewah_callback(size_t pos, void *is) 32{ 33 struct index_state *istate = (struct index_state *)is; 34 struct cache_entry *ce; 35 36 assert_index_minimum(istate, pos + 1); 37 38 ce = istate->cache[pos]; 39 ce->ce_flags &= ~CE_FSMONITOR_VALID; 40} 41 42static int fsmonitor_hook_version(void) 43{ 44 int hook_version; 45 46 if (repo_config_get_int(the_repository, "core.fsmonitorhookversion", &hook_version)) 47 return -1; 48 49 if (hook_version == HOOK_INTERFACE_VERSION1 || 50 hook_version == HOOK_INTERFACE_VERSION2) 51 return hook_version; 52 53 warning("Invalid hook version '%i' in core.fsmonitorhookversion. " 54 "Must be 1 or 2.", hook_version); 55 return -1; 56} 57 58int read_fsmonitor_extension(struct index_state *istate, const void *data, 59 unsigned long sz) 60{ 61 const char *index = data; 62 uint32_t hdr_version; 63 uint32_t ewah_size; 64 struct ewah_bitmap *fsmonitor_dirty; 65 int ret; 66 uint64_t timestamp; 67 struct strbuf last_update = STRBUF_INIT; 68 69 if (sz < sizeof(uint32_t) + 1 + sizeof(uint32_t)) 70 return error("corrupt fsmonitor extension (too short)"); 71 72 hdr_version = get_be32(index); 73 index += sizeof(uint32_t); 74 if (hdr_version == INDEX_EXTENSION_VERSION1) { 75 timestamp = get_be64(index); 76 strbuf_addf(&last_update, "%"PRIu64"", timestamp); 77 index += sizeof(uint64_t); 78 } else if (hdr_version == INDEX_EXTENSION_VERSION2) { 79 strbuf_addstr(&last_update, index); 80 index += last_update.len + 1; 81 } else { 82 return error("bad fsmonitor version %d", hdr_version); 83 } 84 85 istate->fsmonitor_last_update = strbuf_detach(&last_update, NULL); 86 87 ewah_size = get_be32(index); 88 index += sizeof(uint32_t); 89 90 fsmonitor_dirty = ewah_new(); 91 ret = ewah_read_mmap(fsmonitor_dirty, index, ewah_size); 92 if (ret != ewah_size) { 93 ewah_free(fsmonitor_dirty); 94 return error("failed to parse ewah bitmap reading fsmonitor index extension"); 95 } 96 istate->fsmonitor_dirty = fsmonitor_dirty; 97 98 if (!istate->split_index) 99 assert_index_minimum(istate, istate->fsmonitor_dirty->bit_size); 100 101 trace2_data_string("index", NULL, "extension/fsmn/read/token", 102 istate->fsmonitor_last_update); 103 trace_printf_key(&trace_fsmonitor, 104 "read fsmonitor extension successful '%s'", 105 istate->fsmonitor_last_update); 106 return 0; 107} 108 109void fill_fsmonitor_bitmap(struct index_state *istate) 110{ 111 unsigned int i, skipped = 0; 112 istate->fsmonitor_dirty = ewah_new(); 113 for (i = 0; i < istate->cache_nr; i++) { 114 if (istate->cache[i]->ce_flags & CE_REMOVE) 115 skipped++; 116 else if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) 117 ewah_set(istate->fsmonitor_dirty, i - skipped); 118 } 119} 120 121void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate) 122{ 123 uint32_t hdr_version; 124 uint32_t ewah_start; 125 uint32_t ewah_size = 0; 126 int fixup = 0; 127 128 if (!istate->split_index) 129 assert_index_minimum(istate, istate->fsmonitor_dirty->bit_size); 130 131 put_be32(&hdr_version, INDEX_EXTENSION_VERSION2); 132 strbuf_add(sb, &hdr_version, sizeof(uint32_t)); 133 134 strbuf_addstr(sb, istate->fsmonitor_last_update); 135 strbuf_addch(sb, 0); /* Want to keep a NUL */ 136 137 fixup = sb->len; 138 strbuf_add(sb, &ewah_size, sizeof(uint32_t)); /* we'll fix this up later */ 139 140 ewah_start = sb->len; 141 ewah_serialize_strbuf(istate->fsmonitor_dirty, sb); 142 ewah_free(istate->fsmonitor_dirty); 143 istate->fsmonitor_dirty = NULL; 144 145 /* fix up size field */ 146 put_be32(&ewah_size, sb->len - ewah_start); 147 memcpy(sb->buf + fixup, &ewah_size, sizeof(uint32_t)); 148 149 trace2_data_string("index", NULL, "extension/fsmn/write/token", 150 istate->fsmonitor_last_update); 151 trace_printf_key(&trace_fsmonitor, 152 "write fsmonitor extension successful '%s'", 153 istate->fsmonitor_last_update); 154} 155 156/* 157 * Call the query-fsmonitor hook passing the last update token of the saved results. 158 */ 159static int query_fsmonitor_hook(struct repository *r, 160 int version, 161 const char *last_update, 162 struct strbuf *query_result) 163{ 164 struct child_process cp = CHILD_PROCESS_INIT; 165 int result; 166 167 if (fsm_settings__get_mode(r) != FSMONITOR_MODE_HOOK) 168 return -1; 169 170 strvec_push(&cp.args, fsm_settings__get_hook_path(r)); 171 strvec_pushf(&cp.args, "%d", version); 172 strvec_pushf(&cp.args, "%s", last_update); 173 cp.use_shell = 1; 174 cp.dir = repo_get_work_tree(the_repository); 175 176 trace2_region_enter("fsm_hook", "query", NULL); 177 178 result = capture_command(&cp, query_result, 1024); 179 180 if (result) 181 trace2_data_intmax("fsm_hook", NULL, "query/failed", result); 182 else 183 trace2_data_intmax("fsm_hook", NULL, "query/response-length", 184 query_result->len); 185 186 trace2_region_leave("fsm_hook", "query", NULL); 187 188 return result; 189} 190 191/* 192 * Invalidate the FSM bit on this CE. This is like mark_fsmonitor_invalid() 193 * but we've already handled the untracked-cache, so let's not repeat that 194 * work. This also lets us have a different trace message so that we can 195 * see everything that was done as part of the refresh-callback. 196 */ 197static void invalidate_ce_fsm(struct cache_entry *ce) 198{ 199 if (ce->ce_flags & CE_FSMONITOR_VALID) { 200 trace_printf_key(&trace_fsmonitor, 201 "fsmonitor_refresh_callback INV: '%s'", 202 ce->name); 203 ce->ce_flags &= ~CE_FSMONITOR_VALID; 204 } 205} 206 207static size_t handle_path_with_trailing_slash( 208 struct index_state *istate, const char *name, int pos); 209 210/* 211 * Use the name-hash to do a case-insensitive cache-entry lookup with 212 * the pathname and invalidate the cache-entry. 213 * 214 * Returns the number of cache-entries that we invalidated. 215 */ 216static size_t handle_using_name_hash_icase( 217 struct index_state *istate, const char *name) 218{ 219 struct cache_entry *ce = NULL; 220 221 ce = index_file_exists(istate, name, strlen(name), 1); 222 if (!ce) 223 return 0; 224 225 /* 226 * A case-insensitive search in the name-hash using the 227 * observed pathname found a cache-entry, so the observed path 228 * is case-incorrect. Invalidate the cache-entry and use the 229 * correct spelling from the cache-entry to invalidate the 230 * untracked-cache. Since we now have sparse-directories in 231 * the index, the observed pathname may represent a regular 232 * file or a sparse-index directory. 233 * 234 * Note that we should not have seen FSEvents for a 235 * sparse-index directory, but we handle it just in case. 236 * 237 * Either way, we know that there are not any cache-entries for 238 * children inside the cone of the directory, so we don't need to 239 * do the usual scan. 240 */ 241 trace_printf_key(&trace_fsmonitor, 242 "fsmonitor_refresh_callback MAP: '%s' '%s'", 243 name, ce->name); 244 245 /* 246 * NEEDSWORK: We used the name-hash to find the correct 247 * case-spelling of the pathname in the cache-entry[], so 248 * technically this is a tracked file or a sparse-directory. 249 * It should not have any entries in the untracked-cache, so 250 * we should not need to use the case-corrected spelling to 251 * invalidate the untracked-cache. So we may not need to 252 * do this. For now, I'm going to be conservative and always 253 * do it; we can revisit this later. 254 */ 255 untracked_cache_invalidate_trimmed_path(istate, ce->name, 0); 256 257 invalidate_ce_fsm(ce); 258 return 1; 259} 260 261/* 262 * Use the dir-name-hash to find the correct-case spelling of the 263 * directory. Use the canonical spelling to invalidate all of the 264 * cache-entries within the matching cone. 265 * 266 * Returns the number of cache-entries that we invalidated. 267 */ 268static size_t handle_using_dir_name_hash_icase( 269 struct index_state *istate, const char *name) 270{ 271 struct strbuf canonical_path = STRBUF_INIT; 272 int pos; 273 size_t len = strlen(name); 274 size_t nr_in_cone; 275 276 if (name[len - 1] == '/') 277 len--; 278 279 if (!index_dir_find(istate, name, len, &canonical_path)) 280 return 0; /* name is untracked */ 281 282 if (!memcmp(name, canonical_path.buf, canonical_path.len)) { 283 strbuf_release(&canonical_path); 284 /* 285 * NEEDSWORK: Our caller already tried an exact match 286 * and failed to find one. They called us to do an 287 * ICASE match, so we should never get an exact match, 288 * so we could promote this to a BUG() here if we 289 * wanted to. It doesn't hurt anything to just return 290 * 0 and go on because we should never get here. Or we 291 * could just get rid of the memcmp() and this "if" 292 * clause completely. 293 */ 294 BUG("handle_using_dir_name_hash_icase(%s) did not exact match", 295 name); 296 } 297 298 trace_printf_key(&trace_fsmonitor, 299 "fsmonitor_refresh_callback MAP: '%s' '%s'", 300 name, canonical_path.buf); 301 302 /* 303 * The dir-name-hash only tells us the corrected spelling of 304 * the prefix. We have to use this canonical path to do a 305 * lookup in the cache-entry array so that we repeat the 306 * original search using the case-corrected spelling. 307 */ 308 strbuf_addch(&canonical_path, '/'); 309 pos = index_name_pos(istate, canonical_path.buf, 310 canonical_path.len); 311 nr_in_cone = handle_path_with_trailing_slash( 312 istate, canonical_path.buf, pos); 313 strbuf_release(&canonical_path); 314 return nr_in_cone; 315} 316 317/* 318 * The daemon sent an observed pathname without a trailing slash. 319 * (This is the normal case.) We do not know if it is a tracked or 320 * untracked file, a sparse-directory, or a populated directory (on a 321 * platform such as Windows where FSEvents are not qualified). 322 * 323 * The pathname contains the observed case reported by the FS. We 324 * do not know it is case-correct or -incorrect. 325 * 326 * Assume it is case-correct and try an exact match. 327 * 328 * Return the number of cache-entries that we invalidated. 329 */ 330static size_t handle_path_without_trailing_slash( 331 struct index_state *istate, const char *name, int pos) 332{ 333 /* 334 * Mark the untracked cache dirty for this path (regardless of 335 * whether or not we find an exact match for it in the index). 336 * Since the path is unqualified (no trailing slash hint in the 337 * FSEvent), it may refer to a file or directory. So we should 338 * not assume one or the other and should always let the untracked 339 * cache decide what needs to invalidated. 340 */ 341 untracked_cache_invalidate_trimmed_path(istate, name, 0); 342 343 if (pos >= 0) { 344 /* 345 * An exact match on a tracked file. We assume that we 346 * do not need to scan forward for a sparse-directory 347 * cache-entry with the same pathname, nor for a cone 348 * at that directory. (That is, assume no D/F conflicts.) 349 */ 350 invalidate_ce_fsm(istate->cache[pos]); 351 return 1; 352 } else { 353 size_t nr_in_cone; 354 struct strbuf work_path = STRBUF_INIT; 355 356 /* 357 * The negative "pos" gives us the suggested insertion 358 * point for the pathname (without the trailing slash). 359 * We need to see if there is a directory with that 360 * prefix, but there can be lots of pathnames between 361 * "foo" and "foo/" like "foo-" or "foo-bar", so we 362 * don't want to do our own scan. 363 */ 364 strbuf_add(&work_path, name, strlen(name)); 365 strbuf_addch(&work_path, '/'); 366 pos = index_name_pos(istate, work_path.buf, work_path.len); 367 nr_in_cone = handle_path_with_trailing_slash( 368 istate, work_path.buf, pos); 369 strbuf_release(&work_path); 370 return nr_in_cone; 371 } 372} 373 374/* 375 * The daemon can decorate directory events, such as a move or rename, 376 * by adding a trailing slash to the observed name. Use this to 377 * explicitly invalidate the entire cone under that directory. 378 * 379 * The daemon can only reliably do that if the OS FSEvent contains 380 * sufficient information in the event. 381 * 382 * macOS FSEvents have enough information. 383 * 384 * Other platforms may or may not be able to do it (and it might 385 * depend on the type of event (for example, a daemon could lstat() an 386 * observed pathname after a rename, but not after a delete)). 387 * 388 * If we find an exact match in the index for a path with a trailing 389 * slash, it means that we matched a sparse-index directory in a 390 * cone-mode sparse-checkout (since that's the only time we have 391 * directories in the index). We should never see this in practice 392 * (because sparse directories should not be present and therefore 393 * not generating FS events). Either way, we can treat them in the 394 * same way and just invalidate the cache-entry and the untracked 395 * cache (and in this case, the forward cache-entry scan won't find 396 * anything and it doesn't hurt to let it run). 397 * 398 * Return the number of cache-entries that we invalidated. We will 399 * use this later to determine if we need to attempt a second 400 * case-insensitive search on case-insensitive file systems. That is, 401 * if the search using the observed-case in the FSEvent yields any 402 * results, we assume the prefix is case-correct. If there are no 403 * matches, we still don't know if the observed path is simply 404 * untracked or case-incorrect. 405 */ 406static size_t handle_path_with_trailing_slash( 407 struct index_state *istate, const char *name, int pos) 408{ 409 int i; 410 size_t nr_in_cone = 0; 411 412 /* 413 * Mark the untracked cache dirty for this directory path 414 * (regardless of whether or not we find an exact match for it 415 * in the index or find it to be proper prefix of one or more 416 * files in the index), since the FSEvent is hinting that 417 * there may be changes on or within the directory. 418 */ 419 untracked_cache_invalidate_trimmed_path(istate, name, 0); 420 421 if (pos < 0) 422 pos = -pos - 1; 423 424 /* Mark all entries for the folder invalid */ 425 for (i = pos; i < istate->cache_nr; i++) { 426 if (!starts_with(istate->cache[i]->name, name)) 427 break; 428 invalidate_ce_fsm(istate->cache[i]); 429 nr_in_cone++; 430 } 431 432 return nr_in_cone; 433} 434 435static void fsmonitor_refresh_callback(struct index_state *istate, char *name) 436{ 437 int len = strlen(name); 438 int pos = index_name_pos(istate, name, len); 439 size_t nr_in_cone; 440 441 trace_printf_key(&trace_fsmonitor, 442 "fsmonitor_refresh_callback '%s' (pos %d)", 443 name, pos); 444 445 if (name[len - 1] == '/') 446 nr_in_cone = handle_path_with_trailing_slash(istate, name, pos); 447 else 448 nr_in_cone = handle_path_without_trailing_slash(istate, name, pos); 449 450 /* 451 * If we did not find an exact match for this pathname or any 452 * cache-entries with this directory prefix and we're on a 453 * case-insensitive file system, try again using the name-hash 454 * and dir-name-hash. 455 */ 456 if (!nr_in_cone && ignore_case) { 457 nr_in_cone = handle_using_name_hash_icase(istate, name); 458 if (!nr_in_cone) 459 nr_in_cone = handle_using_dir_name_hash_icase( 460 istate, name); 461 } 462 463 if (nr_in_cone) 464 trace_printf_key(&trace_fsmonitor, 465 "fsmonitor_refresh_callback CNT: %d", 466 (int)nr_in_cone); 467} 468 469/* 470 * The number of pathnames that we need to receive from FSMonitor 471 * before we force the index to be updated. 472 * 473 * Note that any pathname within the set of received paths MAY cause 474 * cache-entry or istate flag bits to be updated and thus cause the 475 * index to be updated on disk. 476 * 477 * However, the response may contain many paths (such as ignored 478 * paths) that will not update any flag bits. And thus not force the 479 * index to be updated. (This is fine and normal.) It also means 480 * that the token will not be updated in the FSMonitor index 481 * extension. So the next Git command will find the same token in the 482 * index, make the same token-relative request, and receive the same 483 * response (plus any newly changed paths). If this response is large 484 * (and continues to grow), performance could be impacted. 485 * 486 * For example, if the user runs a build and it writes 100K object 487 * files but doesn't modify any source files, the index would not need 488 * to be updated. The FSMonitor response (after the build and 489 * relative to a pre-build token) might be 5MB. Each subsequent Git 490 * command will receive that same 100K/5MB response until something 491 * causes the index to be updated. And `refresh_fsmonitor()` will 492 * have to iterate over those 100K paths each time. 493 * 494 * Performance could be improved if we optionally force update the 495 * index after a very large response and get an updated token into 496 * the FSMonitor index extension. This should allow subsequent 497 * commands to get smaller and more current responses. 498 * 499 * The value chosen here does not need to be precise. The index 500 * will be updated automatically the first time the user touches 501 * a tracked file and causes a command like `git status` to 502 * update an mtime to be updated and/or set a flag bit. 503 */ 504static int fsmonitor_force_update_threshold = 100; 505 506void refresh_fsmonitor(struct index_state *istate) 507{ 508 static int warn_once = 0; 509 struct strbuf query_result = STRBUF_INIT; 510 int query_success = 0, hook_version = -1; 511 size_t bol = 0; /* beginning of line */ 512 uint64_t last_update; 513 struct strbuf last_update_token = STRBUF_INIT; 514 char *buf; 515 unsigned int i; 516 int is_trivial = 0; 517 struct repository *r = istate->repo; 518 enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r); 519 enum fsmonitor_reason reason = fsm_settings__get_reason(r); 520 521 if (!warn_once && reason > FSMONITOR_REASON_OK) { 522 char *msg = fsm_settings__get_incompatible_msg(r, reason); 523 warn_once = 1; 524 warning("%s", msg); 525 free(msg); 526 } 527 528 if (fsm_mode <= FSMONITOR_MODE_DISABLED || 529 istate->fsmonitor_has_run_once) 530 return; 531 532 istate->fsmonitor_has_run_once = 1; 533 534 trace_printf_key(&trace_fsmonitor, "refresh fsmonitor"); 535 536 if (fsm_mode == FSMONITOR_MODE_IPC) { 537 query_success = !fsmonitor_ipc__send_query( 538 istate->fsmonitor_last_update ? 539 istate->fsmonitor_last_update : "builtin:fake", 540 &query_result); 541 if (query_success) { 542 /* 543 * The response contains a series of nul terminated 544 * strings. The first is the new token. 545 * 546 * Use `char *buf` as an interlude to trick the CI 547 * static analysis to let us use `strbuf_addstr()` 548 * here (and only copy the token) rather than 549 * `strbuf_addbuf()`. 550 */ 551 buf = query_result.buf; 552 strbuf_addstr(&last_update_token, buf); 553 bol = last_update_token.len + 1; 554 is_trivial = query_result.buf[bol] == '/'; 555 if (is_trivial) 556 trace2_data_intmax("fsm_client", NULL, 557 "query/trivial-response", 1); 558 } else { 559 /* 560 * The builtin daemon is not available on this 561 * platform -OR- we failed to get a response. 562 * 563 * Generate a fake token (rather than a V1 564 * timestamp) for the index extension. (If 565 * they switch back to the hook API, we don't 566 * want ambiguous state.) 567 */ 568 strbuf_addstr(&last_update_token, "builtin:fake"); 569 } 570 571 goto apply_results; 572 } 573 574 assert(fsm_mode == FSMONITOR_MODE_HOOK); 575 576 hook_version = fsmonitor_hook_version(); 577 578 /* 579 * This could be racy so save the date/time now and query_fsmonitor_hook 580 * should be inclusive to ensure we don't miss potential changes. 581 */ 582 last_update = getnanotime(); 583 if (hook_version == HOOK_INTERFACE_VERSION1) 584 strbuf_addf(&last_update_token, "%"PRIu64"", last_update); 585 586 /* 587 * If we have a last update token, call query_fsmonitor_hook for the set of 588 * changes since that token, else assume everything is possibly dirty 589 * and check it all. 590 */ 591 if (istate->fsmonitor_last_update) { 592 if (hook_version == -1 || hook_version == HOOK_INTERFACE_VERSION2) { 593 query_success = !query_fsmonitor_hook( 594 r, HOOK_INTERFACE_VERSION2, 595 istate->fsmonitor_last_update, &query_result); 596 597 if (query_success) { 598 if (hook_version < 0) 599 hook_version = HOOK_INTERFACE_VERSION2; 600 601 /* 602 * First entry will be the last update token 603 * Need to use a char * variable because static 604 * analysis was suggesting to use strbuf_addbuf 605 * but we don't want to copy the entire strbuf 606 * only the chars up to the first NUL 607 */ 608 buf = query_result.buf; 609 strbuf_addstr(&last_update_token, buf); 610 if (!last_update_token.len) { 611 warning("Empty last update token."); 612 query_success = 0; 613 } else { 614 bol = last_update_token.len + 1; 615 is_trivial = query_result.buf[bol] == '/'; 616 } 617 } else if (hook_version < 0) { 618 hook_version = HOOK_INTERFACE_VERSION1; 619 if (!last_update_token.len) 620 strbuf_addf(&last_update_token, "%"PRIu64"", last_update); 621 } 622 } 623 624 if (hook_version == HOOK_INTERFACE_VERSION1) { 625 query_success = !query_fsmonitor_hook( 626 r, HOOK_INTERFACE_VERSION1, 627 istate->fsmonitor_last_update, &query_result); 628 if (query_success) 629 is_trivial = query_result.buf[0] == '/'; 630 } 631 632 if (is_trivial) 633 trace2_data_intmax("fsm_hook", NULL, 634 "query/trivial-response", 1); 635 636 trace_performance_since(last_update, "fsmonitor process '%s'", 637 fsm_settings__get_hook_path(r)); 638 trace_printf_key(&trace_fsmonitor, 639 "fsmonitor process '%s' returned %s", 640 fsm_settings__get_hook_path(r), 641 query_success ? "success" : "failure"); 642 } 643 644apply_results: 645 /* 646 * The response from FSMonitor (excluding the header token) is 647 * either: 648 * 649 * [a] a (possibly empty) list of NUL delimited relative 650 * pathnames of changed paths. This list can contain 651 * files and directories. Directories have a trailing 652 * slash. 653 * 654 * [b] a single '/' to indicate the provider had no 655 * information and that we should consider everything 656 * invalid. We call this a trivial response. 657 */ 658 trace2_region_enter("fsmonitor", "apply_results", istate->repo); 659 660 if (query_success && !is_trivial) { 661 /* 662 * Mark all pathnames returned by the monitor as dirty. 663 * 664 * This updates both the cache-entries and the untracked-cache. 665 */ 666 int count = 0; 667 668 buf = query_result.buf; 669 for (i = bol; i < query_result.len; i++) { 670 if (buf[i] != '\0') 671 continue; 672 fsmonitor_refresh_callback(istate, buf + bol); 673 bol = i + 1; 674 count++; 675 } 676 if (bol < query_result.len) { 677 fsmonitor_refresh_callback(istate, buf + bol); 678 count++; 679 } 680 681 /* Now mark the untracked cache for fsmonitor usage */ 682 if (istate->untracked) 683 istate->untracked->use_fsmonitor = 1; 684 685 if (count > fsmonitor_force_update_threshold) 686 istate->cache_changed |= FSMONITOR_CHANGED; 687 688 trace2_data_intmax("fsmonitor", istate->repo, "apply_count", 689 count); 690 691 } else { 692 /* 693 * We failed to get a response or received a trivial response, 694 * so invalidate everything. 695 * 696 * We only want to run the post index changed hook if 697 * we've actually changed entries, so keep track if we 698 * actually changed entries or not. 699 */ 700 int is_cache_changed = 0; 701 702 for (i = 0; i < istate->cache_nr; i++) { 703 if (istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) { 704 is_cache_changed = 1; 705 istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID; 706 } 707 } 708 709 /* 710 * If we're going to check every file, ensure we save 711 * the results. 712 */ 713 if (is_cache_changed) 714 istate->cache_changed |= FSMONITOR_CHANGED; 715 716 if (istate->untracked) 717 istate->untracked->use_fsmonitor = 0; 718 } 719 trace2_region_leave("fsmonitor", "apply_results", istate->repo); 720 721 strbuf_release(&query_result); 722 723 /* Now that we've updated istate, save the last_update_token */ 724 FREE_AND_NULL(istate->fsmonitor_last_update); 725 istate->fsmonitor_last_update = strbuf_detach(&last_update_token, NULL); 726} 727 728/* 729 * The caller wants to turn on FSMonitor. And when the caller writes 730 * the index to disk, a FSMonitor extension should be included. This 731 * requires that `istate->fsmonitor_last_update` not be NULL. But we 732 * have not actually talked to a FSMonitor process yet, so we don't 733 * have an initial value for this field. 734 * 735 * For a protocol V1 FSMonitor process, this field is a formatted 736 * "nanoseconds since epoch" field. However, for a protocol V2 737 * FSMonitor process, this field is an opaque token. 738 * 739 * Historically, `add_fsmonitor()` has initialized this field to the 740 * current time for protocol V1 processes. There are lots of race 741 * conditions here, but that code has shipped... 742 * 743 * The only true solution is to use a V2 FSMonitor and get a current 744 * or default token value (that it understands), but we cannot do that 745 * until we have actually talked to an instance of the FSMonitor process 746 * (but the protocol requires that we send a token first...). 747 * 748 * For simplicity, just initialize like we have a V1 process and require 749 * that V2 processes adapt. 750 */ 751static void initialize_fsmonitor_last_update(struct index_state *istate) 752{ 753 struct strbuf last_update = STRBUF_INIT; 754 755 strbuf_addf(&last_update, "%"PRIu64"", getnanotime()); 756 istate->fsmonitor_last_update = strbuf_detach(&last_update, NULL); 757} 758 759void add_fsmonitor(struct index_state *istate) 760{ 761 unsigned int i; 762 763 if (!istate->fsmonitor_last_update) { 764 trace_printf_key(&trace_fsmonitor, "add fsmonitor"); 765 istate->cache_changed |= FSMONITOR_CHANGED; 766 initialize_fsmonitor_last_update(istate); 767 768 /* reset the fsmonitor state */ 769 for (i = 0; i < istate->cache_nr; i++) 770 istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID; 771 772 /* reset the untracked cache */ 773 if (istate->untracked) { 774 add_untracked_cache(istate); 775 istate->untracked->use_fsmonitor = 1; 776 } 777 778 /* Update the fsmonitor state */ 779 refresh_fsmonitor(istate); 780 } 781} 782 783void remove_fsmonitor(struct index_state *istate) 784{ 785 if (istate->fsmonitor_last_update) { 786 trace_printf_key(&trace_fsmonitor, "remove fsmonitor"); 787 istate->cache_changed |= FSMONITOR_CHANGED; 788 FREE_AND_NULL(istate->fsmonitor_last_update); 789 } 790} 791 792void tweak_fsmonitor(struct index_state *istate) 793{ 794 unsigned int i; 795 int fsmonitor_enabled = (fsm_settings__get_mode(istate->repo) 796 > FSMONITOR_MODE_DISABLED); 797 798 if (istate->fsmonitor_dirty) { 799 if (fsmonitor_enabled) { 800 /* Mark all entries valid */ 801 for (i = 0; i < istate->cache_nr; i++) { 802 if (S_ISGITLINK(istate->cache[i]->ce_mode)) 803 continue; 804 istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID; 805 } 806 807 /* Mark all previously saved entries as dirty */ 808 assert_index_minimum(istate, istate->fsmonitor_dirty->bit_size); 809 ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate); 810 811 refresh_fsmonitor(istate); 812 } 813 814 ewah_free(istate->fsmonitor_dirty); 815 istate->fsmonitor_dirty = NULL; 816 } 817 818 if (fsmonitor_enabled) 819 add_fsmonitor(istate); 820 else 821 remove_fsmonitor(istate); 822}