don't propagate about-to-be-expunged messages
while we already refrained from propagating messages that would be expunged from the target, we still propagated ones that would be expunged from the source. this would lead to the weird situation of creating orphans, and would pose journal replay idempotence problems. such messages will now never have a sync record, so it becomes pointless to test for S_PENDING in the trashing loop. note that the behavior was previously bogus: these messages would have been paired by the end of the run, so we shouldn't have treated them as solo for the purposes of TrashOnlyNew/TrashRemoteNew.
This commit is contained in:
parent
fbc563e4cb
commit
3c0ad89a13
|
@ -948,10 +948,13 @@ my @x01 = (
|
||||||
C, "*FS", "*", "*F",
|
C, "*FS", "*", "*F",
|
||||||
D, "*", "*", "*",
|
D, "*", "*", "*",
|
||||||
E, "*T", "*", "*",
|
E, "*T", "*", "*",
|
||||||
|
F, "*", "*", "*T",
|
||||||
G, "*F", "*", "_",
|
G, "*F", "*", "_",
|
||||||
H, "*FT", "*", "*",
|
H, "*FT", "*", "*",
|
||||||
I, "_", "*", "*",
|
I, "_", "*", "*",
|
||||||
|
J, "*T", "", "",
|
||||||
K, "*P", "", "",
|
K, "*P", "", "",
|
||||||
|
L, "", "", "*T",
|
||||||
M, "", "", "*",
|
M, "", "", "*",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -962,10 +965,13 @@ my @X01 = (
|
||||||
B, "+F", "+F", "",
|
B, "+F", "+F", "",
|
||||||
C, "", "+FS", "+S",
|
C, "", "+FS", "+S",
|
||||||
E, "", "+T", "+T",
|
E, "", "+T", "+T",
|
||||||
|
F, "+T", "+T", "",
|
||||||
G, "+T", ">", "",
|
G, "+T", ">", "",
|
||||||
H, "", "+FT", "+FT",
|
H, "", "+FT", "+FT",
|
||||||
I, "", "<", "+T",
|
I, "", "<", "+T",
|
||||||
|
L, "*T", "*T", "",
|
||||||
M, "*", "*", "",
|
M, "*", "*", "",
|
||||||
|
J, "", "*T", "*T",
|
||||||
K, "", "*P", "*P",
|
K, "", "*P", "*P",
|
||||||
);
|
);
|
||||||
test("full", \@x01, \@X01, \@O01);
|
test("full", \@x01, \@X01, \@O01);
|
||||||
|
@ -977,9 +983,12 @@ my @X02 = (
|
||||||
B, "+F", "+F", "",
|
B, "+F", "+F", "",
|
||||||
C, "", "+FS", "+S",
|
C, "", "+FS", "+S",
|
||||||
E, "/", "/", "/",
|
E, "/", "/", "/",
|
||||||
|
F, "/", "/", "/",
|
||||||
G, "/", "/", "",
|
G, "/", "/", "",
|
||||||
H, "/", "/", "/",
|
H, "/", "/", "/",
|
||||||
I, "", "/", "/",
|
I, "", "/", "/",
|
||||||
|
J, "/", "", "",
|
||||||
|
L, "", "", "/",
|
||||||
M, "*", "*", "",
|
M, "*", "*", "",
|
||||||
K, "", "*P", "*P",
|
K, "", "*P", "*P",
|
||||||
);
|
);
|
||||||
|
@ -992,9 +1001,11 @@ my @X03 = (
|
||||||
B, "+F", "+F", "",
|
B, "+F", "+F", "",
|
||||||
C, "", "+FS", "+S",
|
C, "", "+FS", "+S",
|
||||||
E, "", ">+T", "/",
|
E, "", ">+T", "/",
|
||||||
|
F, "+T", ">+T", "/",
|
||||||
G, "+T", ">", "",
|
G, "+T", ">", "",
|
||||||
H, "", ">+T", "/",
|
H, "", ">+T", "/",
|
||||||
I, "", "/", "/",
|
I, "", "/", "/",
|
||||||
|
L, "", "", "/",
|
||||||
M, "*", "*", "",
|
M, "*", "*", "",
|
||||||
K, "", "*P", "*P",
|
K, "", "*P", "*P",
|
||||||
);
|
);
|
||||||
|
@ -1008,6 +1019,7 @@ my @X04 = (
|
||||||
E, "", "+T", "+T",
|
E, "", "+T", "+T",
|
||||||
H, "", "+FT", "+FT",
|
H, "", "+FT", "+FT",
|
||||||
I, "", "<", "+T",
|
I, "", "<", "+T",
|
||||||
|
J, "", "*T", "*T",
|
||||||
K, "", "*P", "*P",
|
K, "", "*P", "*P",
|
||||||
);
|
);
|
||||||
test("pull", \@x01, \@X04, \@O04);
|
test("pull", \@x01, \@X04, \@O04);
|
||||||
|
@ -1019,6 +1031,7 @@ my @X05 = (
|
||||||
B, "+F", "+F", "",
|
B, "+F", "+F", "",
|
||||||
C, "", "+FS", "+S",
|
C, "", "+FS", "+S",
|
||||||
E, "", "+T", "+T",
|
E, "", "+T", "+T",
|
||||||
|
F, "+T", "+T", "",
|
||||||
H, "", "+FT", "+FT",
|
H, "", "+FT", "+FT",
|
||||||
);
|
);
|
||||||
test("flags", \@x01, \@X05, \@O05);
|
test("flags", \@x01, \@X05, \@O05);
|
||||||
|
@ -1034,7 +1047,9 @@ test("deletions", \@x01, \@X06, \@O06);
|
||||||
my @O07 = ("", "", "Sync New\n");
|
my @O07 = ("", "", "Sync New\n");
|
||||||
my @X07 = (
|
my @X07 = (
|
||||||
M, 0, K,
|
M, 0, K,
|
||||||
|
L, "*T", "*T", "",
|
||||||
M, "*", "*", "",
|
M, "*", "*", "",
|
||||||
|
J, "", "*T", "*T",
|
||||||
K, "", "*P", "*P",
|
K, "", "*P", "*P",
|
||||||
);
|
);
|
||||||
test("new", \@x01, \@X07, \@O07);
|
test("new", \@x01, \@X07, \@O07);
|
||||||
|
@ -1044,6 +1059,7 @@ my @X08 = (
|
||||||
I, 0, I,
|
I, 0, I,
|
||||||
B, "+F", "+F", "",
|
B, "+F", "+F", "",
|
||||||
C, "", "+F", "",
|
C, "", "+F", "",
|
||||||
|
F, "+T", "+T", "",
|
||||||
I, "", "<", "+T",
|
I, "", "<", "+T",
|
||||||
);
|
);
|
||||||
test("push flags + pull deletions", \@x01, \@X08, \@O08);
|
test("push flags + pull deletions", \@x01, \@X08, \@O08);
|
||||||
|
|
12
src/sync.c
12
src/sync.c
|
@ -767,7 +767,7 @@ box_opened2( sync_vars_t *svars, int t )
|
||||||
}
|
}
|
||||||
opts[t^1] |= OPEN_OLD;
|
opts[t^1] |= OPEN_OLD;
|
||||||
}
|
}
|
||||||
if (chan->ops[t] & OP_EXPUNGE) // Don't propagate doomed msgs
|
if ((chan->ops[t] | chan->ops[t^1]) & OP_EXPUNGE) // Don't propagate doomed msgs
|
||||||
opts[t^1] |= OPEN_FLAGS;
|
opts[t^1] |= OPEN_FLAGS;
|
||||||
}
|
}
|
||||||
if (chan->ops[t] & OP_EXPUNGE) {
|
if (chan->ops[t] & OP_EXPUNGE) {
|
||||||
|
@ -1155,8 +1155,10 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
|
||||||
debug( "unpropagated old message %u\n", tmsg->uid );
|
debug( "unpropagated old message %u\n", tmsg->uid );
|
||||||
|
|
||||||
if (srec->status & S_UPGRADE) {
|
if (srec->status & S_UPGRADE) {
|
||||||
if ((svars->chan->ops[t] & OP_EXPUNGE) &&
|
if (((svars->chan->ops[t] & OP_EXPUNGE) &&
|
||||||
((srec->pflags | srec->aflags[t]) & ~srec->dflags[t] & F_DELETED)) {
|
((srec->pflags | srec->aflags[t]) & ~srec->dflags[t] & F_DELETED)) ||
|
||||||
|
((svars->chan->ops[t^1] & OP_EXPUNGE) &&
|
||||||
|
((srec->msg[t^1]->flags | srec->aflags[t^1]) & ~srec->dflags[t^1] & F_DELETED))) {
|
||||||
// We can't just kill the entry, as we may be propagating flags
|
// We can't just kill the entry, as we may be propagating flags
|
||||||
// (in particular, F_DELETED) towards the real message.
|
// (in particular, F_DELETED) towards the real message.
|
||||||
// No dummy is actually present, but pretend there is, so the
|
// No dummy is actually present, but pretend there is, so the
|
||||||
|
@ -1202,7 +1204,7 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
|
||||||
svars->newmaxuid[t^1] = tmsg->uid;
|
svars->newmaxuid[t^1] = tmsg->uid;
|
||||||
JLOG( "+ %u %u", (srec->uid[F], srec->uid[N]), "fresh" );
|
JLOG( "+ %u %u", (srec->uid[F], srec->uid[N]), "fresh" );
|
||||||
}
|
}
|
||||||
if ((svars->chan->ops[t] & OP_EXPUNGE) && (tmsg->flags & F_DELETED)) {
|
if (((svars->chan->ops[t] | svars->chan->ops[t^1]) & OP_EXPUNGE) && (tmsg->flags & F_DELETED)) {
|
||||||
// Yes, we may nuke fresh entries, created only for newmaxuid tracking.
|
// Yes, we may nuke fresh entries, created only for newmaxuid tracking.
|
||||||
// It would be lighter on the journal to log a (compressed) skip, but
|
// It would be lighter on the journal to log a (compressed) skip, but
|
||||||
// this rare case does not justify additional complexity.
|
// this rare case does not justify additional complexity.
|
||||||
|
@ -1661,7 +1663,7 @@ msgs_flags_set( sync_vars_t *svars, int t )
|
||||||
debug( "is deleted dummy\n" );
|
debug( "is deleted dummy\n" );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (only_new && !(srec->status & (S_PENDING | S_DUMMY(t^1) | S_SKIPPED))) {
|
if (only_new && !(srec->status & (S_DUMMY(t^1) | S_SKIPPED))) {
|
||||||
debug( "is not new\n" );
|
debug( "is not new\n" );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user