commit b8a4401b8e46c0a32b824433c648ea749898616b from: Stefan Sperling date: Thu Sep 01 10:45:47 2022 UTC refresh our pack-index path list if the mtime of objects/pack has changed ok op@ commit - 625e5896fc9ecf87ccfc92ad2a65cd3be58f73c0 commit + b8a4401b8e46c0a32b824433c648ea749898616b blob - 02b998107e294bc2eca6ffb21a128c5973771755 blob + fadbfad45e1c86893452d04c192e3bf35883bebf --- lib/got_lib_repository.h +++ lib/got_lib_repository.h @@ -52,6 +52,7 @@ struct got_repository { int gitdir_fd; struct got_pathlist_head packidx_paths; + time_t pack_path_mtime; /* The pack index cache speeds up search for packed objects. */ struct got_packidx *packidx_cache[GOT_PACK_CACHE_SIZE]; blob - 237c796775a73f7eac4b6b6b463b2caefc13b720 blob + 87c7abb573744c7b7f9b38f35d7550229267b418 --- lib/repository.c +++ lib/repository.c @@ -1282,6 +1282,7 @@ got_repo_list_packidx(struct got_pathlist_head *packid struct dirent *dent; char *path_packidx = NULL; int packdir_fd; + struct stat sb; packdir_fd = openat(got_repo_get_fd(repo), GOT_OBJECTS_PACK_DIR, O_DIRECTORY | O_CLOEXEC); @@ -1294,8 +1295,14 @@ got_repo_list_packidx(struct got_pathlist_head *packid packdir = fdopendir(packdir_fd); if (packdir == NULL) { err = got_error_from_errno("fdopendir"); + goto done; + } + + if (fstat(packdir_fd, &sb) == -1) { + err = got_error_from_errno("fstat"); goto done; } + repo->pack_path_mtime = sb.st_mtime; while ((dent = readdir(packdir)) != NULL) { if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen)) @@ -1606,6 +1613,19 @@ got_repo_init(const char *repo_path) return err; return NULL; +} + +static void +purge_packidx_paths(struct got_pathlist_head *packidx_paths) +{ + struct got_pathlist_entry *pe; + + while (!TAILQ_EMPTY(packidx_paths)) { + pe = TAILQ_FIRST(packidx_paths); + TAILQ_REMOVE(packidx_paths, pe, entry); + free((char *)pe->path); + free(pe); + } } static const struct got_error * @@ -1615,9 +1635,21 @@ match_packed_object(struct got_object_id **unique_id, const struct got_error *err = NULL; struct got_object_id_queue matched_ids; struct got_pathlist_entry *pe; + struct stat sb; STAILQ_INIT(&matched_ids); + if (stat(got_repo_get_path_objects_pack(repo), &sb) == -1) { + if (errno != ENOENT) + return got_error_from_errno2("stat", + got_repo_get_path_objects_pack(repo)); + } else if (sb.st_mtime != repo->pack_path_mtime) { + purge_packidx_paths(&repo->packidx_paths); + err = got_repo_list_packidx(&repo->packidx_paths, repo); + if (err) + return err; + } + TAILQ_FOREACH(pe, &repo->packidx_paths, entry) { const char *path_packidx = pe->path; struct got_packidx *packidx;