]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dbox: Removed dbox-index code.
authorTimo Sirainen <tss@iki.fi>
Tue, 17 Feb 2009 03:44:42 +0000 (22:44 -0500)
committerTimo Sirainen <tss@iki.fi>
Tue, 17 Feb 2009 03:44:42 +0000 (22:44 -0500)
--HG--
branch : HEAD

src/lib-storage/index/dbox/dbox-file.h
src/lib-storage/index/dbox/dbox-index.c
src/lib-storage/index/dbox/dbox-index.h
src/lib-storage/index/dbox/dbox-storage.h
src/lib-storage/index/dbox/dbox-sync-file.c

index 80acec3e9704f2a952d1e77924a4da2dd58b2a71..5f63b95940d1c3e1afd6e929aa341c32899850aa 100644 (file)
@@ -145,7 +145,7 @@ void dbox_files_free(struct dbox_mailbox *mbox);
 /* Assign a newly created file (file_id=0) a new id. */
 int dbox_file_assign_id(struct dbox_file *file, unsigned int file_id);
 
-/* If file_id is 0, open the file, otherwise create it. Returns 1 if ok,
+/* Open the file if file_id is not 0, otherwise create it. Returns 1 if ok,
    0 if read_header=TRUE and opened file was broken, -1 if error. If file is
    deleted, deleted_r=TRUE and 1 is returned. */
 int dbox_file_open_or_create(struct dbox_file *file, bool read_header,
index aedbc342b19e4c78369078de47b8b9b82748f78c..8790ee8dbef393bdc1ff81144252f1d583e80eab 100644 (file)
@@ -2,36 +2,12 @@
 
 #include "lib.h"
 #include "array.h"
-#include "hex-dec.h"
-#include "str.h"
-#include "istream.h"
-#include "ostream.h"
-#include "write-full.h"
-#include "nfs-workarounds.h"
-#include "safe-mkstemp.h"
-#include "mailbox-uidvalidity.h"
 #include "dbox-storage.h"
 #include "dbox-file.h"
 #include "dbox-index.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#define DBOX_INDEX_LOCK_RETRY_COUNT 10
-
 struct dbox_index {
        struct dbox_mailbox *mbox;
-
-       struct istream *input;
-       char *path;
-       int fd;
-
-       uint32_t uid_validity, next_uid;
-       unsigned int next_file_id;
-
-       pool_t record_data_pool;
-       ARRAY_DEFINE(records, struct dbox_index_record);
 };
 
 struct dbox_index_append_context {
@@ -40,656 +16,47 @@ struct dbox_index_append_context {
 
        uoff_t output_offset;
        unsigned int new_record_idx;
-       unsigned int first_new_file_id;
+       uint32_t first_new_file_id;
 
        unsigned int locked_header:1;
 };
 
-static int dbox_index_recreate(struct dbox_index *index, bool locked);
-
 struct dbox_index *dbox_index_init(struct dbox_mailbox *mbox)
 {
        struct dbox_index *index;
 
        index = i_new(struct dbox_index, 1);
        index->mbox = mbox;
-       index->path = i_strdup_printf("%s/"DBOX_INDEX_NAME, mbox->path);
-       index->fd = -1;
-       index->next_uid = 1;
-       index->next_file_id = 1;
-       i_array_init(&index->records, 128);
-       index->record_data_pool =
-               pool_alloconly_create("dbox index record data", 256);
        return index;
 }
 
-static void dbox_index_close(struct dbox_index *index)
-{
-       if (index->input != NULL)
-               i_stream_unref(&index->input);
-       if (index->fd != -1) {
-               if (close(index->fd) < 0)
-                       i_error("close(%s) failed: %m", index->path);
-               index->fd = -1;
-       }
-}
-
 void dbox_index_deinit(struct dbox_index **_index)
 {
        struct dbox_index *index = *_index;
 
        *_index = NULL;
 
-       dbox_index_close(index);
-       array_free(&index->records);
-       pool_unref(&index->record_data_pool);
-       i_free(index->path);
        i_free(index);
 }
 
-static int dbox_index_parse_maildir(struct dbox_index *index, const char *line,
-                                   struct dbox_index_record *rec)
-{
-       char *p;
-       unsigned long uid;
-
-       if (*line++ != ' ')
-               return -1;
-
-       uid = strtoul(line, &p, 10);
-       if (*p++ != ' ' || *p == '\0' || uid == 0 || uid >= (uint32_t)-1)
-               return -1;
-
-       if (*p == ':' || strstr(p, " :") != NULL)
-               rec->data = p_strdup(index->record_data_pool, line);
-       else {
-               /* convert to new format */
-               rec->data = p_strconcat(index->record_data_pool,
-                                       t_strdup_until(line, p), ":", p, NULL);
-       }
-       return 0;
-}
-
-static int dbox_index_parse_line(struct dbox_index *index, const char *line,
-                                unsigned int offset)
-{
-       struct dbox_index_record rec;
-
-       memset(&rec, 0, sizeof(rec));
-       rec.file_offset = offset;
-
-       /* <file id> <status><expunges><dirty> [<status-specific data>] */
-       while (*line >= '0' && *line <= '9') {
-               rec.file_id = rec.file_id*10 + *line - '0';
-               line++;
-       }
-       if (*line++ != ' ')
-               return -1;
-
-       if ((rec.file_id & DBOX_FILE_ID_FLAG_UID) != 0) {
-               /* UID files shouldn't be listed in dbox.index */
-               return -1;
-       }
-
-       if (line[0] == '\0' || line[1] == '\0' || line[2] == '\0')
-               return -1;
-       rec.status = line[0];
-       rec.expunges = line[1] != '0';
-       rec.dirty = line[2] != '0';
-
-       line += 3;
-       if (rec.status == DBOX_INDEX_FILE_STATUS_MAILDIR) {
-               if (dbox_index_parse_maildir(index, line, &rec) < 0)
-                       return -1;
-       }
-       array_append(&index->records, &rec, 1);
-       return 0;
-}
-
-static int
-dbox_index_set_corrupted(struct dbox_index *index, const char *reason)
-{
-       mail_storage_set_critical(index->mbox->ibox.box.storage,
-                                 "dbox index %s corrupted: %s",
-                                 index->path, reason);
-
-       if (unlink(index->path) < 0 && errno != ENOENT)
-               i_error("unlink(%s) failed: %m", index->path);
-       return -1;
-}
-
-static uint32_t dbox_get_uidvalidity_next(struct mail_storage *storage)
-{
-       const char *path;
-
-       path = mailbox_list_get_path(storage->list, NULL,
-                                    MAILBOX_LIST_PATH_TYPE_CONTROL);
-       path = t_strconcat(path, "/"DBOX_UIDVALIDITY_FILE_NAME, NULL);
-       return mailbox_uidvalidity_next(path);
-}
-
-static void dbox_index_header_init(struct dbox_index *index,
-                                  struct dbox_index_file_header *hdr)
-{
-       if (index->uid_validity == 0) {
-               struct index_mailbox *ibox = &index->mbox->ibox;
-               const struct mail_index_header *idx_hdr;
-
-               idx_hdr = mail_index_get_header(ibox->view);
-               index->uid_validity = idx_hdr->uid_validity != 0 ?
-                       idx_hdr->uid_validity :
-                       dbox_get_uidvalidity_next(ibox->box.storage);
-       }
-
-       memset(hdr, ' ', sizeof(*hdr));
-       hdr->version = DBOX_INDEX_VERSION;
-       dec2hex(hdr->uid_validity_hex, index->uid_validity,
-               sizeof(hdr->uid_validity_hex));
-       dec2hex(hdr->next_uid_hex, index->next_uid, sizeof(hdr->next_uid_hex));
-       dec2hex(hdr->next_file_id_hex, index->next_file_id,
-               sizeof(hdr->next_file_id_hex));
-}
-
-static int dbox_index_parse_header(struct dbox_index *index, const char *line)
-{
-       struct dbox_index_file_header hdr;
-
-       if (strlen(line) < sizeof(hdr))
-               return dbox_index_set_corrupted(index, "Header too short");
-
-       memcpy(&hdr, line, sizeof(hdr));
-       if (hdr.version != DBOX_INDEX_VERSION)
-               return dbox_index_set_corrupted(index, "Invalid version");
-
-       index->uid_validity =
-               hex2dec(hdr.uid_validity_hex, sizeof(hdr.uid_validity_hex));
-       if (index->uid_validity == 0)
-               return dbox_index_set_corrupted(index, "uid_validity = 0");
-
-       index->next_uid = hex2dec(hdr.next_uid_hex, sizeof(hdr.next_uid_hex));
-       if (index->next_uid == 0)
-               return dbox_index_set_corrupted(index, "next_uid = 0");
-       index->next_file_id =
-               hex2dec(hdr.next_file_id_hex, sizeof(hdr.next_file_id_hex));
-       return 0;
-}
-
-static int dbox_index_read_header(struct dbox_index *index)
-{
-       const char *line;
-
-       i_stream_sync(index->input);
-       i_stream_seek(index->input, 0);
-
-       line = i_stream_read_next_line(index->input);
-       if (line == NULL)
-               return dbox_index_set_corrupted(index, "Missing header");
-       return dbox_index_parse_header(index, line);
-}
-
-static int dbox_index_read(struct dbox_index *index)
-{
-       struct istream *input;
-       const char *line;
-       uoff_t start_offset;
-       int ret;
-
-       if (index->fd != -1)
-               dbox_index_close(index);
-
-       index->fd = open(index->path, O_RDWR);
-       if (index->fd == -1) {
-               if (errno == ENOENT)
-                       return 0;
-               mail_storage_set_critical(index->mbox->ibox.box.storage,
-                                         "open(%s) failed: %m", index->path);
-               return -1;
-       }
-
-       p_clear(index->record_data_pool);
-       array_clear(&index->records);
-       input = index->input = i_stream_create_fd(index->fd, 1024, FALSE);
-
-       ret = dbox_index_read_header(index);
-       start_offset = input->v_offset;
-       while ((line = i_stream_read_next_line(input)) != NULL) {
-               if (dbox_index_parse_line(index, line, start_offset) < 0) {
-                       dbox_index_set_corrupted(index, "Corrupted record");
-                       ret = -1;
-                       break;
-               }
-               start_offset = input->v_offset;
-       }
-       return ret == 0 ? 1 :
-               (input->stream_errno == 0 ? 0 : -1);
-}
-
-static int dbox_index_read_or_create(struct dbox_index *index)
-{
-       unsigned int i;
-       int ret;
-
-       for (i = 0;; i++) {
-               if ((ret = dbox_index_read(index)) != 0)
-                       return ret;
-
-               /* doesn't exist / corrupted */
-               if (i == DBOX_INDEX_LOCK_RETRY_COUNT)
-                       break;
-
-               if (index->fd != -1)
-                       dbox_index_close(index);
-
-               T_BEGIN {
-                       ret = dbox_index_recreate(index, FALSE);
-               } T_END;
-               if (ret < 0)
-                       return -1;
-       }
-
-       mail_storage_set_critical(index->mbox->ibox.box.storage,
-               "dbox index recreation keeps failing: %s", index->path);
-       return -1;
-}
-
-static int dbox_index_refresh(struct dbox_index *index)
-{
-       struct stat st1, st2;
-
-       if (index->fd == -1) {
-               if (dbox_index_read_or_create(index) < 0)
-                       return -1;
-               i_assert(index->fd != -1);
-               return 1;
-       }
-
-       if (fstat(index->fd, &st1) < 0) {
-               mail_storage_set_critical(index->mbox->ibox.box.storage,
-                                         "fstat(%s) failed: %m", index->path);
-               return -1;
-       }
-       if (stat(index->path, &st2) < 0) {
-               mail_storage_set_critical(index->mbox->ibox.box.storage,
-                                         "stat(%s) failed: %m", index->path);
-               return -1;
-       }
-
-       if (st1.st_ino != st2.st_ino || !CMP_DEV_T(st1.st_dev, st2.st_dev)) {
-               if (dbox_index_read(index) < 0)
-                       return -1;
-               return 1;
-       }
-       return 0;
-}
-
-static int dbox_index_record_cmp(const void *key, const void *data)
-{
-       const unsigned int *file_id = key;
-       const struct dbox_index_record *rec = data;
-
-       return *file_id - rec->file_id;
-}
-
-struct dbox_index_record *
-dbox_index_record_lookup(struct dbox_index *index, unsigned int file_id)
-{
-       struct dbox_index_record *records;
-       unsigned int count;
-
-       if ((file_id & DBOX_FILE_ID_FLAG_UID) != 0)
-               return NULL;
-
-       if (index->fd == -1) {
-               if (dbox_index_refresh(index) < 0)
-                       return NULL;
-       }
-
-       records = array_get_modifiable(&index->records, &count);
-       return bsearch(&file_id, records, count, sizeof(*records),
-                      dbox_index_record_cmp);
-}
-
-static int
-dbox_index_lock_range(struct dbox_index *index, int cmd, int lock_type,
-                     off_t start, off_t len)
-{
-       struct flock fl;
-       const char *errstr;
-
-       fl.l_type = lock_type;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = start;
-       fl.l_len = len;
-       if (fcntl(index->fd, cmd, &fl) < 0) {
-               if ((errno == EACCES || errno == EAGAIN || errno == EINTR) &&
-                   cmd == F_SETLK)
-                       return 0;
-
-               errstr = errno != EACCES ? strerror(errno) :
-                       "File is locked by another process (EACCES)";
-               mail_storage_set_critical(index->mbox->ibox.box.storage,
-                       "fcntl(%s, %s) failed: %s", index->path,
-                       lock_type == F_UNLCK ? "F_UNLCK" : "F_WRLCK", errstr);
-               return -1;
-       }
-       return 1;
-}
-
-static void dbox_index_unlock_range(struct dbox_index *index,
-                                   off_t start, off_t len)
-{
-       (void)dbox_index_lock_range(index, F_SETLK, F_UNLCK, start, len);
-}
-
-static int
-dbox_index_try_lock_once(struct dbox_index *index, unsigned int file_id,
-                        enum dbox_index_file_lock_status *lock_status_r)
-{
-       struct dbox_index_record *rec;
-       int ret;
-
-       i_assert((file_id & DBOX_FILE_ID_FLAG_UID) == 0);
-
-       rec = dbox_index_record_lookup(index, file_id);
-       if (rec == NULL || rec->status == DBOX_INDEX_FILE_STATUS_UNLINKED) {
-               *lock_status_r = DBOX_INDEX_FILE_LOCK_UNLINKED;
-               return 0;
-       }
-
-       if (rec->status != DBOX_INDEX_FILE_STATUS_APPENDABLE) {
-               *lock_status_r = DBOX_INDEX_FILE_LOCK_NOT_NEEDED;
-               return 1;
-       }
-
-       /* we'll need to try to lock this record */
-       ret = dbox_index_lock_range(index, F_SETLK, F_WRLCK,
-                                   rec->file_offset, 1);
-       if (ret > 0) {
-               *lock_status_r = DBOX_INDEX_FILE_LOCKED;
-               rec->locked = TRUE;
-       } else if (ret == 0)
-               *lock_status_r = DBOX_INDEX_FILE_LOCK_TRY_AGAIN;
-       return ret;
-}
-
-int dbox_index_try_lock_file(struct dbox_index *index, unsigned int file_id,
-                            enum dbox_index_file_lock_status *lock_status_r)
-{
-       int i, ret;
-
-       if ((file_id & DBOX_FILE_ID_FLAG_UID) != 0) {
-               *lock_status_r = DBOX_INDEX_FILE_LOCK_NOT_NEEDED;
-               return 1;
-       }
-
-       if (index->fd == -1) {
-               if (dbox_index_refresh(index) < 0)
-                       return 1;
-       }
-
-       for (i = 0; i < DBOX_INDEX_LOCK_RETRY_COUNT; i++) {
-               ret = dbox_index_try_lock_once(index, file_id, lock_status_r);
-               if (ret <= 0 || *lock_status_r != DBOX_INDEX_FILE_LOCKED)
-                       return ret;
-
-               /* if file was recreated, reopen it and try again */
-               if ((ret = dbox_index_refresh(index)) <= 0)
-                       return ret < 0 ? -1 : 1;
-       }
-
-       i_warning("dbox index keeps getting recreated: %s", index->path);
-       return 0;
-}
-
-void dbox_index_unlock_file(struct dbox_index *index, unsigned int file_id)
-{
-       struct dbox_index_record *rec;
-
-       rec = dbox_index_record_lookup(index, file_id);
-       if (rec == NULL || !rec->locked)
-               return;
-
-       dbox_index_unlock_range(index, rec->file_offset, 1);
-       rec->locked = FALSE;
-}
-
-static int dbox_index_lock_header(struct dbox_index *index)
-{
-       int i, ret;
-
-       if (index->fd == -1) {
-               if (dbox_index_refresh(index) < 0)
-                       return 1;
-       }
-
-       for (i = 0; i < DBOX_INDEX_LOCK_RETRY_COUNT; i++) {
-               ret = dbox_index_lock_range(index, F_SETLKW, F_WRLCK, 0,
-                                       sizeof(struct dbox_index_file_header));
-               if (ret <= 0)
-                       return -1;
-
-               /* if file was recreated, reopen it and try again */
-               if ((ret = dbox_index_refresh(index)) <= 0)
-                       return ret < 0;
-       }
-
-       mail_storage_set_critical(index->mbox->ibox.box.storage,
-               "dbox index keeps getting recreated: %s", index->path);
-       return -1;
-}
-
-static void dbox_index_unlock_header(struct dbox_index *index)
-{
-       dbox_index_unlock_range(index, 0,
-                               sizeof(struct dbox_index_file_header));
-}
-
-static void
-dbox_index_append_record(const struct dbox_index_record *rec, string_t *str)
-{
-       str_printfa(str, "%u %c%c%c",
-                   rec->file_id, rec->status,
-                   rec->expunges ? 'E' : '0',
-                   rec->dirty ? 'D' : '0');
-
-       switch (rec->status) {
-       case DBOX_INDEX_FILE_STATUS_APPENDABLE:
-               str_append(str, " 00000000");
-               break;
-       case DBOX_INDEX_FILE_STATUS_APPENDING:
-       case DBOX_INDEX_FILE_STATUS_UNLINKED:
-               i_unreached();
-               break;
-       case DBOX_INDEX_FILE_STATUS_NONAPPENDABLE:
-       case DBOX_INDEX_FILE_STATUS_SINGLE_MESSAGE:
-               break;
-       case DBOX_INDEX_FILE_STATUS_MAILDIR:
-               str_append_c(str, ' ');
-               str_append(str, rec->data);
-               break;
-       }
-       str_append_c(str, '\n');
-}
-
-static int dbox_index_create_fd(struct dbox_mailbox *mbox, string_t *temp_path,
-                               bool locked)
-{
-       mode_t old_mask;
-       int fd;
-
-       if (locked) {
-               str_append(temp_path, ".tmp");
-               return dbox_create_fd(mbox, str_c(temp_path));
-       }
-
-       str_append_c(temp_path, '.');
-       old_mask = umask(0777 & ~mbox->ibox.box.file_create_mode);
-       fd = safe_mkstemp_hostpid(temp_path, 0777, (uid_t)-1, (gid_t)-1);
-       umask(old_mask);
-
-       if (fd == -1) {
-               mail_storage_set_critical(mbox->ibox.box.storage,
-                                         "safe_mkstemp_hostpid(%s) failed: %m",
-                                         str_c(temp_path));
-       }
-       return fd;
-}
-
-static int dbox_index_recreate(struct dbox_index *index, bool locked)
-{
-       struct mail_storage *storage = &index->mbox->storage->storage;
-       struct dbox_index_record *records;
-       struct ostream *output;
-       struct dbox_index_file_header hdr;
-       string_t *temp_path, *str;
-       unsigned int i, count;
-       int fd, ret = 0;
-
-       temp_path = t_str_new(256);
-       str_append(temp_path, index->path);
-
-       fd = dbox_index_create_fd(index->mbox, temp_path, locked);
-       if (fd == -1)
-               return -1;
-
-       str = t_str_new(256);
-       output = o_stream_create_fd_file(fd, 0, FALSE);
-       o_stream_cork(output);
-
-       dbox_index_header_init(index, &hdr);
-       o_stream_send(output, &hdr, sizeof(hdr));
-       o_stream_send(output, "\n", 1);
-
-       records = array_get_modifiable(&index->records, &count);
-       for (i = 0; i < count; ) {
-               if (records[i].status == DBOX_INDEX_FILE_STATUS_UNLINKED) {
-                       array_delete(&index->records, i, 1);
-                       records = array_get_modifiable(&index->records, &count);
-               } else {
-                       records[i].file_offset = output->offset;
-                       str_truncate(str, 0);
-                       dbox_index_append_record(&records[i], str);
-                       o_stream_send(output, str_data(str), str_len(str));
-                       i++;
-               }
-       }
-
-       if (o_stream_flush(output) < 0) {
-               mail_storage_set_critical(storage,
-                       "write(%s) failed: %m", str_c(temp_path));
-               ret = -1;
-       }
-
-       o_stream_destroy(&output);
-       if (ret == 0 && index->mbox->ibox.fsync_disable) {
-               if (fdatasync(fd) < 0) {
-                       mail_storage_set_critical(storage,
-                               "fdatasync(%s) failed: %m", str_c(temp_path));
-                       ret = -1;
-               }
-       }
-       if (close(fd) < 0) {
-               mail_storage_set_critical(storage,
-                       "close(%s) failed: %m", str_c(temp_path));
-               ret = -1;
-       }
-       if (ret == 0) {
-               if (locked) {
-                       if (rename(str_c(temp_path), index->path) < 0) {
-                               mail_storage_set_critical(storage,
-                                       "rename(%s, %s) failed: %m",
-                                       str_c(temp_path), index->path);
-                               ret = -1;
-                       }
-               } else {
-                       if (nfs_safe_link(str_c(temp_path), index->path,
-                                         TRUE) < 0 &&
-                           errno != EEXIST) {
-                               mail_storage_set_critical(storage,
-                                       "link(%s, %s) failed: %m",
-                                       str_c(temp_path), index->path);
-                               ret = -1;
-                       }
-               }
-       }
-       if (ret < 0 || !locked) {
-               if (unlink(str_c(temp_path)) < 0)
-                       i_error("unlink(%s) failed: %m", str_c(temp_path));
-       }
-       return ret;
-}
-
 struct dbox_index_append_context *
 dbox_index_append_begin(struct dbox_index *index)
 {
        struct dbox_index_append_context *ctx;
-       const void *data;
-       bool expunged;
 
        ctx = i_new(struct dbox_index_append_context, 1);
        ctx->index = index;
-       ctx->first_new_file_id = (unsigned int)-1;
+       ctx->first_new_file_id = (uint32_t)-1;
        i_array_init(&ctx->files, 64);
-
-       /* refresh the index now if there's a possibility of some appendable
-          files existing */
-       if (mail_index_view_get_messages_count(index->mbox->ibox.view) > 0) {
-               mail_index_lookup_ext(index->mbox->ibox.view, 1,
-                                     index->mbox->dbox_ext_id,
-                                     &data, &expunged);
-               if (data != NULL)
-                       (void)dbox_index_refresh(index);
-       }
        return ctx;
 }
 
-static bool
-dbox_index_append_file_record(struct dbox_index_append_context *ctx,
-                             struct dbox_index_record *record,
-                             uoff_t mail_size, struct dbox_file **file_r,
-                             struct ostream **output_r)
-{
-       struct dbox_file *const *files, *file;
-       enum dbox_index_file_lock_status lock_status;
-       unsigned int i, count;
-
-       if (record->status != DBOX_INDEX_FILE_STATUS_APPENDABLE)
-               return FALSE;
-
-       if (record->expunges)
-               return FALSE;
-
-       /* if we already have it in our files list, we already checked that
-          we can't append to it. */
-       files = array_get(&ctx->files, &count);
-       for (i = 0; i < count; i++) {
-               if (files[i]->file_id == record->file_id)
-                       return FALSE;
-       }
-       i_assert(!record->locked);
-
-       if (dbox_index_try_lock_file(ctx->index, record->file_id,
-                                    &lock_status) <= 0)
-               return FALSE;
-
-       /* open the file to see if we can append */
-       file = dbox_file_init(ctx->index->mbox, record->file_id);
-       if (dbox_file_get_append_stream(file, mail_size, output_r) <= 0) {
-               dbox_index_unlock_file(ctx->index, record->file_id);
-               dbox_file_unref(&file);
-               return FALSE;
-       }
-       *file_r = file;
-       return TRUE;
-}
-
 int dbox_index_append_next(struct dbox_index_append_context *ctx,
                           uoff_t mail_size,
                           struct dbox_file **file_r,
                           struct ostream **output_r)
 {
        struct dbox_file *const *files, *file = NULL;
-       struct dbox_index_record *records;
        unsigned int i, count;
        int ret;
 
@@ -703,13 +70,7 @@ int dbox_index_append_next(struct dbox_index_append_context *ctx,
                }
        }
 
-       /* try to find an existing appendable file */
-       records = array_get_modifiable(&ctx->index->records, &count);
-       for (i = 0; i < count; i++) {
-               if (dbox_index_append_file_record(ctx, &records[i], mail_size,
-                                                 &file, output_r))
-                       break;
-       }
+       /* FIXME: try to find an existing appendable file */
 
        if (file == NULL) {
                /* create a new file */
@@ -728,157 +89,46 @@ int dbox_index_append_next(struct dbox_index_append_context *ctx,
        return 0;
 }
 
-static const char *dbox_file_maildir_get_index_data(struct dbox_file *file)
-{
-       return t_strdup_printf("%u :%s", file->last_append_uid,
-                              file->fname);
-}
-
 static int dbox_index_append_commit_new(struct dbox_index_append_context *ctx,
-                                       struct dbox_file *file, string_t *str)
+                                       struct dbox_file *file)
 {
-       struct mail_storage *storage = &ctx->index->mbox->storage->storage;
-       struct dbox_index_record rec;
-       struct stat st;
        unsigned int file_id;
 
+       i_assert(!file->maildir_file);
        i_assert(file->append_count > 0);
 
-       if (file->append_count == 1 && !file->maildir_file &&
-           !dbox_file_can_append(file, 0)) {
+       if (file->append_count == 1 && !dbox_file_can_append(file, 0)) {
                /* single UID message file */
                i_assert(file->last_append_uid != 0);
                file_id = file->last_append_uid | DBOX_FILE_ID_FLAG_UID;
                return dbox_file_assign_id(file, file_id);
        }
 
-       if (!ctx->locked_header) {
-               if (dbox_index_lock_header(ctx->index) < 0)
-                       return -1;
-               if (dbox_index_read_header(ctx->index) < 0) {
-                       dbox_index_unlock_header(ctx->index);
-                       return -1;
-               }
-               if (fstat(ctx->index->fd, &st) < 0) {
-                       mail_storage_set_critical(storage,
-                               "fstat(%s) failed: %m", ctx->index->path);
-                       dbox_index_unlock_header(ctx->index);
-                       return -1;
-               }
-               ctx->output_offset = st.st_size;
-               ctx->new_record_idx = array_count(&ctx->index->records);
-               ctx->first_new_file_id = ctx->index->next_file_id;
-               ctx->locked_header = TRUE;
-       }
-
-       file_id = ctx->index->next_file_id++;
-       if (dbox_file_assign_id(file, file_id) < 0)
-               return -1;
-
-       memset(&rec, 0, sizeof(rec));
-       rec.file_id = file_id;
-       rec.file_offset = ctx->output_offset + str_len(str);
-       if (file->maildir_file) {
-               rec.status = DBOX_INDEX_FILE_STATUS_MAILDIR;
-               rec.data = p_strdup(ctx->index->record_data_pool,
-                                   dbox_file_maildir_get_index_data(file));
-
-       } else {
-               rec.status = dbox_file_can_append(file, 0) ?
-                       DBOX_INDEX_FILE_STATUS_APPENDABLE :
-                       DBOX_INDEX_FILE_STATUS_NONAPPENDABLE;
-       }
-
-       array_append(&ctx->index->records, &rec, 1);
-       dbox_index_append_record(&rec, str);
-       return 0;
-}
-
-static void
-dbox_index_append_rollback_commit(struct dbox_index_append_context *ctx)
-{
-       struct dbox_file *const *files;
-       unsigned int i, count;
-
-       files = array_get(&ctx->files, &count);
-       for (i = 0; i < count; i++) {
-               if (files[i]->file_id >= ctx->first_new_file_id) {
-                       if (unlink(dbox_file_get_path(files[i])) < 0) {
-                               i_error("unlink(%s) failed: %m",
-                                       dbox_file_get_path(files[i]));
-                       }
-                       files[i]->deleted = TRUE;
-               } else {
-                       /* FIXME: we should delete the appended mails.. */
-               }
-       }
-       array_delete(&ctx->index->records, ctx->new_record_idx,
-                    array_count(&ctx->index->records) - ctx->new_record_idx);
-}
-
-static int
-dbox_index_append_write_records(struct dbox_index_append_context *ctx,
-                               string_t *str)
-{
-       int ret;
-
-       ret = dbox_index_lock_range(ctx->index, F_SETLKW, F_WRLCK,
-                                   ctx->output_offset, str_len(str));
-       if (ret <= 0)
-               return -1;
-
-       if (pwrite_full(ctx->index->fd, str_data(str), str_len(str),
-                       ctx->output_offset) < 0) {
-               mail_storage_set_critical(&ctx->index->mbox->storage->storage,
-                       "pwrite(%s) failed: %m", ctx->index->path);
-               if (ftruncate(ctx->index->fd, ctx->output_offset) < 0)
-                       i_error("ftruncate(%s) failed: %m", ctx->index->path);
-               ret = -1;
-       }
-       dbox_index_unlock_range(ctx->index, ctx->output_offset, str_len(str));
-       return ret < 0 ? -1 : 0;
-}
-
-static int dbox_index_write_header(struct dbox_index *index)
-{
-       struct dbox_index_file_header hdr;
-
-       dbox_index_header_init(index, &hdr);
-       if (pwrite_full(index->fd, &hdr, sizeof(hdr), 0) < 0) {
-               mail_storage_set_critical(&index->mbox->storage->storage,
-                       "pwrite(%s) failed: %m", index->path);
-               return -1;
-       }
-       return 0;
+       /* FIXME */
+       return -1;
 }
 
 int dbox_index_append_assign_file_ids(struct dbox_index_append_context *ctx)
 {
        struct dbox_file *const *files, *file;
-       string_t *str;
        unsigned int i, count;
        int ret = 0;
 
-       str = str_new(default_pool, 1024);
        files = array_get(&ctx->files, &count);
        for (i = 0; i < count; i++) {
                file = files[i];
 
-               if (file->file_id == 0) T_BEGIN {
-                       if (dbox_index_append_commit_new(ctx, file, str) < 0)
+               if (file->file_id == 0) {
+                       if (dbox_index_append_commit_new(ctx, file) < 0) {
                                ret = -1;
-               } T_END;
+                               break;
+                       }
+               }
        }
 
-       if (ret == 0 && str_len(str) > 0) {
-               /* write the new records to index */
-               ret = dbox_index_append_write_records(ctx, str);
+       if (ret < 0) {
+               /* FIXME: we have to rollback the changes we made */
        }
-       if (ret < 0 && str_len(str) > 0) {
-               /* we have to rollback changes we made */
-               dbox_index_append_rollback_commit(ctx);
-       }
-       str_free(&str);
        return ret;
 }
 
@@ -887,24 +137,12 @@ int dbox_index_append_commit(struct dbox_index_append_context **_ctx)
        struct dbox_index_append_context *ctx = *_ctx;
        struct dbox_file **files;
        unsigned int i, count;
-       int ret = 0;
 
        *_ctx = NULL;
 
        files = array_get_modifiable(&ctx->files, &count);
-       for (i = 0; i < count; i++) {
-               if (files[i]->file_id < ctx->first_new_file_id) {
-                       /* FIXME: update status */
-                       dbox_index_unlock_file(ctx->index, files[i]->file_id);
-               }
+       for (i = 0; i < count; i++)
                dbox_file_unref(&files[i]);
-       }
-
-       if (ctx->locked_header) {
-               if (dbox_index_write_header(ctx->index) < 0)
-                       ret = -1;
-               dbox_index_unlock_header(ctx->index);
-       }
 
        array_free(&ctx->files);
        i_free(ctx);
@@ -923,9 +161,9 @@ void dbox_index_append_rollback(struct dbox_index_append_context **_ctx)
        for (i = 0; i < count; i++) {
                file = files[i];
 
-               if (file->file_id != 0)
-                       dbox_index_unlock_file(ctx->index, file->file_id);
-               else {
+               if (file->file_id != 0) {
+                       /* FIXME: truncate? */
+               else {
                        if (unlink(dbox_file_get_path(file)) < 0) {
                                i_error("unlink(%s) failed: %m",
                                        dbox_file_get_path(file));
index 7be931a3d9ace0c327550d918c00b03f8a87cbb6..721f834f9f534f32a0091432f7e659de8c8aa024 100644 (file)
 #ifndef DBOX_INDEX_H
 #define DBOX_INDEX_H
 
-/* The file begins with a header followed by zero or more records:
-
-   <file id> <status><expunges><dirty> [<status-specific data>]<LF>
-
-   <expunges> contains either '0' = no or 'E' = file contains messages marked
-   as expunged, which should be removed when possible.
-
-   <dirty> contains either '0' = no or 'D' = file contains messages that don't
-   have up-to-date metadata. When expunge copies message data to a new file,
-   the dirty state should be flushed for the copied messages (or the dirty
-   state should be copied).
-
-   <expunges> and <dirty> can be written without locking the record, so syncing
-   can update them even while messages are being appended to the file.
-
-   If status-specific data isn't specified for the given status, it should be
-   ignored. Especially 'U' status may contain different kinds of data.
-*/
-
 struct dbox_file;
 struct dbox_index_append_context;
 
-#define DBOX_INDEX_VERSION     '1'
-
-enum dbox_index_file_status {
-       /* File can be appended to as long as <expunges> is zero. It must be
-          locked when expunging. status-specific data contains a %08x lock
-          timestamp. */
-       DBOX_INDEX_FILE_STATUS_APPENDABLE       = '0',
-       /* File is currently being appended to. If this record can be locked,
-          the append crashed and this file should be opened for fixing
-          (truncate non-committed appends from the file). */
-       DBOX_INDEX_FILE_STATUS_APPENDING        = 'A',
-       /* File can't be appended to. */
-       DBOX_INDEX_FILE_STATUS_NONAPPENDABLE    = 'N',
-       /* File contains only a single message. It can't be appended to
-          and it can be expunged by unlinking the file. */
-       DBOX_INDEX_FILE_STATUS_SINGLE_MESSAGE   = '1',
-       /* The file has already been unlinked, this record should be removed. */
-       DBOX_INDEX_FILE_STATUS_UNLINKED         = 'U',
-
-       /* File is a maildir file. Status-specific data contains
-          old: <uid> <filename>
-          new: <uid> [<maildir extra field>] :<filename>
-       */
-       DBOX_INDEX_FILE_STATUS_MAILDIR          = 'M'
-};
-
-enum dbox_index_file_lock_status {
-       /* File was locked (ret=1) */
-       DBOX_INDEX_FILE_LOCKED,
-       /* File didn't have appendable status (ret=1) */
-       DBOX_INDEX_FILE_LOCK_NOT_NEEDED,
-       /* File was already locked by someone else (ret=0) */
-       DBOX_INDEX_FILE_LOCK_TRY_AGAIN,
-       /* File is already unlinked (ret=0) */
-       DBOX_INDEX_FILE_LOCK_UNLINKED
-};
-
-struct dbox_index_file_header {
-       /* DBOX_INDEX_VERSION */
-       unsigned char version;
-       unsigned char space_1;
-
-       /* Current UIDVALIDITY */
-       unsigned char uid_validity_hex[8];
-       unsigned char space_2;
-
-       /* Next available message UID */
-       unsigned char next_uid_hex[8];
-       unsigned char space_3;
-
-       /* Next available <file id> */
-       unsigned char next_file_id_hex[8];
-};
-
-struct dbox_index_record {
-       unsigned int file_id;
-       unsigned int file_offset;
-
-       enum dbox_index_file_status status;
-       const char *data;
-
-       unsigned int expunges:1;
-       unsigned int dirty:1;
-       unsigned int locked:1;
-};
-
 struct dbox_index *dbox_index_init(struct dbox_mailbox *mbox);
 void dbox_index_deinit(struct dbox_index **index);
 
-struct dbox_index_record *
-dbox_index_record_lookup(struct dbox_index *index, unsigned int file_id);
-
-/* Try to lock a file record. Only appendable files are actually locked.
-   Returns 1 if lock acquired or not needed, 0 if we failed to get a lock or
-   file is unlinked, -1 if error. lock_status_r is set if 0 or 1 is returned. */
-int dbox_index_try_lock_file(struct dbox_index *index, unsigned int file_id,
-                            enum dbox_index_file_lock_status *lock_status_r);
-void dbox_index_unlock_file(struct dbox_index *index, unsigned int file_id);
-
 struct dbox_index_append_context *
 dbox_index_append_begin(struct dbox_index *index);
 /* Request file for saving a new message with given size. If an existing file
index fe837d95d67b924447b3937644976ee906baf3d6..d5d20b57e60b82f2e23c3d62dd128a01b451bb12 100644 (file)
@@ -10,7 +10,6 @@
 #define DBOX_INDEX_PREFIX "dovecot.index"
 
 #define DBOX_MAILDIR_NAME "dbox-Mails"
-#define DBOX_INDEX_NAME "dbox.index"
 #define DBOX_MAIL_FILE_MULTI_PREFIX "m."
 #define DBOX_MAIL_FILE_UID_PREFIX "u."
 #define DBOX_MAIL_FILE_MULTI_FORMAT DBOX_MAIL_FILE_MULTI_PREFIX"%u"
index f1acb689003de2b6efb27348e8b7dcfee506880b..4654bd30a29ad79fe72fb47ca0c2c4288b6c78b8 100644 (file)
@@ -6,7 +6,6 @@
 #include "ostream.h"
 #include "str.h"
 #include "dbox-storage.h"
-#include "dbox-index.h"
 #include "dbox-file.h"
 #include "dbox-sync.h"
 
@@ -52,6 +51,8 @@ dbox_sync_file_expunge(struct dbox_sync_context *ctx, struct dbox_file *file,
        bool expunged;
        int ret;
 
+       /* FIXME: lock the file first */
+
        expunges = array_get(&entry->expunges, &count);
        if (!dbox_file_lookup(ctx->mbox, ctx->sync_view, expunges[0].seq1,
                              &file_id, &first_offset))
@@ -276,29 +277,11 @@ int dbox_sync_file(struct dbox_sync_context *ctx,
                   const struct dbox_sync_file_entry *entry)
 {
        struct dbox_file *file;
-       struct dbox_index_record *rec;
-       enum dbox_index_file_status status;
-       bool locked, deleted;
+       bool deleted;
        int ret;
 
-       if ((entry->file_id & DBOX_FILE_ID_FLAG_UID) != 0) {
-               locked = TRUE;
-               status = DBOX_INDEX_FILE_STATUS_SINGLE_MESSAGE;
-       } else {
-               rec = dbox_index_record_lookup(ctx->mbox->dbox_index,
-                                              entry->file_id);
-               if (rec == NULL ||
-                   rec->status == DBOX_INDEX_FILE_STATUS_UNLINKED) {
-                       /* file doesn't exist, nothing to do */
-                       return 1;
-               }
-               locked = rec->locked;
-               status = rec->status;
-       }
-
        file = dbox_file_init(ctx->mbox, entry->file_id);
-       if ((status == DBOX_INDEX_FILE_STATUS_SINGLE_MESSAGE ||
-            status == DBOX_INDEX_FILE_STATUS_MAILDIR) &&
+       if ((file->file_id & DBOX_FILE_ID_FLAG_UID) != 0 &&
            array_is_created(&entry->expunges)) {
                /* fast path to expunging the whole file */
                if ((ret = dbox_sync_file_unlink(file)) == 0) {
@@ -310,7 +293,7 @@ int dbox_sync_file(struct dbox_sync_context *ctx,
                ret = dbox_file_open_or_create(file, TRUE, &deleted);
                if (ret > 0 && !deleted) {
                        dbox_sync_file_move_if_needed(file, entry);
-                       if (array_is_created(&entry->expunges) && locked)
+                       if (array_is_created(&entry->expunges))
                                ret = dbox_sync_file_expunge(ctx, file, entry);
                }
        }