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[] = {
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;
}
}
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. */
/* 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;
}