orphan/prune sync entries also if messages were expunged externally
deletions we propagated ourselves are implicitly covered by that as well, so we don't need to record them separately anymore.
This commit is contained in:
parent
f2f519e20b
commit
eab3874918
|
@ -941,6 +941,7 @@ sub test($$$$)
|
|||
|
||||
my @x01 = (
|
||||
I, 0, I,
|
||||
P, "_", "*", "_",
|
||||
R, "*", "", "", # Skipped/failed messages to prevent maxuid topping
|
||||
S, "", "", "*",
|
||||
A, "*F", "*", "*",
|
||||
|
@ -949,6 +950,8 @@ my @x01 = (
|
|||
D, "*", "*", "*",
|
||||
E, "*T", "*", "*",
|
||||
F, "*", "*", "*T",
|
||||
O, "*T", "*T", "*T",
|
||||
Q, "_", "*T", "*T",
|
||||
G, "*F", "*", "_",
|
||||
H, "*FT", "*", "*",
|
||||
I, "_", "*", "*",
|
||||
|
@ -961,11 +964,13 @@ my @x01 = (
|
|||
my @O01 = ("", "", "");
|
||||
my @X01 = (
|
||||
M, 0, K,
|
||||
P, "", "/", "",
|
||||
A, "", "+F", "+F",
|
||||
B, "+F", "+F", "",
|
||||
C, "", "+FS", "+S",
|
||||
E, "", "+T", "+T",
|
||||
F, "+T", "+T", "",
|
||||
Q, "", "<", "",
|
||||
G, "+T", ">", "",
|
||||
H, "", "+FT", "+FT",
|
||||
I, "", "<", "+T",
|
||||
|
@ -979,11 +984,14 @@ test("full", \@x01, \@X01, \@O01);
|
|||
my @O02 = ("", "", "Expunge Both\n");
|
||||
my @X02 = (
|
||||
M, 0, K,
|
||||
P, "", "/", "",
|
||||
A, "", "+F", "+F",
|
||||
B, "+F", "+F", "",
|
||||
C, "", "+FS", "+S",
|
||||
E, "/", "/", "/",
|
||||
F, "/", "/", "/",
|
||||
O, "/", "/", "/",
|
||||
Q, "", "/", "/",
|
||||
G, "/", "/", "",
|
||||
H, "/", "/", "/",
|
||||
I, "", "/", "/",
|
||||
|
@ -997,11 +1005,14 @@ test("full + expunge both", \@x01, \@X02, \@O02);
|
|||
my @O03 = ("", "", "Expunge Near\n");
|
||||
my @X03 = (
|
||||
M, 0, K,
|
||||
P, "", "/", "",
|
||||
A, "", "+F", "+F",
|
||||
B, "+F", "+F", "",
|
||||
C, "", "+FS", "+S",
|
||||
E, "", ">+T", "/",
|
||||
F, "+T", ">+T", "/",
|
||||
O, "", ">", "/",
|
||||
Q, "", "/", "/",
|
||||
G, "+T", ">", "",
|
||||
H, "", ">+T", "/",
|
||||
I, "", "/", "/",
|
||||
|
@ -1014,9 +1025,11 @@ test("full + expunge near side", \@x01, \@X03, \@O03);
|
|||
my @O04 = ("", "", "Sync Pull\n");
|
||||
my @X04 = (
|
||||
K, 0, I,
|
||||
P, "", "/", "", # Only because test uses Maildir driver
|
||||
A, "", "+F", "+F",
|
||||
C, "", "+FS", "+S",
|
||||
E, "", "+T", "+T",
|
||||
Q, "", "<", "",
|
||||
H, "", "+FT", "+FT",
|
||||
I, "", "<", "+T",
|
||||
J, "", "*T", "*T",
|
||||
|
@ -1027,11 +1040,13 @@ test("pull", \@x01, \@X04, \@O04);
|
|||
my @O05 = ("", "", "Sync Flags\n");
|
||||
my @X05 = (
|
||||
I, 0, I,
|
||||
P, "", "/", "",
|
||||
A, "", "+F", "+F",
|
||||
B, "+F", "+F", "",
|
||||
C, "", "+FS", "+S",
|
||||
E, "", "+T", "+T",
|
||||
F, "+T", "+T", "",
|
||||
Q, "", "<", "",
|
||||
H, "", "+FT", "+FT",
|
||||
);
|
||||
test("flags", \@x01, \@X05, \@O05);
|
||||
|
@ -1039,7 +1054,9 @@ test("flags", \@x01, \@X05, \@O05);
|
|||
my @O06 = ("", "", "Sync Delete\n");
|
||||
my @X06 = (
|
||||
I, 0, I,
|
||||
P, "", "/", "",
|
||||
G, "+T", ">", "",
|
||||
Q, "", "<", "",
|
||||
I, "", "<", "+T",
|
||||
);
|
||||
test("deletions", \@x01, \@X06, \@O06);
|
||||
|
@ -1057,9 +1074,11 @@ test("new", \@x01, \@X07, \@O07);
|
|||
my @O08 = ("", "", "Sync PushFlags PullDelete\n");
|
||||
my @X08 = (
|
||||
I, 0, I,
|
||||
P, "", "/", "",
|
||||
B, "+F", "+F", "",
|
||||
C, "", "+F", "",
|
||||
F, "+T", "+T", "",
|
||||
Q, "", "<", "",
|
||||
I, "", "<", "+T",
|
||||
);
|
||||
test("push flags + pull deletions", \@x01, \@X08, \@O08);
|
||||
|
@ -1067,8 +1086,11 @@ test("push flags + pull deletions", \@x01, \@X08, \@O08);
|
|||
my @O09 = ("", "", "Sync None\nExpunge Both\n");
|
||||
my @X09 = (
|
||||
I, 0, I,
|
||||
P, "", "/", "",
|
||||
E, "/", "", "",
|
||||
F, "", "", "/",
|
||||
O, "/", "/", "/",
|
||||
Q, "", "/", "/",
|
||||
H, "/", "", "",
|
||||
J, "/", "", "",
|
||||
L, "", "", "/",
|
||||
|
@ -1080,6 +1102,8 @@ my @O0A = ("", "", "Sync None\nExpunge Near\n");
|
|||
my @X0A = (
|
||||
I, 0, I,
|
||||
F, "", "", "/",
|
||||
O, "", "", "/",
|
||||
Q, "", "", "/",
|
||||
L, "", "", "/",
|
||||
);
|
||||
test("noop + expunge near side", \@x01, \@X0A, \@O0A);
|
||||
|
|
20
src/sync.c
20
src/sync.c
|
@ -1036,6 +1036,7 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
|
|||
} else if (del[t]) {
|
||||
// The target was newly expunged, so there is nothing to update.
|
||||
// The deletion is propagated in the opposite iteration.
|
||||
srec->status |= S_GONE(t);
|
||||
} else if (!srec->uid[t]) {
|
||||
// The target was never stored, or was previously expunged, so there
|
||||
// is nothing to update.
|
||||
|
@ -1340,7 +1341,7 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
|
|||
for (t = 0; t < 2; t++) {
|
||||
if (!srec->uid[t])
|
||||
continue;
|
||||
if (!srec->msg[t] && (svars->opts[t] & OPEN_OLD)) {
|
||||
if (srec->status & S_GONE(t)) {
|
||||
// The message was expunged. No need to call flags_set(), because:
|
||||
// - for S_DELETE and S_PURGE, the entry will be pruned due to both sides being gone
|
||||
// - for regular flag propagations, there is nothing to do
|
||||
|
@ -1571,10 +1572,7 @@ flags_set_p2( sync_vars_t *svars, sync_rec_t *srec, int t )
|
|||
if (srec->status & S_PURGE) {
|
||||
JLOG( "P %u %u", (srec->uid[F], srec->uid[N]), "deleted dummy" );
|
||||
srec->status = (srec->status & ~S_PURGE) | S_PURGED;
|
||||
} else if (srec->status & S_DELETE) {
|
||||
JLOG( "%c %u %u 0", ("><"[t], srec->uid[F], srec->uid[N]), "%sed deletion", str_hl[t] );
|
||||
srec->uid[t^1] = 0;
|
||||
} else {
|
||||
} else if (!(srec->status & S_DELETE)) {
|
||||
uchar nflags = (srec->flags | srec->aflags[t]) & ~srec->dflags[t];
|
||||
if (srec->flags != nflags) {
|
||||
JLOG( "* %u %u %u", (srec->uid[F], srec->uid[N], nflags), "%sed flags %s; were %s",
|
||||
|
@ -1802,13 +1800,16 @@ box_closed_p2( sync_vars_t *svars, int t )
|
|||
PC_JLOG( "N %d %u", (t, svars->maxuid[t]), "up maxuid of %s", str_fn[t] );
|
||||
}
|
||||
|
||||
if (((svars->state[F] | svars->state[N]) & ST_DID_EXPUNGE) || svars->chan->max_messages) {
|
||||
debug( "purging obsolete entries\n" );
|
||||
for (srec = svars->srecs; srec; srec = srec->next) {
|
||||
if (srec->status & S_DEAD)
|
||||
continue;
|
||||
if (!srec->uid[N] || ((srec->status & S_DEL(N)) && (svars->state[N] & ST_DID_EXPUNGE))) {
|
||||
if (!srec->uid[F] || ((srec->status & S_DEL(F)) && (svars->state[F] & ST_DID_EXPUNGE)) ||
|
||||
if ((srec->status & S_DEL(F)) && (svars->state[F] & ST_DID_EXPUNGE))
|
||||
srec->status |= S_GONE(F);
|
||||
if ((srec->status & S_DEL(N)) && (svars->state[N] & ST_DID_EXPUNGE))
|
||||
srec->status |= S_GONE(N);
|
||||
if (!srec->uid[N] || (srec->status & S_GONE(N))) {
|
||||
if (!srec->uid[F] || (srec->status & S_GONE(F)) ||
|
||||
((srec->status & S_EXPIRED) && svars->maxuid[F] >= srec->uid[F] && svars->maxxfuid >= srec->uid[F])) {
|
||||
PC_JLOG( "- %u %u", (srec->uid[F], srec->uid[N]), "killing" );
|
||||
srec->status = S_DEAD;
|
||||
|
@ -1816,12 +1817,11 @@ box_closed_p2( sync_vars_t *svars, int t )
|
|||
PC_JLOG( "> %u %u 0", (srec->uid[F], srec->uid[N]), "orphaning" );
|
||||
srec->uid[N] = 0;
|
||||
}
|
||||
} else if (srec->uid[F] && ((srec->status & S_DEL(F)) && (svars->state[F] & ST_DID_EXPUNGE)) && (srec->status & S_DEL(N))) {
|
||||
} else if (srec->uid[F] && (srec->status & S_GONE(F)) && (srec->status & S_DEL(N))) {
|
||||
PC_JLOG( "< %u %u 0", (srec->uid[F], srec->uid[N]), "orphaning" );
|
||||
srec->uid[F] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save_state( svars );
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ BIT_ENUM(
|
|||
S_PENDING, // the entry is new and awaits propagation (possibly a retry)
|
||||
S_DUMMY(2), // f/n message is only a placeholder
|
||||
S_SKIPPED, // pre-1.4 legacy: the entry was not propagated (message is too big)
|
||||
S_GONE(2), // ephemeral: f/n message has been expunged
|
||||
S_DEL(2), // ephemeral: f/n message would be subject to expunge
|
||||
S_DELETE, // ephemeral: flags propagation is a deletion
|
||||
S_UPGRADE, // ephemeral: upgrading placeholder, do not apply MaxSize
|
||||
|
|
Loading…
Reference in New Issue
Block a user