Skip to content

Commit 55a1f4e

Browse files
committed
mailbox: no hierarchy walk when deleting uuid mailboxes
1 parent 4fab1b3 commit 55a1f4e

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

Diff for: imap/mailbox.c

+33-6
Original file line numberDiff line numberDiff line change
@@ -6085,7 +6085,7 @@ static void mailbox_delete_files(const char *path)
60856085
}
60866086
}
60876087

6088-
/* Callback for use by cmd_delete */
6088+
/* Callback for use by mailbox_delete_cleanup */
60896089
static int chkchildren(const mbentry_t *mbentry,
60906090
void *rock)
60916091
{
@@ -6412,7 +6412,11 @@ static struct meta_file meta_files[] = {
64126412
* try to create a mailbox while the delete is underway.
64136413
* VERY tight race condition exists right now... */
64146414
/* we need an exclusive namelock for this */
6415-
HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, const char *name, const char *uniqueid)
6415+
/* XXX uniqueid here must be NULL if this is a legacy mailbox */
6416+
HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox,
6417+
const char *part,
6418+
const char *name,
6419+
const char *uniqueid)
64166420
{
64176421
strarray_t paths = STRARRAY_INITIALIZER;
64186422
int i;
@@ -6432,7 +6436,7 @@ HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, con
64326436
ntail = nbuf + strlen(nbuf);
64336437

64346438
if (mailbox && object_storage_enabled){
6435-
mailbox_remove_files_from_object_storage (mailbox, 0) ;
6439+
mailbox_remove_files_from_object_storage(mailbox, 0);
64366440
}
64376441

64386442
/* XXX - double XXX - this is a really ugly function. It should be
@@ -6465,14 +6469,36 @@ HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, con
64656469
for (i = 0; i < paths.count; i++) {
64666470
char *path = paths.data[i]; /* need direct reference, because we're fiddling */
64676471
r = rmdir(path);
6468-
if (r && errno != ENOENT)
6472+
if (r && errno != ENOENT) {
64696473
syslog(LOG_NOTICE,
64706474
"Remove of supposedly empty directory %s failed: %m",
64716475
path);
6472-
p = strrchr(path, '/');
6473-
if (p) *p = '\0';
6476+
}
6477+
6478+
if (!uniqueid) {
6479+
p = strrchr(path, '/');
6480+
if (p) *p = '\0';
6481+
}
64746482
}
64756483

6484+
if (uniqueid) {
6485+
/* n.b. careful here -- legacy mailboxes will also have uniqueids,
6486+
* but we don't pass the uniqueid to this function for those, so
6487+
* uniqueid being non-NULL here means we're dealing with a UUID
6488+
* mailbox.
6489+
* UUID mailboxes have a flat on disk structure, so once we've
6490+
* removed the listed paths we're done, no hierarchy walk needed.
6491+
*/
6492+
goto done;
6493+
}
6494+
6495+
/* XXX For legacy mailboxes, this hierarchy walk might have been
6496+
* XXX intended to remove intermediate mailboxes after their
6497+
* XXX last child was removed. In which case, the hierarchy walk
6498+
* XXX might be obsolete for legacy mailboxes too, since we no
6499+
* XXX longer create intermediate mailboxes.
6500+
*/
6501+
64766502
/* Check if parent mailbox exists */
64776503
ntail = strrchr(nbuf, '.');
64786504
if (!ntail || strchr(ntail, '!')) {
@@ -6496,6 +6522,7 @@ HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, con
64966522
}
64976523
} while (r == IMAP_MAILBOX_NONEXISTENT);
64986524

6525+
done:
64996526
strarray_fini(&paths);
65006527

65016528
return 0;

0 commit comments

Comments
 (0)