]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Replace MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE with explicit mail_user_au...
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 23 Mar 2017 12:15:49 +0000 (14:15 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 27 Mar 2017 10:04:38 +0000 (13:04 +0300)
This allows better control of which users are being autoexpunged. This
patch changes behavior at least in two ways now:

1) After shared folder access, the owner user isn't autoexpunged at deinit.
Although this is a bit questionable of whether it should be or not.

2) LMTP's quota check at RCPT TO stage doesn't trigger autoexpunging.

src/imap/imap-client.c
src/imap/main.c
src/lib-storage/mail-storage-service.c
src/lib-storage/mail-storage-service.h
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h
src/lmtp/commands.c
src/lmtp/main.c
src/pop3/main.c
src/pop3/pop3-client.c

index c16bf8c02e0c3745c2e3c61fe7a26f925ad2cb8b..1e19e3e1d81e96e70481804db681d8604d2834f4 100644 (file)
@@ -19,6 +19,7 @@
 #include "mail-error.h"
 #include "mail-namespace.h"
 #include "mail-storage-service.h"
+#include "mail-autoexpunge.h"
 #include "imap-state.h"
 #include "imap-search.h"
 #include "imap-notify.h"
@@ -453,10 +454,13 @@ static void client_default_destroy(struct client *client, const char *reason)
        /* i/ostreams are already closed at this stage, so fd can be closed */
        fd_close_maybe_stdio(&client->fd_in, &client->fd_out);
 
-       /* refresh proctitle before a potentially long-running user unref */
+       /* Autoexpunging might run for a long time. Disconnect the client
+          before it starts, and refresh proctitle so it's clear that it's
+          doing autoexpunging. We've also sent DISCONNECT to anvil already,
+          because this is background work and shouldn't really be counted
+          as an active IMAP session for the user. */
        imap_refresh_proctitle();
-       /* Free the user after client is already disconnected. It may start
-          some background work like autoexpunging. */
+       mail_user_autoexpunge(client->user);
        mail_user_unref(&client->user);
 
        /* free the i/ostreams after mail_user_unref(), which could trigger
index 5c85394eac7838d794693fac23b3f56c50a81d60..a5c7f718ae91576f061d6d974f7b76c8b3b76439 100644 (file)
@@ -374,8 +374,7 @@ int main(int argc, char *argv[])
        };
        struct master_login_settings login_set;
        enum master_service_flags service_flags = 0;
-       enum mail_storage_service_flags storage_service_flags =
-               MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE;
+       enum mail_storage_service_flags storage_service_flags = 0;
        const char *username = NULL, *auth_socket_path = "auth-master";
        int c;
 
index 631f254d21ccc6f0126c540b6a82eb6f544764fd..de30e3941975d9a7d2b306422d33246a8503cb24 100644 (file)
@@ -678,8 +678,6 @@ mail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
        }
        mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL :
                p_strarray_dup(mail_user->pool, user->input.userdb_fields);
-       mail_user->autoexpunge_enabled =
-               (user->flags & MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE) != 0;
        
        mail_set = mail_user_set_get_storage_set(mail_user);
 
index 7816bf044964e1a13487a738bdcbc5718dc9a3a5..e4caef84bb37e6e656fdb8df80c58d9005b6aa0d 100644 (file)
@@ -34,8 +34,6 @@ enum mail_storage_service_flags {
        MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS          = 0x400,
        /* Don't create namespaces, only the user. */
        MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES         = 0x800,
-       /* Enable autoexpunging at deinit. */
-       MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE           = 0x1000
 };
 
 struct mail_storage_service_input {
index d4c36cffa020acff444f89cd817712f51057a0d3..51d3cab82862d8d8859eba8e02ba191c79bd31ef 100644 (file)
@@ -189,9 +189,6 @@ void mail_user_unref(struct mail_user **_user)
                return;
        }
 
-       if (user->autoexpunge_enabled && user->namespaces_created)
-               mail_user_autoexpunge(user);
-
        user->deinitializing = TRUE;
 
        /* call deinit() with refcount=1, otherwise we may assert-crash in
index 5af969d9b23f37ab10f6f03e5bc1240c4a02ecad..81b31c78b8f0eebf0c66fdf1f6cd98a9aaf38665 100644 (file)
@@ -95,8 +95,6 @@ struct mail_user {
        unsigned int admin:1;
        /* Enable all statistics gathering */
        unsigned int stats_enabled:1;
-       /* Enable autoexpunging at deinit. */
-       unsigned int autoexpunge_enabled:1;
        /* This session was restored (e.g. IMAP unhibernation) */
        unsigned int session_restored:1;
 };
index 457fa38b494461b3d27940a291f31e26158c7de1..a93763664845994720294231d94806f8078f9915 100644 (file)
@@ -27,6 +27,7 @@
 #include "index/raw/raw-storage.h"
 #include "lda-settings.h"
 #include "lmtp-settings.h"
+#include "mail-autoexpunge.h"
 #include "mail-namespace.h"
 #include "mail-deliver.h"
 #include "main.h"
@@ -945,8 +946,10 @@ static bool client_deliver_next(struct client *client, struct mail *src_mail,
                if (ret == 0)
                        return TRUE;
                /* failed. try the next one. */
-               if (client->state.dest_user != NULL)
+               if (client->state.dest_user != NULL) {
+                       mail_user_autoexpunge(client->state.dest_user);
                        mail_user_unref(&client->state.dest_user);
+               }
        }
        return FALSE;
 }
@@ -1034,9 +1037,10 @@ client_input_data_write_local(struct client *client, struct istream *input)
        src_mail = client->state.raw_mail;
        while (client_deliver_next(client, src_mail, session)) {
                if (client->state.first_saved_mail == NULL ||
-                   client->state.first_saved_mail == src_mail)
+                   client->state.first_saved_mail == src_mail) {
+                       mail_user_autoexpunge(client->state.dest_user);
                        mail_user_unref(&client->state.dest_user);
-               else {
+               else {
                        /* use the first saved message to save it elsewhere too.
                           this might allow hard linking the files. */
                        client->state.dest_user = NULL;
@@ -1065,6 +1069,7 @@ client_input_data_write_local(struct client *client, struct istream *input)
                mail_free(&mail);
                mailbox_transaction_rollback(&trans);
                mailbox_free(&box);
+               mail_user_autoexpunge(user);
                mail_user_unref(&user);
        }
 
index 1ab4c3f9f3e3a972fa194e7e7ab4782b6a71c850..9a8e034a7f84c95e53d2fa17a14dda704a280452 100644 (file)
@@ -88,8 +88,7 @@ int main(int argc, char *argv[])
                MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP |
                MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP |
                MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
-               MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT |
-               MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE;
+               MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT;
        int c;
 
        if (IS_STANDALONE()) {
index 685eeb011c157cdaa7584c60bd2078f25db6cd9a..cafe51ac6c4842bc0250478894ea1196f940b7c5 100644 (file)
@@ -215,8 +215,7 @@ int main(int argc, char *argv[])
        };
        struct master_login_settings login_set;
        enum master_service_flags service_flags = 0;
-       enum mail_storage_service_flags storage_service_flags =
-               MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE;
+       enum mail_storage_service_flags storage_service_flags = 0;
        const char *username = NULL, *auth_socket_path = "auth-master";
        int c;
 
index 9cde282d4b0873cccf5a2b93e5ac54e74028051c..c9b5eec247f253a4bf85463aa695f18af04df495 100644 (file)
@@ -17,6 +17,7 @@
 #include "master-service.h"
 #include "mail-storage.h"
 #include "mail-storage-service.h"
+#include "mail-autoexpunge.h"
 #include "pop3-commands.h"
 #include "mail-search-build.h"
 #include "mail-namespace.h"
@@ -648,8 +649,13 @@ static void client_default_destroy(struct client *client, const char *reason)
 
        fd_close_maybe_stdio(&client->fd_in, &client->fd_out);
 
-       /* refresh proctitle before a potentially long-running user unref */
+       /* Autoexpunging might run for a long time. Disconnect the client
+          before it starts, and refresh proctitle so it's clear that it's
+          doing autoexpunging. We've also sent DISCONNECT to anvil already,
+          because this is background work and shouldn't really be counted
+          as an active POP3 session for the user. */
        pop3_refresh_proctitle();
+       mail_user_autoexpunge(client->user);
        mail_user_unref(&client->user);
        mail_storage_service_user_unref(&client->service_user);