commit 5345b4c7e102ec42f81e1b9b229294a0774d9b40 from: Stefan Sperling date: Tue Jul 06 07:39:36 2021 UTC allow lockfiles to be used in cases where we have a dir_fd and a relative path commit - c294a758150a69ed50df4df8fb5986257cce07fd commit + 5345b4c7e102ec42f81e1b9b229294a0774d9b40 blob - 379232fed66680154f7f43abb7948287cd9bd809 blob + 977f28bca21557ad62008b7a21e4d731ecc5cbd9 --- lib/got_lib_lockfile.h +++ lib/got_lib_lockfile.h @@ -27,5 +27,6 @@ struct got_lockfile { int fd; }; -const struct got_error *got_lockfile_lock(struct got_lockfile **, const char *); -const struct got_error *got_lockfile_unlock(struct got_lockfile *); +const struct got_error *got_lockfile_lock(struct got_lockfile **, + const char *, int); +const struct got_error *got_lockfile_unlock(struct got_lockfile *, int); blob - 71a5d735012116d324357ccca04f1c7be867e6c2 blob + 846038c091fec21e8c028ab14a6fcdb0ea52c913 --- lib/lockfile.c +++ lib/lockfile.c @@ -31,7 +31,7 @@ #include "got_lib_lockfile.h" const struct got_error * -got_lockfile_lock(struct got_lockfile **lf, const char *path) +got_lockfile_lock(struct got_lockfile **lf, const char *path, int dir_fd) { const struct got_error *err = NULL; int attempts = 5; @@ -53,9 +53,15 @@ got_lockfile_lock(struct got_lockfile **lf, const char } do { - (*lf)->fd = open((*lf)->path, - O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK, - GOT_DEFAULT_FILE_MODE); + if (dir_fd != -1) { + (*lf)->fd = openat(dir_fd, (*lf)->path, + O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK, + GOT_DEFAULT_FILE_MODE); + } else { + (*lf)->fd = open((*lf)->path, + O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK, + GOT_DEFAULT_FILE_MODE); + } if ((*lf)->fd != -1) break; if (errno != EEXIST) { @@ -69,18 +75,22 @@ got_lockfile_lock(struct got_lockfile **lf, const char err = got_error(GOT_ERR_LOCKFILE_TIMEOUT); done: if (err) { - got_lockfile_unlock(*lf); + got_lockfile_unlock(*lf, dir_fd); *lf = NULL; } return err; } const struct got_error * -got_lockfile_unlock(struct got_lockfile *lf) +got_lockfile_unlock(struct got_lockfile *lf, int dir_fd) { const struct got_error *err = NULL; - if (lf->path && lf->fd != -1 && unlink(lf->path) != 0) + if (dir_fd != -1) { + if (lf->path && lf->fd != -1 && + unlinkat(dir_fd, lf->path, 0) != 0) + err = got_error_from_errno("unlinkat"); + } else if (lf->path && lf->fd != -1 && unlink(lf->path) != 0) err = got_error_from_errno("unlink"); if (lf->fd != -1 && close(lf->fd) == -1 && err == NULL) err = got_error_from_errno("close"); blob - 38484be4282a8429eade676e2b71bcbb96196be8 blob + 70dc0d95f90464c02d691b2e2157c818079650c3 --- lib/object_create.c +++ lib/object_create.c @@ -87,7 +87,7 @@ create_object_file(struct got_object_id *id, FILE *con if (err) goto done; - err = got_lockfile_lock(&lf, objpath); + err = got_lockfile_lock(&lf, objpath, -1); if (err) goto done; @@ -107,7 +107,7 @@ done: if (tmpfile && fclose(tmpfile) == EOF && err == NULL) err = got_error_from_errno("fclose"); if (lf) - unlock_err = got_lockfile_unlock(lf); + unlock_err = got_lockfile_unlock(lf, -1); return err ? err : unlock_err; } blob - b89875ec9e861ec53c6a8c19a5fcbaa184ead648 blob + ee703d1487de86d26b7373621514084605d208eb --- lib/reference.c +++ lib/reference.c @@ -174,7 +174,7 @@ parse_ref_file(struct got_reference **ref, const char struct got_lockfile *lf = NULL; if (lock) { - err = got_lockfile_lock(&lf, abspath); + err = got_lockfile_lock(&lf, abspath, -1); if (err) { if (err->code == GOT_ERR_ERRNO && errno == ENOENT) err = got_error_not_ref(name); @@ -189,7 +189,7 @@ parse_ref_file(struct got_reference **ref, const char else err = got_error_not_ref(name); if (lock) - got_lockfile_unlock(lf); + got_lockfile_unlock(lf, -1); return err; } @@ -206,7 +206,7 @@ parse_ref_file(struct got_reference **ref, const char err = got_error_from_errno2("getline", abspath); } if (lock) - got_lockfile_unlock(lf); + got_lockfile_unlock(lf, -1); goto done; } while (linelen > 0 && line[linelen - 1] == '\n') { @@ -217,12 +217,12 @@ parse_ref_file(struct got_reference **ref, const char err = parse_ref_line(ref, absname, line); if (lock) { if (err) - got_lockfile_unlock(lf); + got_lockfile_unlock(lf, -1); else { if (*ref) (*ref)->lf = lf; else - got_lockfile_unlock(lf); + got_lockfile_unlock(lf, -1); } } done: @@ -479,7 +479,7 @@ got_ref_open(struct got_reference **ref, struct got_re } if (lock) { - err = got_lockfile_lock(&lf, packed_refs_path); + err = got_lockfile_lock(&lf, packed_refs_path, -1); if (err) goto done; } @@ -502,7 +502,7 @@ done: if (!err && *ref == NULL) err = got_error_not_ref(refname); if (err && lf) - got_lockfile_unlock(lf); + got_lockfile_unlock(lf, -1); free(path_refs); return err; } @@ -1175,7 +1175,7 @@ got_ref_write(struct got_reference *ref, struct got_re } if (ref->lf == NULL) { - err = got_lockfile_lock(&lf, path); + err = got_lockfile_lock(&lf, path, -1); if (err) goto done; } @@ -1203,7 +1203,7 @@ got_ref_write(struct got_reference *ref, struct got_re tmppath = NULL; done: if (ref->lf == NULL && lf) - unlock_err = got_lockfile_unlock(lf); + unlock_err = got_lockfile_unlock(lf, -1); if (f) { if (fclose(f) == EOF && err == NULL) err = got_error_from_errno("fclose"); @@ -1244,7 +1244,7 @@ delete_packed_ref(struct got_reference *delref, struct goto done; if (delref->lf == NULL) { - err = got_lockfile_lock(&lf, packed_refs_path); + err = got_lockfile_lock(&lf, packed_refs_path, -1); if (err) goto done; } @@ -1348,7 +1348,7 @@ delete_packed_ref(struct got_reference *delref, struct } done: if (delref->lf == NULL && lf) - unlock_err = got_lockfile_unlock(lf); + unlock_err = got_lockfile_unlock(lf, -1); if (f) { if (fclose(f) == EOF && err == NULL) err = got_error_from_errno("fclose"); @@ -1385,7 +1385,7 @@ delete_loose_ref(struct got_reference *ref, struct got } if (ref->lf == NULL) { - err = got_lockfile_lock(&lf, path); + err = got_lockfile_lock(&lf, path, -1); if (err) goto done; } @@ -1396,7 +1396,7 @@ delete_loose_ref(struct got_reference *ref, struct got err = got_error_from_errno2("unlink", path); done: if (ref->lf == NULL && lf) - unlock_err = got_lockfile_unlock(lf); + unlock_err = got_lockfile_unlock(lf, -1); free(path_refs); free(path); @@ -1446,7 +1446,7 @@ const struct got_error * got_ref_unlock(struct got_reference *ref) { const struct got_error *err; - err = got_lockfile_unlock(ref->lf); + err = got_lockfile_unlock(ref->lf, -1); ref->lf = NULL; return err; } blob - 391b44aff9089bc0157349e22029d60c4765029c blob + c5017d50e0b3fa7053f7d9159a76ee0467cf926a --- lib/repository_admin.c +++ lib/repository_admin.c @@ -1053,7 +1053,7 @@ purge_loose_object(struct got_object_id *id, void *dat } if (!a->dry_run) { - err = got_lockfile_lock(&lf, path); + err = got_lockfile_lock(&lf, path, -1); if (err) goto done; if (unlink(path) == -1) { @@ -1073,7 +1073,7 @@ done: err = got_error_from_errno("close"); free(path); if (lf) - unlock_err = got_lockfile_unlock(lf); + unlock_err = got_lockfile_unlock(lf, -1); return err ? err : unlock_err; }