]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Fixed syncing renaming mailboxes with children.
authorTimo Sirainen <tss@iki.fi>
Thu, 13 Jun 2013 21:23:45 +0000 (00:23 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 13 Jun 2013 21:23:45 +0000 (00:23 +0300)
So that the childrens' rename timestamps are at least as high as their
parents'.

src/doveadm/dsync/dsync-mailbox-tree-sync.c
src/doveadm/dsync/test-dsync-mailbox-tree-sync.c

index 2cf7bc276eff77ef88979d7b34cb80f6c9020f65..7f80e693f684f52fdf3f1f5984654ba726450a10 100644 (file)
@@ -1140,6 +1140,20 @@ static void sync_mailbox_dirs(struct dsync_mailbox_tree_sync_ctx *ctx)
                                &ctx->remote_tree->root);
 }
 
+static void
+dsync_mailbox_tree_update_child_timestamps(struct dsync_mailbox_node *node,
+                                          time_t parent_timestamp)
+{
+       time_t ts;
+
+       if (node->last_renamed_or_created < parent_timestamp)
+               node->last_renamed_or_created = parent_timestamp;
+       ts = node->last_renamed_or_created;
+
+       for (node = node->first_child; node != NULL; node = node->next)
+               dsync_mailbox_tree_update_child_timestamps(node, ts);
+}
+
 struct dsync_mailbox_tree_sync_ctx *
 dsync_mailbox_trees_sync_init(struct dsync_mailbox_tree *local_tree,
                              struct dsync_mailbox_tree *remote_tree,
@@ -1166,6 +1180,8 @@ dsync_mailbox_trees_sync_init(struct dsync_mailbox_tree *local_tree,
        ignore_deletes = sync_type == DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_REMOTE;
        sync_tree_sort_and_delete_mailboxes(ctx, local_tree, ignore_deletes);
 
+       dsync_mailbox_tree_update_child_timestamps(&local_tree->root, 0);
+       dsync_mailbox_tree_update_child_timestamps(&remote_tree->root, 0);
        while (sync_rename_mailboxes(ctx, &local_tree->root, &remote_tree->root)) ;
        while (sync_rename_temp_mailboxes(ctx, local_tree, &local_tree->root)) ;
        while (sync_rename_temp_mailboxes(ctx, remote_tree, &remote_tree->root)) ;
index a86f164c41c15f8c23a43551409b883dc3fd7660..1b8875c0c5562e7ef7ebca544583d77159546f91 100644 (file)
@@ -154,9 +154,10 @@ static void trees_dump(struct dsync_mailbox_tree *tree1,
        nodes_dump(tree2->root.first_child, 1);
 }
 
-static void test_trees(struct dsync_mailbox_tree *tree1,
-                      struct dsync_mailbox_tree *tree2)
+static void test_trees_nofree(struct dsync_mailbox_tree *tree1,
+                             struct dsync_mailbox_tree **_tree2)
 {
+       struct dsync_mailbox_tree *tree2 = *_tree2;
        struct dsync_mailbox_tree *orig_tree1, *orig_tree2;
        struct dsync_mailbox_tree_sync_ctx *ctx;
        struct dsync_mailbox_node *dup_node1, *dup_node2;
@@ -201,12 +202,18 @@ static void test_trees(struct dsync_mailbox_tree *tree1,
                trees_dump(tree1, orig_tree1);
        }
 
-       dsync_mailbox_tree_deinit(&tree1);
-       dsync_mailbox_tree_deinit(&tree2);
+       dsync_mailbox_tree_deinit(_tree2);
        dsync_mailbox_tree_deinit(&orig_tree1);
        dsync_mailbox_tree_deinit(&orig_tree2);
 }
 
+static void test_trees(struct dsync_mailbox_tree *tree1,
+                      struct dsync_mailbox_tree *tree2)
+{
+       test_trees_nofree(tree1, &tree2);
+       dsync_mailbox_tree_deinit(&tree1);
+}
+
 static void test_dsync_mailbox_tree_sync_creates(void)
 {
        static const char *common_nodes[] = { "foo", "foo/bar", NULL };
@@ -600,9 +607,32 @@ static void test_dsync_mailbox_tree_sync_renames19(void)
        test_end();
 }
 
+static void test_dsync_mailbox_tree_sync_renames20(void)
+{
+       struct dsync_mailbox_tree *tree1, *tree2;
+
+       test_begin("dsync mailbox tree sync renames 20");
+       tree1 = dsync_mailbox_tree_init('/', '_');
+       tree2 = dsync_mailbox_tree_init('/', '_');
+
+       node_create(tree1, 1, "1", 0);
+       node_create(tree1, 2, "0", 0);
+       node_create(tree1, 3, "0/2", 0);
+       /* rename 0 -> 1/0 */
+       node_create(tree2, 1, "1", 0);
+       node_create(tree2, 2, "1/0", 1);
+       node_create(tree2, 3, "1/0/2", 0);
+
+       test_trees_nofree(tree1, &tree2);
+       test_assert(tree1->root.first_child->next == NULL);
+       dsync_mailbox_tree_deinit(&tree1);
+       test_end();
+}
+
 static void test_dsync_mailbox_tree_sync_random(void)
 {
        struct dsync_mailbox_tree *tree1, *tree2;
+       unsigned int i;
 
        test_begin("dsync mailbox tree sync random");
        tree1 = create_random_tree();
@@ -635,6 +665,7 @@ int main(void)
                test_dsync_mailbox_tree_sync_renames17,
                test_dsync_mailbox_tree_sync_renames18,
                test_dsync_mailbox_tree_sync_renames19,
+               test_dsync_mailbox_tree_sync_renames20,
                test_dsync_mailbox_tree_sync_random,
                NULL
        };