Mercurial > dovecot > core-2.2
changeset 2063:21a3e5d08290 HEAD
mail_index_refresh() - allows forcing a refresh check
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 26 May 2004 02:13:57 +0300 |
parents | 397ce1dbc593 |
children | 5cfdc99fab69 |
files | src/lib-index/mail-index-lock.c src/lib-index/mail-index-private.h src/lib-index/mail-index.c src/lib-index/mail-index.h |
diffstat | 4 files changed, 163 insertions(+), 158 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-lock.c Tue May 25 20:50:36 2004 +0300 +++ b/src/lib-index/mail-index-lock.c Wed May 26 02:13:57 2004 +0300 @@ -27,99 +27,6 @@ #include <stdio.h> #include <sys/stat.h> -static int mail_index_reopen(struct mail_index *index, int fd) -{ - struct mail_index_map *old_map; - unsigned int old_shared_locks, old_lock_id, lock_id = 0; - int ret, old_fd, old_lock_type; - - old_map = index->map; - old_fd = index->fd; - - index->map = NULL; - index->hdr = NULL; - - /* new file, new locks. the old fd can keep it's locks, they don't - matter anymore as no-one's going to modify the file. */ - old_lock_type = index->lock_type; - old_lock_id = index->lock_id; - old_shared_locks = index->shared_lock_count; - - if (index->lock_type == F_RDLCK) - index->lock_type = F_UNLCK; - index->lock_id += 2; - index->shared_lock_count = 0; - - if (fd != -1) { - index->fd = fd; - ret = 0; - } else { - i_assert(index->excl_lock_count == 0); - ret = mail_index_try_open_only(index); - if (ret > 0) - ret = mail_index_lock_shared(index, FALSE, &lock_id); - else if (ret == 0) { - /* index file is lost */ - ret = -1; - } - } - - if (ret == 0) { - if (mail_index_map(index, FALSE) <= 0) - ret = -1; - } - - if (lock_id != 0) - mail_index_unlock(index, lock_id); - - if (ret == 0) { - mail_index_unmap(index, old_map); - if (close(old_fd) < 0) - mail_index_set_syscall_error(index, "close()"); - } else { - if (index->map != NULL) - mail_index_unmap(index, index->map); - if (index->fd != -1) { - if (close(index->fd) < 0) - mail_index_set_syscall_error(index, "close()"); - } - - index->map = old_map; - index->hdr = index->map->hdr; - index->fd = old_fd; - index->lock_type = old_lock_type; - index->lock_id = old_lock_id; - index->shared_lock_count = old_shared_locks; - } - return ret; -} - -static int mail_index_has_changed(struct mail_index *index) -{ - struct stat st1, st2; - - if (fstat(index->fd, &st1) < 0) - return mail_index_set_syscall_error(index, "fstat()"); - if (stat(index->filepath, &st2) < 0) { - mail_index_set_syscall_error(index, "stat()"); - if (errno != ENOENT) - return -1; - - /* lost it? recreate */ - (void)mail_index_mark_corrupted(index); - return -1; - } - - if (st1.st_ino != st2.st_ino || - !CMP_DEV_T(st1.st_dev, st2.st_dev)) { - if (mail_index_reopen(index, -1) < 0) - return -1; - return 1; - } else { - return 0; - } -} - int mail_index_map_lock_mprotect(struct mail_index *index, struct mail_index_map *map, int lock_type) { @@ -167,7 +74,7 @@ } if (update_index && index->excl_lock_count == 0) { - if ((ret2 = mail_index_has_changed(index)) < 0) + if ((ret2 = mail_index_refresh(index)) < 0) return -1; if (ret > 0 && ret2 == 0) return 1; @@ -184,7 +91,7 @@ if (lock_type == F_WRLCK) return 0; if (update_index && index->lock_type == F_UNLCK) { - if (mail_index_has_changed(index) < 0) + if (mail_index_refresh(index) < 0) return -1; } if (mail_index_lock_mprotect(index, lock_type) < 0)
--- a/src/lib-index/mail-index-private.h Tue May 25 20:50:36 2004 +0300 +++ b/src/lib-index/mail-index-private.h Wed May 26 02:13:57 2004 +0300 @@ -77,8 +77,7 @@ int mail_index_write_header(struct mail_index *index, const struct mail_index_header *hdr); -int mail_index_try_open_only(struct mail_index *index); -int mail_index_try_open(struct mail_index *index, unsigned int *lock_id_r); +int mail_index_reopen(struct mail_index *index, int fd); int mail_index_create_tmp_file(struct mail_index *index, const char **path_r); /* Returns 0 = ok, -1 = error. If update_index is TRUE, reopens the index
--- a/src/lib-index/mail-index.c Tue May 25 20:50:36 2004 +0300 +++ b/src/lib-index/mail-index.c Wed May 26 02:13:57 2004 +0300 @@ -14,6 +14,8 @@ #include <time.h> #include <sys/stat.h> +static int mail_index_try_open_only(struct mail_index *index); + struct mail_index *mail_index_alloc(const char *dir, const char *prefix) { struct mail_index *index; @@ -361,6 +363,68 @@ return mem_map; } +static int mail_index_try_open_only(struct mail_index *index) +{ + int i; + + for (i = 0; i < 3; i++) { + index->fd = open(index->filepath, O_RDWR); + if (index->fd == -1 && errno == EACCES) { + index->fd = open(index->filepath, O_RDONLY); + index->readonly = TRUE; + } + if (index->fd != -1 || errno != ESTALE) + break; + + /* May happen with some OSes with NFS. Try again, although + there's still a race condition with another computer + creating the index file again. However, we can't try forever + as ESTALE happens also if index directory has been deleted + from server.. */ + } + if (index->fd == -1) { + if (errno != ENOENT) + return mail_index_set_syscall_error(index, "open()"); + + /* have to create it */ + return 0; + } + return 1; +} + +static int +mail_index_try_open(struct mail_index *index, unsigned int *lock_id_r) +{ + unsigned int lock_id; + int ret; + + if (lock_id_r != NULL) + *lock_id_r = 0; + + ret = mail_index_try_open_only(index); + if (ret <= 0) + return ret; + + if (mail_index_lock_shared(index, FALSE, &lock_id) < 0) + return -1; + ret = mail_index_map(index, FALSE); + if (ret == 0) { + /* it's corrupted - recreate it */ + mail_index_unlock(index, lock_id); + if (lock_id_r != NULL) + *lock_id_r = 0; + + (void)close(index->fd); + index->fd = -1; + } else { + if (lock_id_r != NULL) + *lock_id_r = lock_id; + else + mail_index_unlock(index, lock_id); + } + return ret; +} + void mail_index_header_init(struct mail_index_header *hdr) { time_t now = time(NULL); @@ -481,67 +545,6 @@ return 1; } -int mail_index_try_open_only(struct mail_index *index) -{ - int i; - - for (i = 0; i < 3; i++) { - index->fd = open(index->filepath, O_RDWR); - if (index->fd == -1 && errno == EACCES) { - index->fd = open(index->filepath, O_RDONLY); - index->readonly = TRUE; - } - if (index->fd != -1 || errno != ESTALE) - break; - - /* May happen with some OSes with NFS. Try again, although - there's still a race condition with another computer - creating the index file again. However, we can't try forever - as ESTALE happens also if index directory has been deleted - from server.. */ - } - if (index->fd == -1) { - if (errno != ENOENT) - return mail_index_set_syscall_error(index, "open()"); - - /* have to create it */ - return 0; - } - return 1; -} - -int mail_index_try_open(struct mail_index *index, unsigned int *lock_id_r) -{ - unsigned int lock_id; - int ret; - - if (lock_id_r != NULL) - *lock_id_r = 0; - - ret = mail_index_try_open_only(index); - if (ret <= 0) - return ret; - - if (mail_index_lock_shared(index, FALSE, &lock_id) < 0) - return -1; - ret = mail_index_map(index, FALSE); - if (ret == 0) { - /* it's corrupted - recreate it */ - mail_index_unlock(index, lock_id); - if (lock_id_r != NULL) - *lock_id_r = 0; - - (void)close(index->fd); - index->fd = -1; - } else { - if (lock_id_r != NULL) - *lock_id_r = lock_id; - else - mail_index_unlock(index, lock_id); - } - return ret; -} - static int mail_index_open_files(struct mail_index *index, enum mail_index_open_flags flags) { @@ -650,6 +653,99 @@ index->opened = FALSE; } +int mail_index_reopen(struct mail_index *index, int fd) +{ + struct mail_index_map *old_map; + unsigned int old_shared_locks, old_lock_id, lock_id = 0; + int ret, old_fd, old_lock_type; + + old_map = index->map; + old_fd = index->fd; + + index->map = NULL; + index->hdr = NULL; + + /* new file, new locks. the old fd can keep it's locks, they don't + matter anymore as no-one's going to modify the file. */ + old_lock_type = index->lock_type; + old_lock_id = index->lock_id; + old_shared_locks = index->shared_lock_count; + + if (index->lock_type == F_RDLCK) + index->lock_type = F_UNLCK; + index->lock_id += 2; + index->shared_lock_count = 0; + + if (fd != -1) { + index->fd = fd; + ret = 0; + } else { + i_assert(index->excl_lock_count == 0); + ret = mail_index_try_open_only(index); + if (ret > 0) + ret = mail_index_lock_shared(index, FALSE, &lock_id); + else if (ret == 0) { + /* index file is lost */ + ret = -1; + } + } + + if (ret == 0) { + if (mail_index_map(index, FALSE) <= 0) + ret = -1; + } + + if (lock_id != 0) + mail_index_unlock(index, lock_id); + + if (ret == 0) { + mail_index_unmap(index, old_map); + if (close(old_fd) < 0) + mail_index_set_syscall_error(index, "close()"); + } else { + if (index->map != NULL) + mail_index_unmap(index, index->map); + if (index->fd != -1) { + if (close(index->fd) < 0) + mail_index_set_syscall_error(index, "close()"); + } + + index->map = old_map; + index->hdr = index->map->hdr; + index->fd = old_fd; + index->lock_type = old_lock_type; + index->lock_id = old_lock_id; + index->shared_lock_count = old_shared_locks; + } + return ret; +} + +int mail_index_refresh(struct mail_index *index) +{ + struct stat st1, st2; + + if (fstat(index->fd, &st1) < 0) + return mail_index_set_syscall_error(index, "fstat()"); + if (stat(index->filepath, &st2) < 0) { + mail_index_set_syscall_error(index, "stat()"); + if (errno != ENOENT) + return -1; + + /* lost it? recreate */ + (void)mail_index_mark_corrupted(index); + return -1; + } + + if (st1.st_ino != st2.st_ino || + !CMP_DEV_T(st1.st_dev, st2.st_dev)) { + if (mail_index_reopen(index, -1) < 0) + return -1; + return 1; + } else { + return 0; + } +} + struct mail_cache *mail_index_get_cache(struct mail_index *index) { return index->cache;
--- a/src/lib-index/mail-index.h Tue May 25 20:50:36 2004 +0300 +++ b/src/lib-index/mail-index.h Wed May 26 02:13:57 2004 +0300 @@ -136,6 +136,9 @@ int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags); void mail_index_close(struct mail_index *index); +/* Force checking if index can be refreshed. */ +int mail_index_refresh(struct mail_index *index); + struct mail_cache *mail_index_get_cache(struct mail_index *index); /* View can be used to look into index. Sequence numbers inside view change