]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Only NOOP and CHECK will now always do a real mailbox sync. Other commands
authorTimo Sirainen <tss@iki.fi>
Sun, 15 Jun 2003 03:42:28 +0000 (06:42 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 15 Jun 2003 03:42:28 +0000 (06:42 +0300)
will also do it but no often than once in 5 seconds. Also with maildir we
don't anymore try to sync it before running commands since syncing is now
done automatically whenever we try to access a file that doesn't exist.

--HG--
branch : HEAD

29 files changed:
src/imap/cmd-append.c
src/imap/cmd-capability.c
src/imap/cmd-copy.c
src/imap/cmd-fetch.c
src/imap/cmd-search.c
src/imap/cmd-sort.c
src/imap/cmd-store.c
src/imap/cmd-thread.c
src/imap/commands-util.c
src/imap/commands-util.h
src/lib-index/mail-index-open.c
src/lib-index/mail-index.h
src/lib-index/maildir/maildir-index.h
src/lib-index/maildir/maildir-rebuild.c
src/lib-index/maildir/maildir-sync.c
src/lib-index/mbox/mbox-index.h
src/lib-index/mbox/mbox-rewrite.c
src/lib-index/mbox/mbox-sync.c
src/lib-storage/index/index-copy.c
src/lib-storage/index/index-expunge.c
src/lib-storage/index/index-fetch.c
src/lib-storage/index/index-search.c
src/lib-storage/index/index-status.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/index-sync.c
src/lib-storage/index/index-update-flags.c
src/lib-storage/index/maildir/maildir-copy.c
src/lib-storage/index/mbox/mbox-save.c
src/lib-storage/mail-storage.h

index f36e81cf36d4c981f099264b6796b128bff809a9..408db83e73b4a6c4d686ad113a73dfe06ca05c59 100644 (file)
@@ -207,7 +207,7 @@ int cmd_append(struct client *client)
        box->close(box);
 
        if (!failed) {
-               client_sync_full(client);
+               client_sync_full_fast(client);
                client_send_tagline(client, "OK Append completed.");
        }
        return TRUE;
index 10eeec52a5561dfccd5e5f163923d22a53c0d4d3..f2f12352c9f8186fb855ec5988f446cbafa6372a 100644 (file)
@@ -7,7 +7,7 @@ int cmd_capability(struct client *client)
 {
        client_send_line(client, "* CAPABILITY " CAPABILITY_STRING);
 
-       client_sync_full(client);
+       client_sync_full_fast(client);
        client_send_tagline(client, "OK Capability completed.");
        return TRUE;
 }
index 0f37341cb5e03e83207b4535381e47882097e448..8428a89178f252ba3cc8b90942e20e3a62a8fb27 100644 (file)
@@ -31,14 +31,14 @@ int cmd_copy(struct client *client)
        ret = client->mailbox->copy(client->mailbox, destbox,
                                    messageset, client->cmd_uid);
 
-       /* sync always - if COPY fails because of expunges they'll get
-          synced here */
-       client_sync_full(client);
-
-       if (ret)
+       if (ret) {
+               client_sync_full_fast(client);
                client_send_tagline(client, "OK Copy completed.");
-       else
+       } else {
+               /* if COPY fails because of expunges they'll get synced here */
+               client_sync_full(client);
                client_send_storage_error(client);
+       }
 
        destbox->close(destbox);
        return TRUE;
index 2dc87499cc10dbf31f144a1acfb986fde48d6515..871f7c6416da9e27813b1e823014397ffb1c3d20 100644 (file)
@@ -354,7 +354,7 @@ int cmd_fetch(struct client *client)
                if ((client_workarounds &
                     WORKAROUND_OE6_FETCH_NO_NEWMAIL) == 0) {
                        if (client->cmd_uid)
-                               client_sync_full(client);
+                               client_sync_full_fast(client);
                        else
                                client_sync_without_expunges(client);
                }
index 2c17d0d292f99c05d6aad950925820973627406a..b4aa7b14803a45af7b8cfdcfb634c51583a9b752 100644 (file)
@@ -92,7 +92,7 @@ int cmd_search(struct client *client)
                client_send_tagline(client, t_strconcat("NO ", error, NULL));
        } else if (imap_search(client, charset, sargs)) {
                if (client->cmd_uid)
-                       client_sync_full(client);
+                       client_sync_full_fast(client);
                else
                        client_sync_without_expunges(client);
                client_send_tagline(client, "OK Search completed.");
index 203b4dac3c317c5d60acee3bb9f9e613bda1c42c..16d17e24f684a8a0f718b0b1a937d0dad9f0da26 100644 (file)
@@ -123,7 +123,7 @@ int cmd_sort(struct client *client)
        } else if (imap_sort(client, charset, sargs, sorting)) {
                /* NOTE: syncing is allowed when returning UIDs */
                if (client->cmd_uid)
-                       client_sync_full(client);
+                       client_sync_full_fast(client);
                else
                        client_sync_without_expunges(client);
                client_send_tagline(client, "OK Sort completed.");
index 328d9fd4d902dabee3d19e5b5439b95904b0db21..9cb639af0d70ca1a1d233b93ffdb0670b554baac 100644 (file)
@@ -75,7 +75,7 @@ int cmd_store(struct client *client)
                                          client->cmd_uid, &flags,
                                          modify_type, !silent, &all_found)) {
                if (client->cmd_uid)
-                       client_sync_full(client);
+                       client_sync_full_fast(client);
                else
                        client_sync_without_expunges(client);
                client_send_tagline(client, all_found ? "OK Store completed." :
index 9fc005317c265481d940b4d576a9a8459c3aa4ec..b191d79404fadec4904eb990dbcbb35e1c66d29c 100644 (file)
@@ -65,7 +65,7 @@ int cmd_thread(struct client *client)
        } else if (imap_thread(client, charset, sargs, threading)) {
                /* NOTE: syncing is allowed when returning UIDs */
                if (client->cmd_uid)
-                       client_sync_full(client);
+                       client_sync_full_fast(client);
                else
                        client_sync_without_expunges(client);
                client_send_tagline(client, "OK Search completed.");
index 5f487f378d02a569c087c75b2f040ebe6814fbb6..4da8155d44551d7c63d965589aea98ff8bec3c7d 100644 (file)
@@ -94,7 +94,16 @@ int client_verify_open_mailbox(struct client *client)
 void client_sync_full(struct client *client)
 {
        if (client->mailbox != NULL) {
-               if (!client->mailbox->sync(client->mailbox, TRUE))
+               if (!client->mailbox->sync(client->mailbox, 0))
+                        client_send_untagged_storage_error(client);
+       }
+}
+
+void client_sync_full_fast(struct client *client)
+{
+       if (client->mailbox != NULL) {
+               if (!client->mailbox->sync(client->mailbox,
+                                          MAIL_SYNC_FLAG_FAST))
                         client_send_untagged_storage_error(client);
        }
 }
@@ -102,7 +111,9 @@ void client_sync_full(struct client *client)
 void client_sync_without_expunges(struct client *client)
 {
        if (client->mailbox != NULL) {
-               if (!client->mailbox->sync(client->mailbox, FALSE))
+               if (!client->mailbox->sync(client->mailbox,
+                                           MAIL_SYNC_FLAG_NO_EXPUNGES |
+                                          MAIL_SYNC_FLAG_FAST))
                        client_send_untagged_storage_error(client);
        }
 }
index 6202d42ab3ea33bf68ef3bcf97dec19c5b7e8f52..cdc230c108b3bb62946ba085e005826ce59b2c23 100644 (file)
@@ -20,6 +20,9 @@ int client_verify_open_mailbox(struct client *client);
    FETCH FLAGS, EXISTS and RECENT responses. */
 void client_sync_full(struct client *client);
 
+/* Synchronize fast. */
+void client_sync_full_fast(struct client *client);
+
 /* Synchronize all but expunges with client. */
 void client_sync_without_expunges(struct client *client);
 
index c6b5ec33e1d720303b14fd2ac54b85ad6e622344..09e47afb51fc3c1bf5427fe7159c2f08e48671c4 100644 (file)
@@ -136,7 +136,8 @@ static int index_open_and_fix(struct mail_index *index,
        if (!rebuilt) {
                /* sync ourself. do it before updating cache and compression
                   which may happen because of this. */
-               if (!index->sync_and_lock(index, MAIL_LOCK_SHARED, NULL) &&
+               if (!index->sync_and_lock(index, FALSE,
+                                         MAIL_LOCK_SHARED, NULL) &&
                    !index->nodiskspace)
                        return FALSE;
 
index 33ab950db6405f33366e5053e5fe3c808b5648ca..e72db06e8ee4007fb45acd8069bce2ba73225a1d 100644 (file)
@@ -247,8 +247,10 @@ struct mail_index {
           lock when calling this function. The data_lock_type specifies what
           lock should be set to data file (mbox file). This function may
           leave the index in ANY locking state. If changes is non-NULL, it's
-          set to TRUE if any changes were noticed. */
-       int (*sync_and_lock)(struct mail_index *index,
+          set to TRUE if any changes were noticed. If minimal_sync is TRUE,
+          we do as little as possible to get data file locked (ie. noop with
+          maildir). */
+       int (*sync_and_lock)(struct mail_index *index, int minimal_sync,
                             enum mail_lock_type data_lock_type, int *changes);
 
        /* Returns the index header (never fails). The index needs to be
index c58b7a55ba178910a26391a876821f45031c38d1..3d0d192427cf55c964bd7ab07da73276ffbe1ef2 100644 (file)
@@ -30,7 +30,7 @@ const char *maildir_filename_set_flags(const char *fname,
 int maildir_index_rebuild(struct mail_index *index);
 int maildir_index_sync_readonly(struct mail_index *index,
                                const char *fname, int *found);
-int maildir_index_sync(struct mail_index *index,
+int maildir_index_sync(struct mail_index *index, int minimal_sync,
                       enum mail_lock_type lock_type, int *changes);
 
 int maildir_index_append_file(struct mail_index *index, const char *dir,
index f031c33140af096f43ce84bb51d26b8c282b2492..23604ab86d401516e1110db978205adfe208ab59 100644 (file)
@@ -44,7 +44,7 @@ int maildir_index_rebuild(struct mail_index *index)
        }
 
        /* read the mails by syncing */
-       if (!index->sync_and_lock(index, MAIL_LOCK_UNLOCK, NULL))
+       if (!index->sync_and_lock(index, FALSE, MAIL_LOCK_UNLOCK, NULL))
                return FALSE;
 
        /* rebuild is complete - remove the flag */
index c393e986c0096fd39211541ed50ec5508f1d5160..9ad7517690444ff22680bedc1a648f3512c8b251 100644 (file)
@@ -1337,7 +1337,7 @@ int maildir_index_sync_readonly(struct mail_index *index,
        return ret;
 }
 
-int maildir_index_sync(struct mail_index *index,
+int maildir_index_sync(struct mail_index *index, int minimal_sync,
                       enum mail_lock_type data_lock_type __attr_unused__,
                       int *changes)
 {
@@ -1349,6 +1349,9 @@ int maildir_index_sync(struct mail_index *index,
        if (changes != NULL)
                *changes = FALSE;
 
+       if (minimal_sync)
+               return TRUE;
+
        ctx = maildir_sync_context_new(index);
        ret = maildir_index_sync_context(ctx, changes);
         maildir_index_sync_deinit(ctx);
index 4d9b44bc85594c2a847b5bf6889b01c02e6c927e..7ebde0e74e188d019384ee3f43ed42527ef52b2f 100644 (file)
@@ -56,7 +56,7 @@ struct mail_index *
 mbox_index_alloc(const char *mbox_path, const char *index_dir,
                 const char *control_dir);
 int mbox_index_rebuild(struct mail_index *index);
-int mbox_index_sync(struct mail_index *index,
+int mbox_index_sync(struct mail_index *index, int minimal_sync,
                    enum mail_lock_type lock_type, int *changes);
 int mbox_sync_full(struct mail_index *index);
 struct istream *mbox_open_mail(struct mail_index *index,
index 53539356beacb028eef52eea7a77de29374a2734..d8c253966e49cfab54871914d412afc562fa5f53 100644 (file)
@@ -600,8 +600,8 @@ int mbox_index_rewrite(struct mail_index *index)
                        if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
                                break;
 
-                       if (!index->sync_and_lock(index, MAIL_LOCK_EXCLUSIVE,
-                                                 NULL))
+                       if (!index->sync_and_lock(index, FALSE,
+                                                 MAIL_LOCK_EXCLUSIVE, NULL))
                                break;
                }
 
index b975db7e02e364a6d762aa972dc9ab4c40eaff72..6153d75592a2e2d476331b55c68ddf71583f2634 100644 (file)
@@ -65,7 +65,7 @@ static int mbox_lock_and_sync_full(struct mail_index *index,
        return mbox_sync_full(index);
 }
 
-int mbox_index_sync(struct mail_index *index,
+int mbox_index_sync(struct mail_index *index, int minimal_sync __attr_unused__,
                    enum mail_lock_type data_lock_type, int *changes)
 {
        struct stat st;
index d6e0224bb95eb025ac3e91b63dd4640d7822b0fa..4fed36dd04a685adbeeb94ea67f02e7e6481748b 100644 (file)
@@ -64,7 +64,8 @@ int index_storage_copy(struct mailbox *box, struct mailbox *destbox,
                if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
                        return FALSE;
        } else {
-               if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_SHARED))
+               if (!index_storage_sync_and_lock(ibox, TRUE, TRUE,
+                                                MAIL_LOCK_SHARED))
                        return FALSE;
        }
 
index 1b475617daeb4efe745c433da0480371198b1841..afa7223c2f34f61e09ccb6d75b7126657ccf50c0 100644 (file)
@@ -78,7 +78,8 @@ int index_storage_expunge(struct mailbox *box, int notify)
        if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
                return FALSE;
 
-       if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_EXCLUSIVE))
+       if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
+                                        MAIL_LOCK_EXCLUSIVE))
                return FALSE;
 
        /* modifylog must be marked synced before expunging
index 5b74cf7e79227439699052dca61bda53115d51cc..0fb82ba7157d2b349df2d474220ac277d3dc8d15 100644 (file)
@@ -42,7 +42,8 @@ index_storage_fetch_init(struct mailbox *box,
 
        check_mail = (client_workarounds &
                      WORKAROUND_OE6_FETCH_NO_NEWMAIL) == 0;
-       if (!index_storage_sync_and_lock(ibox, check_mail, MAIL_LOCK_SHARED))
+       if (!index_storage_sync_and_lock(ibox, check_mail, TRUE,
+                                        MAIL_LOCK_SHARED))
                return NULL;
 
        if (update_seen != NULL && *update_seen &&
index b44fc8f34869962e2746c30b628d601320cbbd42..eb32e18ddb01356e5e43c494ad45f3eda09ba3df 100644 (file)
@@ -926,7 +926,7 @@ index_storage_search_init(struct mailbox *box, const char *charset,
                return NULL;
        }
 
-       if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_SHARED))
+       if (!index_storage_sync_and_lock(ibox, TRUE, TRUE, MAIL_LOCK_SHARED))
                return NULL;
 
        ctx = i_new(struct mail_search_context, 1);
index 91e10b8d182506f6f9671a27902e2c3860166ea3..f3099b21c18c19daad663081dec00347605f9b0e 100644 (file)
@@ -89,7 +89,8 @@ int index_storage_get_status(struct mailbox *box,
        if ((items & STATUS_MESSAGE_COUNTS) != 0) {
                /* if we're doing STATUS for selected mailbox, we have to sync
                   it first or STATUS reply may give different data */
-               if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_UNLOCK))
+               if (!index_storage_sync_and_lock(ibox, TRUE, FALSE,
+                                                MAIL_LOCK_UNLOCK))
                        return FALSE;
 
                if (!index_storage_sync_modifylog(ibox, FALSE)) {
index f2bbab5c1ec74197df33b775cb605ff0f30f2260..014d97c59abd8d7835b54c64ae631caa3d7b8436 100644 (file)
@@ -52,7 +52,8 @@ index_storage_init(struct mail_storage *storage, struct mailbox *box,
                   int readonly, int fast);
 int index_storage_close(struct mailbox *box);
 
-int index_storage_sync_and_lock(struct index_mailbox *ibox, int sync_size,
+int index_storage_sync_and_lock(struct index_mailbox *ibox,
+                               int sync_size, int minimal_sync,
                                enum mail_lock_type data_lock_type);
 int index_storage_sync_modifylog(struct index_mailbox *ibox, int hide_deleted);
 
@@ -82,7 +83,7 @@ int index_storage_expunge(struct mailbox *box, int notify);
 int index_storage_get_status(struct mailbox *box,
                             enum mailbox_status_items items,
                             struct mailbox_status *status);
-int index_storage_sync(struct mailbox *box, int sync_expunges);
+int index_storage_sync(struct mailbox *box, enum mail_sync_flags flags);
 int index_storage_update_flags(struct mailbox *box, const char *messageset,
                               int uidset, const struct mail_full_flags *flags,
                               enum modify_type modify_type, int notify,
index 2d2d3eb33d7587595506f456ee31b291eaab3f63..4b9206c4656359bbab93d8639d47190bbd8d30ee 100644 (file)
@@ -7,6 +7,9 @@
 #include "mail-modifylog.h"
 #include "mail-custom-flags.h"
 
+/* How often to do full sync when fast sync flag is set. */
+#define MAILBOX_FULL_SYNC_INTERVAL 5
+
 static void index_storage_sync_size(struct index_mailbox *ibox)
 {
        struct mail_storage *storage = ibox->box.storage;
@@ -29,7 +32,8 @@ static void index_storage_sync_size(struct index_mailbox *ibox)
        }
 }
 
-int index_storage_sync_and_lock(struct index_mailbox *ibox, int sync_size,
+int index_storage_sync_and_lock(struct index_mailbox *ibox,
+                               int sync_size, int minimal_sync,
                                enum mail_lock_type data_lock_type)
 {
        struct mail_storage *storage = ibox->box.storage;
@@ -39,7 +43,8 @@ int index_storage_sync_and_lock(struct index_mailbox *ibox, int sync_size,
         set_shared_lock = ibox->index->lock_type != MAIL_LOCK_EXCLUSIVE;
 
         index_storage_init_lock_notify(ibox);
-       failed = !index->sync_and_lock(index, data_lock_type, &changes);
+       failed = !index->sync_and_lock(index, minimal_sync,
+                                      data_lock_type, &changes);
        ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
 
        if (!failed) {
@@ -209,19 +214,29 @@ int index_storage_sync_modifylog(struct index_mailbox *ibox, int hide_deleted)
        return TRUE;
 }
 
-int index_storage_sync(struct mailbox *box, int sync_expunges)
+int index_storage_sync(struct mailbox *box, enum mail_sync_flags flags)
 {
        struct index_mailbox *ibox = (struct index_mailbox *) box;
        int ret;
 
-       ibox->sync_last_check = ioloop_time;
+       if ((flags & MAIL_SYNC_FLAG_FAST) == 0 ||
+           ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
+               ibox->sync_last_check = ioloop_time;
 
-       if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_UNLOCK))
-               return FALSE;
+               if (!index_storage_sync_and_lock(ibox, FALSE, FALSE,
+                                                MAIL_LOCK_UNLOCK))
+                       return FALSE;
+       } else {
+               /* check only modify log */
+               if (!index_storage_lock(ibox, MAIL_LOCK_SHARED)) {
+                       (void)index_storage_lock(ibox, MAIL_LOCK_UNLOCK);
+                       return FALSE;
+               }
+       }
 
        /* FIXME: we could sync flags always, but expunges in the middle
           could make it a bit more difficult and slower */
-       if (sync_expunges ||
+       if ((flags & MAIL_SYNC_FLAG_NO_EXPUNGES) == 0 ||
            mail_modifylog_get_expunge_count(ibox->index->modifylog) == 0)
                ret = index_storage_sync_modifylog(ibox, FALSE);
        else
index 4e4ae102c249b684ff55e609519add009671b714..255ba363be4f5a503143dada5a23e7c67cf3a15b 100644 (file)
@@ -83,7 +83,7 @@ int index_storage_update_flags(struct mailbox *box, const char *messageset,
        if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
                return FALSE;
 
-       if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_UNLOCK))
+       if (!index_storage_sync_and_lock(ibox, TRUE, TRUE, MAIL_LOCK_UNLOCK))
                return FALSE;
 
        mail_flags &= ~MAIL_RECENT; /* \Recent can't be changed */
index a17ddb299d6dea174cfb878a7127aec6891c7e35..43ceaa81919e91b8aa416b7eeda8aa71fa7ba71b 100644 (file)
@@ -151,7 +151,7 @@ static int copy_with_hardlinks(struct index_mailbox *src,
         struct messageset_context *ctx;
        int exdev, ret, ret2;
 
-       if (!index_storage_sync_and_lock(src, TRUE, MAIL_LOCK_SHARED))
+       if (!src->index->set_lock(src->index, MAIL_LOCK_SHARED))
                return -1;
 
        ctx = index_messageset_init(src, messageset, uidset, FALSE);
index 810236a414167fb2ef9113ea5af7c75accabd297..e8815469e3693b663c55614d428a0a2c9cf9eff8 100644 (file)
@@ -325,7 +325,8 @@ mbox_storage_save_init(struct mailbox *box, int transaction)
                return NULL;
        }
 
-       if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_EXCLUSIVE))
+       if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
+                                        MAIL_LOCK_EXCLUSIVE))
                return NULL;
 
        ctx = i_new(struct mail_save_context, 1);
index 9c5382ba132da7af896ef9189cd71edd3fc73273..08f88a73c964302bdfb745786f2ba2e74a9c2d6f 100644 (file)
@@ -93,6 +93,11 @@ enum mail_fetch_field {
        MAIL_FETCH_IMAP_ENVELOPE        = 0x4000
 };
 
+enum mail_sync_flags {
+       MAIL_SYNC_FLAG_NO_EXPUNGES      = 0x01,
+       MAIL_SYNC_FLAG_FAST             = 0x02
+};
+
 enum client_workarounds {
        WORKAROUND_OE6_FETCH_NO_NEWMAIL = 0x01,
        WORKAROUND_OUTLOOK_IDLE         = 0x02
@@ -225,9 +230,8 @@ struct mailbox {
        int (*get_status)(struct mailbox *box, enum mailbox_status_items items,
                          struct mailbox_status *status);
 
-       /* Synchronize the mailbox. If sync_expunges is FALSE, everything
-          but expunges are synced. */
-       int (*sync)(struct mailbox *box, int sync_expunges);
+       /* Synchronize the mailbox. */
+       int (*sync)(struct mailbox *box, enum mail_sync_flags flags);
 
        /* Synchronize mailbox in background. It's done until this function is
           called with sync_type = MAILBOX_SYNC_NONE */