]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Merged changes from v2.0 tree.
authorTimo Sirainen <tss@iki.fi>
Sun, 26 Jun 2011 16:34:00 +0000 (19:34 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 26 Jun 2011 16:34:00 +0000 (19:34 +0300)
1  2 
src/doveadm/doveadm-mail-index.c
src/lib-storage/index/index-sync-private.h
src/lib-storage/index/index-sync.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.h
src/plugins/fts/fts-storage.c

index 409797c4e82971ac7b00ea875be28e03fd52b61a,e942c194e4d1b041a8e97a172fe1b1ad4978c96b..d5c286c006a79bad0bbc3728c90ec9697b57397a
@@@ -164,11 -10,11 +10,9 @@@ static in
  cmd_index_box(const struct mailbox_info *info)
  {
        struct mailbox *box;
-       struct mailbox_metadata metadata;
-       enum cache_mask cache;
 -      const char *storage_name;
        int ret = 0;
  
 -      storage_name = mail_namespace_get_storage_name(info->ns, info->name);
 -      box = mailbox_alloc(info->ns->list, storage_name,
 +      box = mailbox_alloc(info->ns->list, info->name,
                            MAILBOX_FLAG_KEEP_RECENT |
                            MAILBOX_FLAG_IGNORE_ACLS);
  
index 47b7e249461d0a85af8382d55b96a9c88a793f94,b033640f3c6936fb74d787dfdce0dc353c553c88..3c9daa9176972f4d44bdf5d396424da4f7c488a1
@@@ -5,8 -5,6 +5,7 @@@
  
  struct index_mailbox_sync_context {
        struct mailbox_sync_context ctx;
-       enum mailbox_sync_flags flags;
 +
        struct mail_index_view_sync_ctx *sync_ctx;
        uint32_t messages_count;
  
index 01fe3544c55f18e0dacad98b0522207dd17027dc,8de7c6bf7af8d389dafa4a20dda63791fd2664d6..0a5b052a86b68b388ed08a39018c13f2ea6df3a0
@@@ -6,11 -6,17 +6,22 @@@
  #include "array.h"
  #include "index-sync-private.h"
  
 +struct index_storage_list_index_record {
 +      uint32_t size;
 +      uint32_t mtime;
 +};
 +
+ enum cache_mask {
+       CACHE_HDR               = 0x01,
+       CACHE_BODY              = 0x02,
+       CACHE_RECEIVED_DATE     = 0x04,
+       CACHE_SAVE_DATE         = 0x08,
+       CACHE_VIRTUAL_SIZE      = 0x10,
+       CACHE_PHYSICAL_SIZE     = 0x20,
+       CACHE_POP3_UIDL         = 0x40,
+       CACHE_GUID              = 0x80
+ };
  enum mail_index_sync_flags index_storage_get_sync_flags(struct mailbox *box)
  {
        enum mail_index_sync_flags sync_flags = 0;
@@@ -330,6 -336,123 +341,128 @@@ index_mailbox_expunge_unseen_recent(str
  #endif
  }
  
 -cache_fields_get(const struct mailbox_status *status, bool debug)
+ static enum cache_mask
 -      cache_fields = array_get(status->cache_fields, &count);
++cache_fields_get(const struct mailbox_metadata *metadata, bool debug)
+ {
+       const char *const *cache_fields;
+       unsigned int i, count;
+       enum cache_mask cache = 0;
 -static int cache_add(struct mailbox *box, const struct mailbox_status *status,
 -                   enum cache_mask cache)
++      cache_fields = array_get(metadata->cache_fields, &count);
+       for (i = 0; i < count; i++) {
+               if (strncmp(cache_fields[i], "hdr.", 4) == 0 ||
+                   strcmp(cache_fields[i], "date.sent") == 0 ||
+                   strcmp(cache_fields[i], "imap.envelope") == 0)
+                       cache |= CACHE_HDR;
+               else if (strcmp(cache_fields[i], "mime.parts") == 0 ||
+                        strcmp(cache_fields[i], "imap.body") == 0 ||
+                        strcmp(cache_fields[i], "imap.bodystructure") == 0)
+                       cache |= CACHE_BODY;
+               else if (strcmp(cache_fields[i], "date.received") == 0)
+                       cache |= CACHE_RECEIVED_DATE;
+               else if (strcmp(cache_fields[i], "date.save") == 0)
+                       cache |= CACHE_SAVE_DATE;
+               else if (strcmp(cache_fields[i], "size.virtual") == 0)
+                       cache |= CACHE_VIRTUAL_SIZE;
+               else if (strcmp(cache_fields[i], "size.physical") == 0)
+                       cache |= CACHE_PHYSICAL_SIZE;
+               else if (strcmp(cache_fields[i], "pop3.uidl") == 0)
+                       cache |= CACHE_POP3_UIDL;
+               else if (strcmp(cache_fields[i], "guid") == 0)
+                       cache |= CACHE_GUID;
+               else if (debug) {
+                       i_debug("Ignoring unknown cache field: %s",
+                               cache_fields[i]);
+               }
+       }
+       return cache;
+ }
 -                              mailbox_get_vname(box));
++static int cache_add(struct mailbox *box, enum cache_mask cache)
+ {
++      struct mailbox_status status;
+       struct mailbox_transaction_context *trans;
+       struct mail *mail;
+       uint32_t seq;
+       time_t date;
+       uoff_t size;
+       const char *str;
+       if (cache == 0) {
+               if (box->storage->set->mail_debug) {
+                       i_debug("%s: Nothing in mailbox cache, skipping",
 -      for (seq = status->messages; seq > 0; seq--) {
++                              box->vname);
+               }
+               return 0;
+       }
+       /* find the first message we need to index */
++      mailbox_get_open_status(box, STATUS_MESSAGES, &status);
+       trans = mailbox_transaction_begin(box, 0);
+       mail = mail_alloc(trans, 0, NULL);
 -              if (seq > status->messages) {
 -                      i_debug("%s: Cache is already up to date",
 -                              mailbox_get_vname(box));
++      for (seq = status.messages; seq > 0; seq--) {
+               mail_set_seq(mail, seq);
+               if (mail_is_cached(mail))
+                       break;
+       }
+       seq++;
+       if (box->storage->set->mail_debug) {
 -                              mailbox_get_vname(box),
 -                              seq, status->messages, cache);
++              if (seq > status.messages) {
++                      i_debug("%s: Cache is already up to date", box->vname);
+               } else {
+                       i_debug("%s: Caching mails seq=%u..%u cache=0x%x",
 -      for (; seq <= status->messages; seq++) {
++                              box->vname, seq, status.messages, cache);
+               }
+       }
 -              i_error("Commiting mailbox %s failed: %s",
 -                      mailbox_get_vname(box),
 -                      mail_storage_get_last_error(mailbox_get_storage(box), NULL));
++      for (; seq <= status.messages; seq++) {
+               mail_set_seq(mail, seq);
+               if ((cache & (CACHE_HDR | CACHE_BODY)) != 0)
+                       mail_parse(mail, (cache & CACHE_BODY) != 0);
+               if ((cache & CACHE_RECEIVED_DATE) != 0)
+                       (void)mail_get_received_date(mail, &date);
+               if ((cache & CACHE_SAVE_DATE) != 0)
+                       (void)mail_get_save_date(mail, &date);
+               if ((cache & CACHE_VIRTUAL_SIZE) != 0)
+                       (void)mail_get_virtual_size(mail, &size);
+               if ((cache & CACHE_PHYSICAL_SIZE) != 0)
+                       (void)mail_get_physical_size(mail, &size);
+               if ((cache & CACHE_POP3_UIDL) != 0) {
+                       (void)mail_get_special(mail, MAIL_FETCH_UIDL_BACKEND,
+                                              &str);
+               }
+               if ((cache & CACHE_GUID) != 0)
+                       (void)mail_get_special(mail, MAIL_FETCH_GUID, &str);
+       }
+       mail_free(&mail);
+       if (mailbox_transaction_commit(&trans) < 0) {
 -      struct mailbox_status status;
++              mail_storage_set_critical(box->storage,
++                      "Commiting mailbox %s failed: %s", box->vname,
++                      mailbox_get_last_error(box, NULL));
+               return -1;
+       }
+       return 0;
+ }
+ static int index_sync_precache(struct mailbox *box)
+ {
 -      mailbox_get_status(box, STATUS_MESSAGES | STATUS_CACHE_FIELDS, &status);
++      struct mailbox_metadata metadata;
+       enum cache_mask cache;
 -      cache = cache_fields_get(&status, box->storage->set->mail_debug);
 -      return cache_add(box, &status, cache);
++      if (mailbox_get_metadata(box, MAILBOX_METADATA_CACHE_FIELDS,
++                               &metadata) < 0) {
++              mail_storage_set_critical(box->storage,
++                      "Metadata lookup from mailbox %s failed: %s", box->vname,
++                      mailbox_get_last_error(box, NULL));
++              return -1;
++      }
++      cache = cache_fields_get(&metadata, box->storage->set->mail_debug);
++      return cache_add(box, cache);
+ }
  int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
                              struct mailbox_sync_status *status_r)
  {
Simple merge
index 142faed2a91dbba072b71fc120a3af29b9f75bc2,09214e8167f91adca1aa16407179ef7482c01e73..2e185ff5168b60d1892799773dc74a5aaa18e73e
@@@ -37,7 -35,7 +37,6 @@@ struct fts_mail 
  struct fts_storage_build_context {
        struct mail_search_context *search_ctx;
        struct mail_search_args *search_args;
--      struct mail *mail;
        struct fts_backend_build_context *build;
  
        struct timeval search_start_time, last_notify;
@@@ -146,7 -144,7 +145,8 @@@ static void fts_build_mail_header(struc
                str_append_c(ctx->headers, '\n');
  }
  
--static int fts_build_mail(struct fts_storage_build_context *ctx, uint32_t uid)
++static int
++fts_build_mail(struct fts_storage_build_context *ctx, struct mail *mail)
  {
        enum message_decoder_flags decoder_flags = MESSAGE_DECODER_FLAG_DTCASE;
        struct istream *input;
        bool skip_body = FALSE, body_part = FALSE;
        int ret;
  
--      ctx->uid = uid;
++      ctx->uid = mail->uid;
  
--      if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
++      if (mail_get_stream(mail, NULL, NULL, &input) < 0)
                return -1;
  
        prev_part = NULL;
        if (!skip_body && body_part)
                fts_backend_build_body_end(ctx->build);
        if (message_parser_deinit(&parser, &parts) < 0)
--              mail_set_cache_corrupted(ctx->mail, MAIL_FETCH_MESSAGE_PARTS);
++              mail_set_cache_corrupted(mail, MAIL_FETCH_MESSAGE_PARTS);
        message_decoder_deinit(&decoder);
  
        if (ret == 0) {
@@@ -526,7 -527,7 +526,7 @@@ static int fts_build_init(struct fts_se
  static int fts_build_deinit(struct fts_storage_build_context **_ctx)
  {
        struct fts_storage_build_context *ctx = *_ctx;
--      struct mailbox *box = ctx->mail->transaction->box;
++      struct mailbox *box = ctx->search_ctx->transaction->box;
        struct fts_mailbox *fbox = FTS_CONTEXT(box);
        struct mailbox_status status;
        int ret = 0;
  
        if (mailbox_search_deinit(&ctx->search_ctx) < 0)
                ret = -1;
-       ctx->mail = NULL;
 -      mail_free(&ctx->mail);
  
        if (fts_backend_build_deinit(&ctx->build) < 0)
                ret = -1;
        return ret;
  }
  
--static void fts_build_notify(struct fts_storage_build_context *ctx)
++static void
++fts_build_notify(struct fts_storage_build_context *ctx, uint32_t seq)
  {
--      struct mailbox *box = ctx->mail->transaction->box;
++      struct mailbox *box = ctx->search_ctx->transaction->box;
  
        if (ctx->last_notify.tv_sec == 0) {
                /* set the search time in here, in case a plugin
                seq_diff = range->seq2 - range->seq1;
  
                if (seq_diff != 0) {
--                      completed_frac = (double)(ctx->mail->seq - range->seq1) / seq_diff;
++                      completed_frac = (double)(seq - range->seq1) / seq_diff;
  
                        if (completed_frac >= 0.000001) {
                                unsigned int elapsed_msecs, est_total_msecs;
  
  static int fts_build_more(struct fts_storage_build_context *ctx)
  {
++      struct mail *mail = NULL;
        unsigned int count = 0;
        int ret;
  
--      if (ioloop_time - ctx->last_notify.tv_sec >=
--          FTS_BUILD_NOTIFY_INTERVAL_SECS)
--              fts_build_notify(ctx);
--
-       while (mailbox_search_next(ctx->search_ctx, &ctx->mail)) {
 -      while (mailbox_search_next(ctx->search_ctx, ctx->mail)) {
++      while (mailbox_search_next(ctx->search_ctx, &mail)) {
                T_BEGIN {
--                      ret = fts_build_mail(ctx, ctx->mail->uid);
++                      ret = fts_build_mail(ctx, mail);
                } T_END;
  
                if (ret < 0)
                        return 0;
        }
  
++      if (ioloop_time - ctx->last_notify.tv_sec >=
++          FTS_BUILD_NOTIFY_INTERVAL_SECS && mail != NULL)
++              fts_build_notify(ctx, mail->seq);
        return 1;
  }
  
@@@ -748,6 -732,29 +734,29 @@@ static int fts_mailbox_search_build_mor
                        }
                }
        }
 -                               struct mail *mail, bool *tryagain_r)
+       return ret;
+ }
+ static bool
+ fts_mailbox_search_next_nonblock(struct mail_search_context *ctx,
++                               struct mail **mail_r, bool *tryagain_r)
+ {
+       struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
+       struct fts_search_context *fctx = FTS_CONTEXT(ctx);
+       if (!fctx->build_initialized) {
+               /* we're still waiting for this process (but another command)
+                  to finish building the indexes */
+               if (!fts_try_build_init(ctx, fctx)) {
+                       *tryagain_r = TRUE;
+                       return FALSE;
+               }
+       }
+       if (fts_mailbox_search_build_more(ctx) == 0) {
+               *tryagain_r = TRUE;
+               return FALSE;
+       }
  
        /* if we're here, the indexes are either built or they're not used */
        return fbox->module_ctx.super.
@@@ -1113,6 -1119,50 +1122,49 @@@ fts_transaction_commit(struct mailbox_t
        return ret;
  }
  
 -      search_args->charset = "UTF-8";
+ static int fts_update(struct mailbox *box)
+ {
+       struct mailbox_transaction_context *t;
+       struct mail_search_args *search_args;
+       struct mail_search_arg *arg;
+       struct mail_search_context *ctx;
+       struct fts_search_context *fctx;
+       int ret = 0;
+       t = mailbox_transaction_begin(box, 0);
+       search_args = mail_search_build_init();
 -      ctx = mailbox_search_init(t, search_args, NULL);
+       mail_search_build_add_all(search_args);
+       arg = mail_search_build_add(search_args, SEARCH_BODY_FAST);
+       arg->value.str = "xyzzy";
++      ctx = mailbox_search_init(t, search_args, NULL, 0, NULL);
+       mail_search_args_unref(&search_args);
+       fctx = FTS_CONTEXT(ctx);
+       if (fctx->build_initialized) {
+               while ((ret = fts_mailbox_search_build_more(ctx)) == 0) ;
+       }
+       (void)mailbox_search_deinit(&ctx);
+       (void)mailbox_transaction_commit(&t);
+       return ret < 0 ? -1 : 0;
+ }
+ static int fts_sync_deinit(struct mailbox_sync_context *ctx,
+                          struct mailbox_sync_status *status_r)
+ {
+       struct mailbox *box = ctx->box;
+       struct fts_mailbox *fbox = FTS_CONTEXT(box);
+       bool precache;
+       precache = (ctx->flags & MAILBOX_SYNC_FLAG_PRECACHE) != 0;
+       if (fbox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
+               return -1;
+       ctx = NULL;
+       return !precache ? 0 : fts_update(box);
+ }
  static void fts_mailbox_init(struct mailbox *box, const char *env)
  {
        struct mailbox_vfuncs *v = box->vlast;