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:
Oswald Buddenhagen 2022-02-10 20:27:31 +01:00
parent fbc563e4cb
commit 3c0ad89a13
2 changed files with 23 additions and 5 deletions

View File

@ -948,10 +948,13 @@ my @x01 = (
C, "*FS", "*", "*F",
D, "*", "*", "*",
E, "*T", "*", "*",
F, "*", "*", "*T",
G, "*F", "*", "_",
H, "*FT", "*", "*",
I, "_", "*", "*",
J, "*T", "", "",
K, "*P", "", "",
L, "", "", "*T",
M, "", "", "*",
);
@ -962,10 +965,13 @@ my @X01 = (
B, "+F", "+F", "",
C, "", "+FS", "+S",
E, "", "+T", "+T",
F, "+T", "+T", "",
G, "+T", ">", "",
H, "", "+FT", "+FT",
I, "", "<", "+T",
L, "*T", "*T", "",
M, "*", "*", "",
J, "", "*T", "*T",
K, "", "*P", "*P",
);
test("full", \@x01, \@X01, \@O01);
@ -977,9 +983,12 @@ my @X02 = (
B, "+F", "+F", "",
C, "", "+FS", "+S",
E, "/", "/", "/",
F, "/", "/", "/",
G, "/", "/", "",
H, "/", "/", "/",
I, "", "/", "/",
J, "/", "", "",
L, "", "", "/",
M, "*", "*", "",
K, "", "*P", "*P",
);
@ -992,9 +1001,11 @@ my @X03 = (
B, "+F", "+F", "",
C, "", "+FS", "+S",
E, "", ">+T", "/",
F, "+T", ">+T", "/",
G, "+T", ">", "",
H, "", ">+T", "/",
I, "", "/", "/",
L, "", "", "/",
M, "*", "*", "",
K, "", "*P", "*P",
);
@ -1008,6 +1019,7 @@ my @X04 = (
E, "", "+T", "+T",
H, "", "+FT", "+FT",
I, "", "<", "+T",
J, "", "*T", "*T",
K, "", "*P", "*P",
);
test("pull", \@x01, \@X04, \@O04);
@ -1019,6 +1031,7 @@ my @X05 = (
B, "+F", "+F", "",
C, "", "+FS", "+S",
E, "", "+T", "+T",
F, "+T", "+T", "",
H, "", "+FT", "+FT",
);
test("flags", \@x01, \@X05, \@O05);
@ -1034,7 +1047,9 @@ test("deletions", \@x01, \@X06, \@O06);
my @O07 = ("", "", "Sync New\n");
my @X07 = (
M, 0, K,
L, "*T", "*T", "",
M, "*", "*", "",
J, "", "*T", "*T",
K, "", "*P", "*P",
);
test("new", \@x01, \@X07, \@O07);
@ -1044,6 +1059,7 @@ my @X08 = (
I, 0, I,
B, "+F", "+F", "",
C, "", "+F", "",
F, "+T", "+T", "",
I, "", "<", "+T",
);
test("push flags + pull deletions", \@x01, \@X08, \@O08);

View File

@ -767,7 +767,7 @@ box_opened2( sync_vars_t *svars, int t )
}
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;
}
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 );
if (srec->status & S_UPGRADE) {
if ((svars->chan->ops[t] & OP_EXPUNGE) &&
((srec->pflags | srec->aflags[t]) & ~srec->dflags[t] & F_DELETED)) {
if (((svars->chan->ops[t] & OP_EXPUNGE) &&
((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
// (in particular, F_DELETED) towards the real message.
// 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;
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.
// It would be lighter on the journal to log a (compressed) skip, but
// 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" );
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" );
continue;
}