commit 1b3e8e8674ebd24834b549a70d90487307d0f3bf from: Stefan Sperling date: Tue Nov 08 20:03:48 2022 UTC use sub-second precision when checking for objects/pack/ modification Convert from st.m_time (second-precision time_t) to st.m_tim (struct timespec). To compensate for the potential case where a filesystem provides resolution in seconds only, always read the directory if no pack files are known to exist. Otherwise, there is a race condition when gotd repo_write creates a new pack and a request arrives for repo_read shortly after. Caught by a regression test for gotd on empty repositories. Test failure pointed out by Mikhail. ok op@ commit - c9f1ac46710e3ac672c769862ae51b838c3c8e46 commit + 1b3e8e8674ebd24834b549a70d90487307d0f3bf blob - cd9aa4370a65e5d58169777bb0760f75b984b0b1 blob + e78dd4fb4cada73349067798a377d8d17194da2e --- gotd/privsep_stub.c +++ gotd/privsep_stub.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include blob - ced490e96ad476ac78d59ed49d235863982116c3 blob + b8032ffd3ffe9dab29beaf3cc57c39a6ef957859 --- lib/got_lib_repository.h +++ lib/got_lib_repository.h @@ -65,7 +65,7 @@ struct got_repository { int gitdir_fd; struct got_pathlist_head packidx_paths; - time_t pack_path_mtime; + struct timespec pack_path_mtime; /* The pack index cache speeds up search for packed objects. */ struct got_packidx *packidx_cache[GOT_PACK_CACHE_SIZE]; blob - 0f29cc09331dd7d207bd1ec47e0b2310708660ee blob + e76312afb71dc950015ded8344d412b185adb00c --- lib/read_gitconfig_privsep.c +++ lib/read_gitconfig_privsep.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include blob - 0cab79b8b8f5f06becd7bc5a485ab1f33f7e022e blob + 5ede5726ac196d5b3ba820a830a44852e453b174 --- lib/repository.c +++ lib/repository.c @@ -1150,7 +1150,9 @@ refresh_packidx_paths(struct got_repository *repo) err = got_error_from_errno2("stat", objects_pack_dir); goto done; } - } else if (sb.st_mtime != repo->pack_path_mtime) { + } else if (TAILQ_EMPTY(&repo->packidx_paths) || + sb.st_mtim.tv_sec != repo->pack_path_mtime.tv_sec || + sb.st_mtim.tv_nsec != repo->pack_path_mtime.tv_nsec) { purge_packidx_paths(&repo->packidx_paths); err = got_repo_list_packidx(&repo->packidx_paths, repo); if (err) @@ -1277,7 +1279,8 @@ got_repo_list_packidx(struct got_pathlist_head *packid err = got_error_from_errno("fstat"); goto done; } - repo->pack_path_mtime = sb.st_mtime; + repo->pack_path_mtime.tv_sec = sb.st_mtim.tv_sec; + repo->pack_path_mtime.tv_nsec = sb.st_mtim.tv_nsec; while ((dent = readdir(packdir)) != NULL) { if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen))