dovecot-2.0: lib-storage: Mailbox deletion API changed.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Feb 9 04:12:03 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/1fd7833c16ca
changeset: 10676:1fd7833c16ca
user: Timo Sirainen <tss at iki.fi>
date: Tue Feb 09 04:11:53 2010 +0200
description:
lib-storage: Mailbox deletion API changed.
Mailbox deletion should now be free of race conditions. The actual file
deletion code is now responsibility of mailbox_list backend.
diffstat:
45 files changed, 837 insertions(+), 1158 deletions(-)
src/dsync/dsync-worker-local.c | 10
src/imap/cmd-delete.c | 15 -
src/lib-storage/index/cydir/cydir-storage.c | 117 --------
src/lib-storage/index/dbox-common/dbox-mail.h | 2
src/lib-storage/index/dbox-common/dbox-storage.c | 123 ---------
src/lib-storage/index/dbox-common/dbox-storage.h | 5
src/lib-storage/index/dbox-multi/mdbox-map.c | 5
src/lib-storage/index/dbox-multi/mdbox-map.h | 1
src/lib-storage/index/dbox-multi/mdbox-storage.c | 87 +-----
src/lib-storage/index/dbox-single/sdbox-storage.c | 31 --
src/lib-storage/index/index-storage.c | 71 ++++-
src/lib-storage/index/index-storage.h | 2
src/lib-storage/index/index-transaction.c | 6
src/lib-storage/index/maildir/maildir-storage.c | 274 +-------------------
src/lib-storage/index/maildir/maildir-storage.h | 1
src/lib-storage/index/mbox/mbox-storage.c | 87 ------
src/lib-storage/index/raw/raw-storage.c | 11
src/lib-storage/index/shared/shared-list.c | 3
src/lib-storage/list/Makefile.am | 2
src/lib-storage/list/mailbox-list-delete.c | 284 +++++++++++++++++++++
src/lib-storage/list/mailbox-list-delete.h | 14 +
src/lib-storage/list/mailbox-list-fs.c | 52 +++
src/lib-storage/list/mailbox-list-fs.h | 4
src/lib-storage/list/mailbox-list-maildir.c | 42 ++-
src/lib-storage/list/mailbox-list-maildir.h | 4
src/lib-storage/mail-copy.h | 3
src/lib-storage/mail-storage-private.h | 3
src/lib-storage/mail-storage.c | 67 ++++
src/lib-storage/mail-storage.h | 6
src/lib-storage/mailbox-list-private.h | 4
src/lib-storage/mailbox-list.c | 69 -----
src/lib-storage/mailbox-list.h | 2
src/lib-storage/test-mailbox.c | 8
src/plugins/acl/acl-mailbox-list.c | 26 -
src/plugins/acl/acl-mailbox.c | 69 +++--
src/plugins/lazy-expunge/lazy-expunge-plugin.c | 164 ++++++------
src/plugins/listescape/listescape-plugin.c | 15 -
src/plugins/mail-log/mail-log-plugin.c | 7
src/plugins/notify/notify-noop.c | 6
src/plugins/notify/notify-plugin-private.h | 6
src/plugins/notify/notify-plugin.c | 33 +-
src/plugins/notify/notify-plugin.h | 13
src/plugins/notify/notify-storage.c | 30 +-
src/plugins/quota/quota-storage.c | 116 +++-----
src/plugins/virtual/virtual-storage.c | 95 -------
diffs (truncated from 3059 to 300 lines):
diff -r 9cefc944d82a -r 1fd7833c16ca src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c Tue Feb 09 04:09:28 2010 +0200
+++ b/src/dsync/dsync-worker-local.c Tue Feb 09 04:11:53 2010 +0200
@@ -1105,6 +1105,7 @@ local_worker_delete_mailbox(struct dsync
(struct local_dsync_worker *)_worker;
struct local_dsync_mailbox *lbox;
const mailbox_guid_t *mailbox = &dsync_box->mailbox_guid;
+ struct mailbox *box;
lbox = hash_table_lookup(worker->mailbox_hash, mailbox);
if (lbox == NULL) {
@@ -1116,12 +1117,15 @@ local_worker_delete_mailbox(struct dsync
mailbox_list_set_changelog_timestamp(lbox->ns->list,
dsync_box->last_change);
- if (mailbox_list_delete_mailbox(lbox->ns->list,
- lbox->storage_name) < 0) {
+ box = mailbox_alloc(lbox->ns->list, lbox->storage_name, NULL, 0);
+ if (mailbox_delete(box) < 0) {
+ struct mail_storage *storage = mailbox_get_storage(box);
+
i_error("Can't delete mailbox %s: %s", lbox->storage_name,
- mailbox_list_get_last_error(lbox->ns->list, NULL));
+ mail_storage_get_last_error(storage, NULL));
dsync_worker_set_failure(_worker);
}
+ mailbox_free(&box);
mailbox_list_set_changelog_timestamp(lbox->ns->list, (time_t)-1);
}
diff -r 9cefc944d82a -r 1fd7833c16ca src/imap/cmd-delete.c
--- a/src/imap/cmd-delete.c Tue Feb 09 04:09:28 2010 +0200
+++ b/src/imap/cmd-delete.c Tue Feb 09 04:11:53 2010 +0200
@@ -7,7 +7,7 @@ bool cmd_delete(struct client_command_co
{
struct client *client = cmd->client;
struct mail_namespace *ns;
- struct mailbox *mailbox;
+ struct mailbox *box;
const char *name;
/* <mailbox> */
@@ -25,19 +25,18 @@ bool cmd_delete(struct client_command_co
if (ns == NULL)
return TRUE;
- mailbox = mailbox_alloc(ns->list, name, NULL, 0);
+ box = mailbox_alloc(ns->list, name, NULL, 0);
if (client->mailbox != NULL &&
- mailbox_backends_equal(mailbox, client->mailbox)) {
+ mailbox_backends_equal(box, client->mailbox)) {
/* deleting selected mailbox. close it first */
client_search_updates_free(client);
mailbox_free(&client->mailbox);
}
- mailbox_free(&mailbox);
- if (mailbox_list_delete_mailbox(ns->list, name) < 0)
- client_send_list_error(cmd, ns->list);
- else {
+ if (mailbox_delete(box) < 0)
+ client_send_storage_error(cmd, mailbox_get_storage(box));
+ else
client_send_tagline(cmd, "OK Delete completed.");
- }
+ mailbox_free(&box);
return TRUE;
}
diff -r 9cefc944d82a -r 1fd7833c16ca src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c Tue Feb 09 04:09:28 2010 +0200
+++ b/src/lib-storage/index/cydir/cydir-storage.c Tue Feb 09 04:11:53 2010 +0200
@@ -1,30 +1,15 @@
/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
#include "lib.h"
-#include "array.h"
-#include "str.h"
-#include "mkdir-parents.h"
+#include "mail-copy.h"
#include "index-mail.h"
-#include "mail-copy.h"
#include "cydir-sync.h"
#include "cydir-storage.h"
-#include <unistd.h>
-#include <dirent.h>
#include <sys/stat.h>
-
-#define CYDIR_LIST_CONTEXT(obj) \
- MODULE_CONTEXT(obj, cydir_mailbox_list_module)
-
-struct cydir_mailbox_list {
- union mailbox_list_module_context module_ctx;
-};
extern struct mail_storage cydir_storage;
extern struct mailbox cydir_mailbox;
-
-static MODULE_CONTEXT_DEFINE_INIT(cydir_mailbox_list_module,
- &mailbox_list_module_register);
static struct mail_storage *cydir_storage_alloc(void)
{
@@ -126,97 +111,6 @@ cydir_mailbox_create(struct mailbox *box
return update == NULL ? 0 :
index_storage_mailbox_update(box, update);
-}
-
-static int
-cydir_delete_nonrecursive(struct mailbox_list *list, const char *path,
- const char *name)
-{
- DIR *dir;
- struct dirent *d;
- string_t *full_path;
- unsigned int dir_len;
- bool unlinked_something = FALSE;
-
- dir = opendir(path);
- if (dir == NULL) {
- if (!mailbox_list_set_error_from_errno(list)) {
- mailbox_list_set_critical(list,
- "opendir(%s) failed: %m", path);
- }
- return -1;
- }
-
- full_path = t_str_new(256);
- str_append(full_path, path);
- str_append_c(full_path, '/');
- dir_len = str_len(full_path);
-
- errno = 0;
- while ((d = readdir(dir)) != NULL) {
- if (d->d_name[0] == '.') {
- /* skip . and .. */
- if (d->d_name[1] == '\0')
- continue;
- if (d->d_name[1] == '.' && d->d_name[2] == '\0')
- continue;
- }
-
- str_truncate(full_path, dir_len);
- str_append(full_path, d->d_name);
-
- /* trying to unlink() a directory gives either EPERM or EISDIR
- (non-POSIX). it doesn't really work anywhere in practise,
- so don't bother stat()ing the file first */
- if (unlink(str_c(full_path)) == 0)
- unlinked_something = TRUE;
- else if (errno != ENOENT && errno != EISDIR && errno != EPERM) {
- mailbox_list_set_critical(list, "unlink(%s) failed: %m",
- str_c(full_path));
- }
- }
-
- if (closedir(dir) < 0) {
- mailbox_list_set_critical(list, "closedir(%s) failed: %m",
- path);
- }
-
- if (rmdir(path) == 0)
- unlinked_something = TRUE;
- else if (errno != ENOENT && errno != ENOTEMPTY) {
- mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path);
- return -1;
- }
-
- if (!unlinked_something) {
- mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
- t_strdup_printf("Directory %s isn't empty, "
- "can't delete it.", name));
- return -1;
- }
- return 0;
-}
-
-static int
-cydir_list_delete_mailbox(struct mailbox_list *list, const char *name)
-{
- struct cydir_mailbox_list *mlist = CYDIR_LIST_CONTEXT(list);
- struct stat st;
- const char *src;
-
- /* delete the index and control directories */
- if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
- return -1;
-
- /* check if the mailbox actually exists */
- src = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX);
- if (stat(src, &st) != 0 && errno == ENOENT) {
- mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
- T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
- return -1;
- }
-
- return cydir_delete_nonrecursive(list, src, name);
}
static void cydir_notify_changes(struct mailbox *box)
@@ -286,15 +180,7 @@ static void cydir_storage_add_list(struc
static void cydir_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
struct mailbox_list *list)
{
- struct cydir_mailbox_list *mlist;
-
- mlist = p_new(list->pool, struct cydir_mailbox_list, 1);
- mlist->module_ctx.super = list->v;
-
list->v.iter_is_mailbox = cydir_list_iter_is_mailbox;
- list->v.delete_mailbox = cydir_list_delete_mailbox;
-
- MODULE_CONTEXT_SET(list, cydir_mailbox_list_module, mlist);
}
struct mail_storage cydir_storage = {
@@ -323,6 +209,7 @@ struct mailbox cydir_mailbox = {
index_storage_mailbox_close,
cydir_mailbox_create,
index_storage_mailbox_update,
+ index_storage_mailbox_delete,
index_storage_get_status,
NULL,
NULL,
diff -r 9cefc944d82a -r 1fd7833c16ca src/lib-storage/index/dbox-common/dbox-mail.h
--- a/src/lib-storage/index/dbox-common/dbox-mail.h Tue Feb 09 04:09:28 2010 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-mail.h Tue Feb 09 04:11:53 2010 +0200
@@ -1,5 +1,7 @@
#ifndef DBOX_MAIL_H
#define DBOX_MAIL_H
+
+#include "index-mail.h"
struct dbox_mail {
struct index_mail imail;
diff -r 9cefc944d82a -r 1fd7833c16ca src/lib-storage/index/dbox-common/dbox-storage.c
--- a/src/lib-storage/index/dbox-common/dbox-storage.c Tue Feb 09 04:09:28 2010 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c Tue Feb 09 04:11:53 2010 +0200
@@ -2,10 +2,7 @@
#include "lib.h"
#include "ioloop.h"
-#include "randgen.h"
-#include "hex-binary.h"
#include "mkdir-parents.h"
-#include "unlink-directory.h"
#include "unlink-old-files.h"
#include "mailbox-uidvalidity.h"
#include "mailbox-list-private.h"
@@ -326,123 +323,3 @@ int dbox_list_rename_mailbox(struct mail
}
return 0;
}
-
-static const char *dbox_get_trash_dest(const char *trash_dir)
-{
- const char *path;
- unsigned char randbuf[16];
- struct stat st;
-
- do {
- random_fill_weak(randbuf, sizeof(randbuf));
- path = t_strconcat(trash_dir, "/",
- binary_to_hex(randbuf, sizeof(randbuf)), NULL);
- } while (lstat(path, &st) == 0);
- return path;
-}
-
-int dbox_list_delete_mailbox1(struct mailbox_list *list, const char *name,
- const char **trash_dest_r)
-{
- struct stat st;
- const char *path, *trash_dir, *trash_dest;
- int ret;
-
- path = mailbox_list_get_path(list, name,
- MAILBOX_LIST_PATH_TYPE_MAILBOX);
- trash_dir = mailbox_list_get_path(list, NULL,
- MAILBOX_LIST_PATH_TYPE_DIR);
- trash_dir = t_strconcat(trash_dir, "/"DBOX_TRASH_DIR_NAME, NULL);
- trash_dest = *trash_dest_r = dbox_get_trash_dest(trash_dir);
-
- /* first try renaming the actual mailbox to trash directory */
- ret = rename(path, trash_dest);
- if (ret < 0 && errno == ENOENT) {
- /* either source mailbox doesn't exist or trash directory
- doesn't exist. try creating the trash and retrying. */
- const char *origin;
- mode_t mode;
- gid_t gid;
-
- mailbox_list_get_dir_permissions(list, NULL, &mode,
- &gid, &origin);
- if (mkdir_parents_chgrp(trash_dir, mode, gid, origin) < 0 &&
- errno != EEXIST) {
- mailbox_list_set_critical(list,
- "mkdir(%s) failed: %m", trash_dir);
- return -1;
- }
More information about the dovecot-cvs
mailing list