]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dbox: If alt path is lost, fail with an error rather than rebuilding indexes.
authorTimo Sirainen <tss@iki.fi>
Thu, 21 Oct 2010 15:33:28 +0000 (16:33 +0100)
committerTimo Sirainen <tss@iki.fi>
Thu, 21 Oct 2010 15:33:28 +0000 (16:33 +0100)
This could be simply because alt storage is unmounted at the time and
rebuilding would just lose messages. If this error happens unintentionally,
it's still possible to fix it with "doveadm force-resync".

src/lib-storage/index/dbox-multi/mdbox-file.c
src/lib-storage/index/dbox-multi/mdbox-file.h
src/lib-storage/index/dbox-multi/mdbox-mail.c
src/lib-storage/index/dbox-multi/mdbox-purge.c
src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c
src/lib-storage/index/dbox-single/sdbox-file.c
src/lib-storage/index/dbox-single/sdbox-file.h
src/lib-storage/index/dbox-single/sdbox-mail.c
src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c
src/lib-storage/index/dbox-single/sdbox-sync.c

index 745c8672c3d92a5c87c076e5f5862aeb23eab95d..a13b39f53c7f01ed39600e0a44719e1fd3ce8da8 100644 (file)
@@ -183,6 +183,32 @@ mdbox_file_init_new_alt(struct mdbox_storage *storage)
        return mdbox_file_init_full(storage, 0, TRUE);
 }
 
+int mdbox_file_open(struct dbox_file *file, bool *deleted_r)
+{
+       struct mdbox_file *mfile = (struct mdbox_file *)file;
+       struct stat st;
+       int ret;
+
+       if ((ret = dbox_file_open(file, deleted_r)) <= 0 || !*deleted_r)
+               return ret;
+
+       /* file appears to be deleted. check if the alt path root even exists
+          to avoid reindexing errors if alt path isn't mounted currently */
+       if (stat(mfile->storage->alt_storage_dir, &st) == 0)
+               return 1;
+       else if (errno == ENOENT) {
+               mail_storage_set_critical(&file->storage->storage,
+                       "mdbox: User's alt path lost: %s",
+                       mfile->storage->alt_storage_dir);
+               return -1;
+       } else {
+               mail_storage_set_critical(&file->storage->storage,
+                       "stat(%s) failed: %m", mfile->storage->alt_storage_dir);
+               return -1;
+       }
+}
+
+
 int mdbox_file_assign_file_id(struct mdbox_file *file, uint32_t file_id)
 {
        const char *old_path;
index 9095cce745b7d5c02248a8af0fc404eeecf5acb3..7750de59c305f6308d782977645e871ec5015ca3 100644 (file)
@@ -16,6 +16,8 @@ mdbox_file_init(struct mdbox_storage *storage, uint32_t file_id);
 struct dbox_file *
 mdbox_file_init_new_alt(struct mdbox_storage *storage);
 
+int mdbox_file_open(struct dbox_file *file, bool *deleted_r);
+
 /* Assign file ID for a newly created file. */
 int mdbox_file_assign_file_id(struct mdbox_file *file, uint32_t file_id);
 
index da776836c6d27474490dc47d590281f8e31990a0..c67843bf7f39f1eac0a12bb3b8f13bd4e2cc1818 100644 (file)
@@ -129,7 +129,7 @@ int mdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r,
 
                if (!dbox_file_is_open(mail->open_file))
                        mail->imail.mail.stats_open_lookup_count++;
-               if (dbox_file_open(mail->open_file, &deleted) <= 0)
+               if (mdbox_file_open(mail->open_file, &deleted) <= 0)
                        return -1;
                if (deleted) {
                        /* either it's expunged now or moved to another file. */
index 33405d3684357ad78f798377d887e9682bbec607..8e5442c729be3be5e416604f35c94b2fc6091bbb 100644 (file)
@@ -658,7 +658,7 @@ int mdbox_purge(struct mail_storage *_storage)
        while (ret == 0 &&
               seq_range_array_iter_nth(&iter, i++, &file_id)) T_BEGIN {
                file = mdbox_file_init(storage, file_id);
-               if (dbox_file_open(file, &deleted) > 0 && !deleted) {
+               if (mdbox_file_open(file, &deleted) > 0 && !deleted) {
                        if (mdbox_file_purge(ctx, file) < 0)
                                ret = -1;
                } else {
index 68c2efe0e3a571c0c2c57a7ff3045fc9200405f1..e9541a4bd68e4bdb15c795fa1ca927cf852fea4c 100644 (file)
@@ -277,7 +277,7 @@ static int rebuild_add_file(struct mdbox_storage_rebuild_context *ctx,
        seq_range_array_add(&ctx->seen_file_ids, 0, file_id);
 
        file = mdbox_file_init(ctx->storage, file_id);
-       if ((ret = dbox_file_open(file, &deleted)) > 0 && !deleted)
+       if ((ret = mdbox_file_open(file, &deleted)) > 0 && !deleted)
                ret = rebuild_file_mails(ctx, file, file_id);
        if (ret == 0)
                i_error("mdbox rebuild: Failed to fix file %s/%s", dir, fname);
@@ -614,7 +614,7 @@ static int rebuild_restore_msg(struct mdbox_storage_rebuild_context *ctx,
        /* first see if message contains the mailbox it was originally
           saved to */
        file = mdbox_file_init(ctx->storage, msg->file_id);
-       ret = dbox_file_open(file, &deleted);
+       ret = mdbox_file_open(file, &deleted);
        if (ret > 0 && !deleted)
                ret = dbox_file_seek(file, msg->offset);
        if (ret > 0 && !deleted && dbox_file_metadata_read(file) > 0) {
index be15a67ce0d61894ce49fe719ba02746bac842df..6df975d7a6d94fb315eb69811b3cf21b1be79682 100644 (file)
@@ -73,6 +73,33 @@ void sdbox_file_free(struct dbox_file *file)
        dbox_file_free(file);
 }
 
+int sdbox_file_open(struct dbox_file *file, bool *deleted_r)
+{
+       struct sdbox_file *sfile = (struct sdbox_file *)file;
+       struct stat st;
+       const char *alt_root;
+       int ret;
+
+       if ((ret = dbox_file_open(file, deleted_r)) <= 0 || !*deleted_r)
+               return ret;
+
+       /* file appears to be deleted. check if the alt path root even exists
+          to avoid reindexing errors if alt path isn't mounted currently */
+       alt_root = mailbox_list_get_path(sfile->mbox->box.list, NULL,
+                                        MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX);
+       if (stat(alt_root, &st) == 0)
+               return 1;
+       else if (errno == ENOENT) {
+               mail_storage_set_critical(&file->storage->storage,
+                       "sdbox: User's alt path lost: %s", alt_root);
+               return -1;
+       } else {
+               mail_storage_set_critical(&file->storage->storage,
+                       "stat(%s) failed: %m", alt_root);
+               return -1;
+       }
+}
+
 int sdbox_file_get_attachments(struct dbox_file *file, const char **extrefs_r)
 {
        const char *line;
@@ -82,7 +109,7 @@ int sdbox_file_get_attachments(struct dbox_file *file, const char **extrefs_r)
        *extrefs_r = NULL;
 
        /* read the metadata */
-       ret = dbox_file_open(file, &deleted);
+       ret = sdbox_file_open(file, &deleted);
        if (ret > 0) {
                if (deleted)
                        return 0;
@@ -365,7 +392,7 @@ int sdbox_file_move(struct dbox_file *file, bool alt_path)
 
        /* file was successfully moved - reopen it */
        dbox_file_close(file);
-       if (dbox_file_open(file, &deleted) <= 0) {
+       if (sdbox_file_open(file, &deleted) <= 0) {
                mail_storage_set_critical(storage,
                        "dbox_file_move(%s): reopening file failed", dest_path);
                return -1;
index 30eb4f48786570485716af7cbf7d215f87f68e40..4a707cf9bab01d7a8c2f9472d8c8abc7c781c530 100644 (file)
@@ -19,6 +19,8 @@ struct dbox_file *sdbox_file_init(struct sdbox_mailbox *mbox, uint32_t uid);
 struct dbox_file *sdbox_file_create(struct sdbox_mailbox *mbox);
 void sdbox_file_free(struct dbox_file *file);
 
+int sdbox_file_open(struct dbox_file *file, bool *deleted_r);
+
 /* Get file's extrefs metadata. */
 int sdbox_file_get_attachments(struct dbox_file *file, const char **extrefs_r);
 /* Returns attachment path for this file, given the source path. The result is
index 0b573d910dbb3c02df9af8f9640c752d018d459e..1c34d6a4e3695dea15492968ea525ad3763c56ed 100644 (file)
@@ -43,7 +43,7 @@ static bool sdbox_mail_file_set(struct dbox_mail *mail)
                mail->open_file->refcount++;
 
                /* it doesn't have input stream yet */
-               ret = dbox_file_open(mail->open_file, &deleted);
+               ret = sdbox_file_open(mail->open_file, &deleted);
                i_assert(ret > 0);
                return TRUE;
        }
@@ -63,7 +63,7 @@ int sdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r,
        if (!sdbox_mail_file_set(mail)) {
                if (!dbox_file_is_open(mail->open_file))
                        mail->imail.mail.stats_open_lookup_count++;
-               if (dbox_file_open(mail->open_file, &deleted) <= 0)
+               if (sdbox_file_open(mail->open_file, &deleted) <= 0)
                        return -1;
                if (deleted) {
                        sdbox_mail_set_expunged(mail);
index b2f2e86f1355c7ec60981af50c77c4e91f88581b..eb7bbcbcd69f64d34a9256d6b9faa25ce21b9551 100644 (file)
@@ -32,7 +32,7 @@ static int sdbox_sync_add_file_index(struct dbox_sync_rebuild_context *ctx,
        bool deleted;
        int ret;
 
-       if ((ret = dbox_file_open(file, &deleted)) > 0) {
+       if ((ret = sdbox_file_open(file, &deleted)) > 0) {
                if (deleted)
                        return 0;
                ret = dbox_file_seek(file, 0);
index c3beab76c2749078e2702a6be38d93ea023ab504..b31518a89c197ae1bd877acc356a0baca5af020a 100644 (file)
@@ -18,7 +18,7 @@ dbox_sync_file_move_if_needed(struct dbox_file *file,
        if (move_to_alt != dbox_file_is_in_alt(file)) {
                /* move the file. if it fails, nothing broke so
                   don't worry about it. */
-               if (dbox_file_open(file, &deleted) > 0 && !deleted)
+               if (sdbox_file_open(file, &deleted) > 0 && !deleted)
                        (void)sdbox_file_move(file, move_to_alt);
        }
 }