From: Timo Sirainen Date: Sat, 14 Jun 2003 17:38:06 +0000 (+0300) Subject: Close index files before deleting the mailbox. X-Git-Tag: 1.1.alpha1~4560 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=484d5c222e6d9a9330c76e8b88c6e96a112d6569;p=thirdparty%2Fdovecot%2Fcore.git Close index files before deleting the mailbox. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 1b42c67456..21fa976a57 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -99,6 +99,23 @@ void index_storage_unref(struct mail_index *index) i_unreached(); } +void index_storage_destroy_unrefed(void) +{ + struct index_list **list, *rec; + + for (list = &indexes; *list != NULL;) { + rec = *list; + + if (rec->refcount == 0) { + rec->index->free(rec->index); + *list = rec->next; + i_free(rec); + } else { + list = &(*list)->next; + } + } +} + static enum mail_data_field get_data_fields(const char *fields) { static const char *field_names[] = { diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index 10fd8277d2..f2bbab5c1e 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -44,6 +44,7 @@ int index_storage_lock(struct index_mailbox *ibox, void index_storage_add(struct mail_index *index); struct mail_index *index_storage_lookup_ref(const char *path); void index_storage_unref(struct mail_index *index); +void index_storage_destroy_unrefed(void); struct index_mailbox * index_storage_init(struct mail_storage *storage, struct mailbox *box, diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index c12f55b147..f935d24c36 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -431,10 +431,14 @@ static int maildir_delete_mailbox(struct mail_storage *storage, if (storage->index_dir != NULL && *name != '/' && *name != '~' && strcmp(storage->index_dir, storage->dir) != 0) { index_dir = t_strconcat(storage->index_dir, "/.", name, NULL); - if (unlink_directory(index_dir, TRUE) < 0) { + index_storage_destroy_unrefed(); + + /* it can fail with some NFS implementations if indexes are + opened by another session.. can't really help it. */ + if (unlink_directory(index_dir, TRUE) < 0 && + errno != ENOTEMPTY) { mail_storage_set_critical(storage, - "unlink_directory(%s) " - "failed: %m", index_dir); + "unlink_directory(%s) failed: %m", index_dir); return FALSE; } } @@ -443,24 +447,22 @@ static int maildir_delete_mailbox(struct mail_storage *storage, while (rename(src, dest) < 0 && count < 2) { if (errno != EEXIST && errno != ENOTEMPTY) { mail_storage_set_critical(storage, - "rename(%s, %s) failed: %m", - src, dest); + "rename(%s, %s) failed: %m", src, dest); return FALSE; } /* ..dir already existed? delete it and try again */ if (unlink_directory(dest, TRUE) < 0) { mail_storage_set_critical(storage, - "unlink_directory(%s) " - "failed: %m", dest); + "unlink_directory(%s) failed: %m", dest); return FALSE; } count++; } - if (unlink_directory(dest, TRUE) < 0) { - mail_storage_set_critical(storage, "unlink_directory(%s) " - "failed: %m", dest); + if (unlink_directory(dest, TRUE) < 0 && errno != ENOTEMPTY) { + mail_storage_set_critical(storage, + "unlink_directory(%s) failed: %m", dest); /* it's already renamed to ..dir, which means it's deleted as far as client is concerned. Report success. */ diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 1e24736235..158fb9526d 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -529,12 +529,18 @@ static int mbox_delete_mailbox(struct mail_storage *storage, const char *name) /* next delete the index directory */ index_dir = mbox_get_index_dir(storage, name); - if (index_dir != NULL && - unlink_directory(index_dir, TRUE) < 0 && errno != ENOENT) { - mail_storage_set_critical(storage, - "unlink_directory(%s) failed: %m", index_dir); - /* mailbox itself is deleted, so return success anyway */ + if (index_dir != NULL) { + index_storage_destroy_unrefed(); + + if (unlink_directory(index_dir, TRUE) < 0 && errno != ENOENT) { + mail_storage_set_critical(storage, + "unlink_directory(%s) failed: %m", index_dir); + + /* mailbox itself is deleted, so return success + anyway */ + } } + return TRUE; }