]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Locking changes. bugfixes.
authorTimo Sirainen <tss@iki.fi>
Wed, 28 Apr 2004 02:39:03 +0000 (05:39 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 28 Apr 2004 02:39:03 +0000 (05:39 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-fsck.c
src/lib-index/mail-index-lock.c
src/lib-index/mail-index-private.h
src/lib-index/mail-index-sync-update.c
src/lib-index/mail-index-sync.c
src/lib-index/mail-index-view.c
src/lib-index/mail-transaction-log-view.c
src/lib-index/mail-transaction-log.c
src/lib-index/mail-transaction-util.c

index 583d5ca82070c542a3dbb2d2b5b004541c6bd560..f02124ded531b05ba2d8e23d332e39b8c02d0d63 100644 (file)
@@ -112,7 +112,7 @@ int mail_index_fsck(struct mail_index *index)
        if (mail_transaction_log_sync_lock(index->log, &file_seq,
                                           &file_offset) < 0)
                return -1;
-       if (mail_index_lock_exclusive(index, 0, 0, &lock_id) < 0) {
+       if (mail_index_lock_exclusive(index, &lock_id) < 0) {
                 mail_transaction_log_sync_unlock(index->log);
                return -1;
        }
index b829110bdb8bdcde2eb37dd59bab996716d1375a..74670147fd8e0f61e0231509d3cedf7907ee49fb 100644 (file)
@@ -108,8 +108,13 @@ static int mail_index_lock(struct mail_index *index, int lock_type,
                   locks then, though */
                if (lock_type == F_WRLCK)
                        return 0;
+               if (update_index && index->lock_type == F_UNLCK) {
+                       if (mail_index_has_changed(index) < 0)
+                               return -1;
+               }
                if (mail_index_lock_mprotect(index, lock_type) < 0)
                        return -1;
+               index->lock_type = lock_type;
                return 1;
        }
 
@@ -227,23 +232,6 @@ static int mail_index_copy(struct mail_index *index)
        return fd;
 }
 
-static int mail_index_need_lock(struct mail_index *index,
-                               uint32_t log_file_seq, uoff_t log_file_offset)
-{
-       if (mail_index_map(index, FALSE) <= 0)
-               return 1;
-
-       if (log_file_seq != 0 &&
-           (index->hdr->log_file_seq > log_file_seq ||
-            (index->hdr->log_file_seq == log_file_seq &&
-             index->hdr->log_file_offset >= log_file_offset))) {
-               /* already synced */
-               return 0;
-       }
-
-       return 1;
-}
-
 static int mail_index_lock_exclusive_copy(struct mail_index *index)
 {
        int fd;
@@ -252,7 +240,7 @@ static int mail_index_lock_exclusive_copy(struct mail_index *index)
 
        if (index->copy_lock_path != NULL) {
                index->excl_lock_count++;
-               return 1;
+               return 0;
        }
 
        /* copy the index to index.tmp and use it. when */
@@ -280,14 +268,12 @@ static int mail_index_lock_exclusive_copy(struct mail_index *index)
        }
 
         i_assert(index->excl_lock_count == 1);
-       return 1;
+       return 0;
 }
 
 int mail_index_lock_exclusive(struct mail_index *index,
-                             uint32_t log_file_seq, uoff_t log_file_offset,
                              unsigned int *lock_id_r)
 {
-       unsigned int lock_id;
        int ret;
 
        /* exclusive transaction log lock protects exclusive locking
@@ -296,33 +282,11 @@ int mail_index_lock_exclusive(struct mail_index *index,
 
        /* wait two seconds for exclusive lock */
        ret = mail_index_lock(index, F_WRLCK, 2, TRUE, lock_id_r);
-       if (ret > 0) {
-               if (mail_index_need_lock(index, log_file_seq, log_file_offset))
-                       return 1;
-
-               mail_index_unlock(index, *lock_id_r);
+       if (ret > 0)
                return 0;
-       }
        if (ret < 0)
                return -1;
 
-       /* Grab shared lock to make sure it's not already being
-          exclusively locked */
-       if (mail_index_lock_shared(index, TRUE, &lock_id) < 0)
-               return -1;
-
-       if (log_file_seq != 0) {
-               /* check first if we really need to recreate it */
-               ret = mail_index_need_lock(index, log_file_seq,
-                                          log_file_offset);
-               if (ret == 0) {
-                       mail_index_unlock(index, lock_id);
-                       return 0;
-               }
-       }
-
-       mail_index_unlock(index, lock_id);
-
        *lock_id_r = index->lock_id + 1;
        return mail_index_lock_exclusive_copy(index);
 }
index d99bef075e816c8e5dc288dff64cebbc3f597856..977d3031a17c06a2038940da6b6604d32bf36286 100644 (file)
@@ -99,9 +99,8 @@ int mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
    races, unless transaction log is exclusively locked). */
 int mail_index_lock_shared(struct mail_index *index, int update_index,
                           unsigned int *lock_id_r);
-/* Returns 1 = ok, 0 = already synced up to given log_file_offset, -1 = error */
+/* Returns 0 = ok, -1 = error. */
 int mail_index_lock_exclusive(struct mail_index *index,
-                             uint32_t log_file_seq, uoff_t log_file_offset,
                              unsigned int *lock_id_r);
 void mail_index_unlock(struct mail_index *index, unsigned int lock_id);
 /* Returns 1 if given lock_id is valid, 0 if not. */
index 84c787d168bdd6987dc5061657e45baa0d99e39b..9c0cfefe12620222baad91b4d9f3053bf30f0e97 100644 (file)
@@ -176,6 +176,7 @@ int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx)
        unsigned int append_count;
        uint32_t count, file_seq, src_idx, dest_idx;
        uoff_t file_offset;
+       unsigned int lock_id;
        int ret;
 
        /* rewind */
@@ -188,6 +189,9 @@ int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx)
                return 0;
        }
 
+       if (mail_index_lock_exclusive(index, &lock_id) < 0)
+               return -1;
+
        if (MAIL_INDEX_MAP_IS_IN_MEMORY(map))
                map->write_to_disk = TRUE;
 
@@ -261,12 +265,15 @@ int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx)
 
        if (!MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
                memcpy(map->mmap_base, &ctx.hdr, sizeof(ctx.hdr));
-               if (msync(map->mmap_base, map->file_used_size, MS_SYNC) < 0)
-                       return mail_index_set_syscall_error(index, "msync()");
+               if (msync(map->mmap_base, map->file_used_size, MS_SYNC) < 0) {
+                       mail_index_set_syscall_error(index, "msync()");
+                       ret = -1;
+               }
        } else {
                map->hdr_copy = ctx.hdr;
                map->hdr = &map->hdr_copy;
        }
 
+       mail_index_unlock(index, lock_id);
        return ret;
 }
index f81e242d13294e51c84ece3b5e956d0ab0f9d4d8..893302c11b37b226411f6b9c328a4aa895c3bdb5 100644 (file)
@@ -115,6 +115,19 @@ static int mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
        return ret;
 }
 
+static int mail_index_need_lock(struct mail_index *index,
+                               uint32_t log_file_seq, uoff_t log_file_offset)
+{
+       if (index->hdr->log_file_seq > log_file_seq ||
+            (index->hdr->log_file_seq == log_file_seq &&
+             index->hdr->log_file_offset >= log_file_offset)) {
+               /* already synced */
+               return 0;
+       }
+
+       return 1;
+}
+
 int mail_index_sync_begin(struct mail_index *index,
                           struct mail_index_sync_ctx **ctx_r,
                          struct mail_index_view **view_r,
@@ -125,25 +138,27 @@ int mail_index_sync_begin(struct mail_index *index,
        uoff_t offset;
        size_t size;
        unsigned int lock_id;
-       int ret;
 
        if (mail_transaction_log_sync_lock(index->log, &seq, &offset) < 0)
                return -1;
 
-       /* FIXME: really needed yet? If there are readers, the index file
-          is copied even if there are no changes.. */
-       ret = mail_index_lock_exclusive(index, log_file_seq,
-                                       log_file_offset, &lock_id);
-       if (ret <= 0) {
+       if (mail_index_lock_shared(index, TRUE, &lock_id) < 0) {
                mail_transaction_log_sync_unlock(index->log);
-               return ret;
+               return -1;
        }
 
        if (mail_index_map(index, FALSE) <= 0) {
                mail_transaction_log_sync_unlock(index->log);
+               mail_index_unlock(index, lock_id);
                return -1;
        }
 
+       if (!mail_index_need_lock(index, log_file_seq, log_file_offset)) {
+               mail_index_unlock(index, lock_id);
+               mail_transaction_log_sync_unlock(index->log);
+               return 0;
+       }
+
        ctx = i_new(struct mail_index_sync_ctx, 1);
        ctx->index = index;
        ctx->lock_id = lock_id;
index 48d340aac593e1396d7d151fef59532a244dffad..ad0d2709d762d960c4cc28c7f77b54def8668409 100644 (file)
@@ -50,6 +50,8 @@ int mail_index_view_lock_head(struct mail_index_view *view, int update_index)
                        view->inconsistent = TRUE;
                        return -1;
                }
+       } else if (update_index) {
+               // FIXME: check if we need to reopen it!
        }
 
        return 0;
index 62c68c5cb172553dcca053a55d63b2c66b3c912f..e933c13968c43913d9ef5710f73f658b1250609a 100644 (file)
@@ -371,9 +371,15 @@ int mail_transaction_log_view_next(struct mail_transaction_log_view *view,
                                        view->expunges_buf);
                ret = mail_transaction_map(hdr, data, &seqfix_funcs, view);
                mail_transaction_expunge_traverse_deinit(view->exp_ctx);
-               i_assert(buffer_get_used_size(view->data_buf) == hdr->size);
 
-               *data_r = buffer_get_data(view->data_buf, NULL);
+               if (ret > 0) {
+                       /* modified */
+                       i_assert(buffer_get_used_size(view->data_buf) ==
+                                hdr->size);
+                       *data_r = buffer_get_data(view->data_buf, NULL);
+               } else {
+                       i_assert(buffer_get_used_size(view->data_buf) == 0);
+               }
        }
 
        if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
index 7c2e2cf75118be239a83745761e64ff3a8f23dca..f8ec536a839b71a0ebacf179c6d8f561b5307849 100644 (file)
@@ -327,7 +327,7 @@ static int mail_transaction_log_file_create(struct mail_transaction_log *log,
 
        if (index->fd != -1) {
                index->log_locked = TRUE; /* kludging around assert.. */
-               if (mail_index_lock_exclusive(index, 0, 0, &lock_id) < 0) {
+               if (mail_index_lock_exclusive(index, &lock_id) < 0) {
                        (void)file_dotlock_delete(path, fd);
                        index->log_locked = FALSE;
                        return -1;
index 45f290c9265d2c1e5c32c5d12e23bf9bbab16981..10fb78f7ff419033a7d1dd2435e734d3d2d11342 100644 (file)
@@ -72,7 +72,8 @@ int mail_transaction_map(const struct mail_transaction_header *hdr,
                }
                break;
        }
-       case MAIL_TRANSACTION_EXPUNGE: {
+       case MAIL_TRANSACTION_EXPUNGE:
+       case MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT: {
                const struct mail_transaction_expunge *rec, *end;
 
                if (map->expunge == NULL)