From: Junio C Hamano Date: Tue, 6 Jun 2006 23:42:52 +0000 (-0700) Subject: Merge branch 'jc/lockfile' X-Git-Tag: v1.4.0-rc2~15 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=9941afc051d953ee5e8fd9a8a27c5cd659ef9552;hp=44fe4f522e63d3f01174459af674af2f9c293671;p=git.git Merge branch 'jc/lockfile' * jc/lockfile: ref-log: style fixes. refs.c: convert it to use lockfile interface. Make index file locking code reusable to others. --- diff --git a/Makefile b/Makefile index f802043a..265a7167 100644 --- a/Makefile +++ b/Makefile @@ -210,7 +210,7 @@ DIFF_OBJS = \ LIB_OBJS = \ blob.o commit.o connect.o csum-file.o cache-tree.o base85.o \ - date.o diff-delta.o entry.o exec_cmd.o ident.o index.o \ + date.o diff-delta.o entry.o exec_cmd.o ident.o lockfile.o \ object.o pack-check.o patch-delta.o path.o pkt-line.o \ quote.o read-cache.o refs.o run-command.o dir.o \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ diff --git a/builtin-add.c b/builtin-add.c index 02fe38b0..bfbbb1bf 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -122,7 +122,7 @@ static int add_file_to_index(const char *path, int verbose) return 0; } -static struct cache_file cache_file; +static struct lock_file lock_file; int cmd_add(int argc, const char **argv, char **envp) { @@ -134,9 +134,9 @@ int cmd_add(int argc, const char **argv, char **envp) git_config(git_default_config); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); if (newfd < 0) - die("unable to create new cachefile"); + die("unable to create new index file"); if (read_cache() < 0) die("index file corrupt"); @@ -181,7 +181,7 @@ int cmd_add(int argc, const char **argv, char **envp) if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) + commit_lock_file(&lock_file)) die("Unable to write new index file"); } diff --git a/builtin-apply.c b/builtin-apply.c index 6a4fb966..e113c74d 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2072,7 +2072,7 @@ static void write_out_results(struct patch *list, int skipped_patch) } } -static struct cache_file cache_file; +static struct lock_file lock_file; static struct excludes { struct excludes *next; @@ -2133,8 +2133,12 @@ static int apply_patch(int fd, const char *filename) apply = 0; write_index = check_index && apply; - if (write_index && newfd < 0) - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + if (write_index && newfd < 0) { + newfd = hold_lock_file_for_update(&lock_file, + get_index_file()); + if (newfd < 0) + die("unable to create new index file"); + } if (check_index) { if (read_cache() < 0) die("unable to read index file"); @@ -2312,8 +2316,8 @@ int cmd_apply(int argc, const char **argv, char **envp) if (write_index) { if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) - die("Unable to write new cachefile"); + commit_lock_file(&lock_file)) + die("Unable to write new index file"); } return 0; diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 8d1a22d3..bb50fbd2 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -853,7 +853,7 @@ static void prime_cache_tree(void) static const char read_tree_usage[] = "git-read-tree ( | -m [--aggressive] [-u | -i] [ []])"; -static struct cache_file cache_file; +static struct lock_file lock_file; int cmd_read_tree(int argc, const char **argv, char **envp) { @@ -864,9 +864,9 @@ int cmd_read_tree(int argc, const char **argv, char **envp) setup_git_directory(); git_config(git_default_config); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); if (newfd < 0) - die("unable to create new cachefile"); + die("unable to create new index file"); git_config(git_default_config); @@ -981,7 +981,7 @@ int cmd_read_tree(int argc, const char **argv, char **envp) } if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) + commit_lock_file(&lock_file)) die("unable to write new index file"); return 0; } diff --git a/builtin-rm.c b/builtin-rm.c index e7793a20..ef2f8b5d 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -41,7 +41,7 @@ static int remove_file(const char *name) return ret; } -static struct cache_file cache_file; +static struct lock_file lock_file; int cmd_rm(int argc, const char **argv, char **envp) { @@ -53,7 +53,7 @@ int cmd_rm(int argc, const char **argv, char **envp) git_config(git_default_config); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); if (newfd < 0) die("unable to create new index file"); @@ -144,7 +144,7 @@ int cmd_rm(int argc, const char **argv, char **envp) if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) + commit_lock_file(&lock_file)) die("Unable to write new index file"); } diff --git a/cache.h b/cache.h index d530af97..d5d7fe4f 100644 --- a/cache.h +++ b/cache.h @@ -167,13 +167,13 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); #define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */ extern int refresh_cache(unsigned int flags); -struct cache_file { - struct cache_file *next; - char lockfile[PATH_MAX]; +struct lock_file { + struct lock_file *next; + char filename[PATH_MAX]; }; -extern int hold_index_file_for_update(struct cache_file *, const char *path); -extern int commit_index_file(struct cache_file *); -extern void rollback_index_file(struct cache_file *); +extern int hold_lock_file_for_update(struct lock_file *, const char *path); +extern int commit_lock_file(struct lock_file *); +extern void rollback_lock_file(struct lock_file *); /* Environment bits from configuration mechanism */ extern int trust_executable_bit; diff --git a/checkout-index.c b/checkout-index.c index 9876af6f..ea40bc29 100644 --- a/checkout-index.c +++ b/checkout-index.c @@ -168,7 +168,7 @@ static int checkout_all(void) static const char checkout_cache_usage[] = "git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]|all] [--prefix=] [--temp] [--] ..."; -static struct cache_file cache_file; +static struct lock_file lock_file; int main(int argc, char **argv) { @@ -211,9 +211,8 @@ int main(int argc, char **argv) if (!strcmp(arg, "-u") || !strcmp(arg, "--index")) { state.refresh_cache = 1; if (newfd < 0) - newfd = hold_index_file_for_update - (&cache_file, - get_index_file()); + newfd = hold_lock_file_for_update + (&lock_file, get_index_file()); if (newfd < 0) die("cannot open index.lock file."); continue; @@ -262,7 +261,7 @@ int main(int argc, char **argv) */ if (state.refresh_cache) { close(newfd); newfd = -1; - rollback_index_file(&cache_file); + rollback_lock_file(&lock_file); } state.refresh_cache = 0; } @@ -312,7 +311,7 @@ int main(int argc, char **argv) if (0 <= newfd && (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file))) - die("Unable to write new cachefile"); + commit_lock_file(&lock_file))) + die("Unable to write new index file"); return 0; } diff --git a/fetch.c b/fetch.c index e040ef97..cf6c9949 100644 --- a/fetch.c +++ b/fetch.c @@ -150,7 +150,8 @@ static int process(struct object *obj) if (has_sha1_file(obj->sha1)) { /* We already have it, so we should scan it now. */ obj->flags |= TO_SCAN; - } else { + } + else { if (obj->flags & COMPLETE) return 0; prefetch(obj->sha1); @@ -255,7 +256,8 @@ int pull(char *target) if (write_ref_log_details) { msg = xmalloc(strlen(write_ref_log_details) + 12); sprintf(msg, "fetch from %s", write_ref_log_details); - } else + } + else msg = NULL; ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)"); if (msg) diff --git a/index.c b/index.c deleted file mode 100644 index f92b960a..00000000 --- a/index.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2005, Junio C Hamano - */ -#include -#include "cache.h" - -static struct cache_file *cache_file_list; - -static void remove_lock_file(void) -{ - while (cache_file_list) { - if (cache_file_list->lockfile[0]) - unlink(cache_file_list->lockfile); - cache_file_list = cache_file_list->next; - } -} - -static void remove_lock_file_on_signal(int signo) -{ - remove_lock_file(); - signal(SIGINT, SIG_DFL); - raise(signo); -} - -int hold_index_file_for_update(struct cache_file *cf, const char *path) -{ - int fd; - sprintf(cf->lockfile, "%s.lock", path); - fd = open(cf->lockfile, O_RDWR | O_CREAT | O_EXCL, 0666); - if (fd >=0 && !cf->next) { - cf->next = cache_file_list; - cache_file_list = cf; - signal(SIGINT, remove_lock_file_on_signal); - atexit(remove_lock_file); - } - return fd; -} - -int commit_index_file(struct cache_file *cf) -{ - char indexfile[PATH_MAX]; - int i; - strcpy(indexfile, cf->lockfile); - i = strlen(indexfile) - 5; /* .lock */ - indexfile[i] = 0; - i = rename(cf->lockfile, indexfile); - cf->lockfile[0] = 0; - return i; -} - -void rollback_index_file(struct cache_file *cf) -{ - if (cf->lockfile[0]) - unlink(cf->lockfile); - cf->lockfile[0] = 0; -} - diff --git a/lockfile.c b/lockfile.c new file mode 100644 index 00000000..9bc60837 --- /dev/null +++ b/lockfile.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2005, Junio C Hamano + */ +#include +#include "cache.h" + +static struct lock_file *lock_file_list; + +static void remove_lock_file(void) +{ + while (lock_file_list) { + if (lock_file_list->filename[0]) + unlink(lock_file_list->filename); + lock_file_list = lock_file_list->next; + } +} + +static void remove_lock_file_on_signal(int signo) +{ + remove_lock_file(); + signal(SIGINT, SIG_DFL); + raise(signo); +} + +int hold_lock_file_for_update(struct lock_file *lk, const char *path) +{ + int fd; + sprintf(lk->filename, "%s.lock", path); + fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666); + if (fd >=0 && !lk->next) { + lk->next = lock_file_list; + lock_file_list = lk; + signal(SIGINT, remove_lock_file_on_signal); + atexit(remove_lock_file); + } + return fd; +} + +int commit_lock_file(struct lock_file *lk) +{ + char result_file[PATH_MAX]; + int i; + strcpy(result_file, lk->filename); + i = strlen(result_file) - 5; /* .lock */ + result_file[i] = 0; + i = rename(lk->filename, result_file); + lk->filename[0] = 0; + return i; +} + +void rollback_lock_file(struct lock_file *lk) +{ + if (lk->filename[0]) + unlink(lk->filename); + lk->filename[0] = 0; +} + diff --git a/refs.c b/refs.c index eeb1196e..f91b7716 100644 --- a/refs.c +++ b/refs.c @@ -259,7 +259,7 @@ int check_ref_format(const char *ref) } } -static struct ref_lock* verify_lock(struct ref_lock *lock, +static struct ref_lock *verify_lock(struct ref_lock *lock, const unsigned char *old_sha1, int mustexist) { char buf[40]; @@ -285,7 +285,7 @@ static struct ref_lock* verify_lock(struct ref_lock *lock, return lock; } -static struct ref_lock* lock_ref_sha1_basic(const char *path, +static struct ref_lock *lock_ref_sha1_basic(const char *path, int plen, const unsigned char *old_sha1, int mustexist) { @@ -301,19 +301,18 @@ static struct ref_lock* lock_ref_sha1_basic(const char *path, unlock_ref(lock); return NULL; } + lock->lk = xcalloc(1, sizeof(struct lock_file)); lock->ref_file = strdup(path); - lock->lock_file = strdup(mkpath("%s.lock", lock->ref_file)); lock->log_file = strdup(git_path("logs/%s", lock->ref_file + plen)); lock->force_write = lstat(lock->ref_file, &st) && errno == ENOENT; - if (safe_create_leading_directories(lock->lock_file)) - die("unable to create directory for %s", lock->lock_file); - lock->lock_fd = open(lock->lock_file, - O_WRONLY | O_CREAT | O_EXCL, 0666); + if (safe_create_leading_directories(lock->ref_file)) + die("unable to create directory for %s", lock->ref_file); + lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file); if (lock->lock_fd < 0) { error("Couldn't open lock file %s: %s", - lock->lock_file, strerror(errno)); + lock->lk->filename, strerror(errno)); unlock_ref(lock); return NULL; } @@ -321,7 +320,7 @@ static struct ref_lock* lock_ref_sha1_basic(const char *path, return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock; } -struct ref_lock* lock_ref_sha1(const char *ref, +struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1, int mustexist) { if (check_ref_format(ref)) @@ -330,23 +329,23 @@ struct ref_lock* lock_ref_sha1(const char *ref, 5 + strlen(ref), old_sha1, mustexist); } -struct ref_lock* lock_any_ref_for_update(const char *ref, +struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int mustexist) { return lock_ref_sha1_basic(git_path("%s", ref), strlen(ref), old_sha1, mustexist); } -void unlock_ref (struct ref_lock *lock) +void unlock_ref(struct ref_lock *lock) { if (lock->lock_fd >= 0) { close(lock->lock_fd); - unlink(lock->lock_file); + /* Do not free lock->lk -- atexit() still looks at them */ + if (lock->lk) + rollback_lock_file(lock->lk); } if (lock->ref_file) free(lock->ref_file); - if (lock->lock_file) - free(lock->lock_file); if (lock->log_file) free(lock->log_file); free(lock); @@ -385,7 +384,8 @@ static int log_ref_write(struct ref_lock *lock, sha1_to_hex(sha1), comitter, msg); - } else { + } + else { maxlen = strlen(comitter) + 2*40 + 4; logrec = xmalloc(maxlen); len = snprintf(logrec, maxlen, "%s %s %s\n", @@ -415,7 +415,7 @@ int write_ref_sha1(struct ref_lock *lock, if (write(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 || write(lock->lock_fd, &term, 1) != 1 || close(lock->lock_fd) < 0) { - error("Couldn't write %s", lock->lock_file); + error("Couldn't write %s", lock->lk->filename); unlock_ref(lock); return -1; } @@ -423,7 +423,7 @@ int write_ref_sha1(struct ref_lock *lock, unlock_ref(lock); return -1; } - if (rename(lock->lock_file, lock->ref_file) < 0) { + if (commit_lock_file(lock->lk)) { error("Couldn't set %s", lock->ref_file); unlock_ref(lock); return -1; @@ -478,10 +478,12 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1) "warning: Log %s has gap after %s.\n", logfile, show_rfc2822_date(date, tz)); } - } else if (date == at_time) { + } + else if (date == at_time) { if (get_sha1_hex(rec + 41, sha1)) die("Log %s is corrupt.", logfile); - } else { + } + else { if (get_sha1_hex(rec + 41, logged_sha1)) die("Log %s is corrupt.", logfile); if (memcmp(logged_sha1, sha1, 20)) { diff --git a/refs.h b/refs.h index 6c946eab..553155c0 100644 --- a/refs.h +++ b/refs.h @@ -3,8 +3,8 @@ struct ref_lock { char *ref_file; - char *lock_file; char *log_file; + struct lock_file *lk; unsigned char old_sha1[20]; int lock_fd; int force_write; @@ -24,13 +24,13 @@ extern int for_each_remote_ref(int (*fn)(const char *path, const unsigned char * extern int get_ref_sha1(const char *ref, unsigned char *sha1); /** Locks a "refs/" ref returning the lock on success and NULL on failure. **/ -extern struct ref_lock* lock_ref_sha1(const char *ref, const unsigned char *old_sha1, int mustexist); +extern struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1, int mustexist); /** Locks any ref (for 'HEAD' type refs). */ -extern struct ref_lock* lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int mustexist); +extern struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int mustexist); /** Release any lock taken but not written. **/ -extern void unlock_ref (struct ref_lock *lock); +extern void unlock_ref(struct ref_lock *lock); /** Writes sha1 into the ref specified by the lock. **/ extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg); diff --git a/update-index.c b/update-index.c index 956b6b34..fbccc4a6 100644 --- a/update-index.c +++ b/update-index.c @@ -186,7 +186,7 @@ static void chmod_path(int flip, const char *path) die("git-update-index: cannot chmod %cx '%s'", flip, path); } -static struct cache_file cache_file; +static struct lock_file lock_file; static void update_one(const char *path, const char *prefix, int prefix_length) { @@ -489,9 +489,9 @@ int main(int argc, const char **argv) git_config(git_default_config); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); if (newfd < 0) - die("unable to create new cachefile"); + die("unable to create new index file"); entries = read_cache(); if (entries < 0) @@ -645,8 +645,8 @@ int main(int argc, const char **argv) finish: if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) - die("Unable to write new cachefile"); + commit_lock_file(&lock_file)) + die("Unable to write new index file"); } return has_errors ? 1 : 0; diff --git a/write-tree.c b/write-tree.c index 7a4f691d..d6a60589 100644 --- a/write-tree.c +++ b/write-tree.c @@ -11,7 +11,7 @@ static int missing_ok = 0; static const char write_tree_usage[] = "git-write-tree [--missing-ok]"; -static struct cache_file cache_file; +static struct lock_file lock_file; int main(int argc, char **argv) { @@ -19,7 +19,7 @@ int main(int argc, char **argv) setup_git_directory(); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); entries = read_cache(); if (argc == 2) { if (!strcmp(argv[1], "--missing-ok")) @@ -45,7 +45,7 @@ int main(int argc, char **argv) die("git-write-tree: error building trees"); if (0 <= newfd) { if (!write_cache(newfd, active_cache, active_nr)) - commit_index_file(&cache_file); + commit_lock_file(&lock_file); } /* Not being able to write is fine -- we are only interested * in updating the cache-tree part, and if the next caller