From: Timo Sirainen Date: Fri, 9 Jul 2010 14:39:03 +0000 (+0100) Subject: dbox: dbox_file_move() was used by only single-dbox, so moved it there. X-Git-Tag: 2.0.rc2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c2d2161296e2361f97ee48b70b168602157069e6;p=thirdparty%2Fdovecot%2Fcore.git dbox: dbox_file_move() was used by only single-dbox, so moved it there. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-common/dbox-file.c b/src/lib-storage/index/dbox-common/dbox-file.c index dacaf5c507..b56aa50b83 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.c +++ b/src/lib-storage/index/dbox-common/dbox-file.c @@ -11,7 +11,6 @@ #include "file-lock.h" #include "file-dotlock.h" #include "mkdir-parents.h" -#include "fdatasync-path.h" #include "eacces-error.h" #include "str.h" #include "dbox-storage.h" @@ -678,116 +677,6 @@ const char *dbox_file_metadata_get(struct dbox_file *file, return NULL; } -int dbox_file_move(struct dbox_file *file, bool alt_path) -{ - struct mail_storage *storage = &file->storage->storage; - struct ostream *output; - const char *dest_dir, *temp_path, *dest_path, *p; - struct stat st; - bool deleted; - int out_fd, ret = 0; - - i_assert(file->input != NULL); - - if (dbox_file_is_in_alt(file) == alt_path) - return 0; - - if (stat(file->cur_path, &st) < 0 && errno == ENOENT) { - /* already expunged/moved by another session */ - dbox_file_unlock(file); - return 0; - } - - dest_path = !alt_path ? file->primary_path : file->alt_path; - p = strrchr(dest_path, '/'); - i_assert(p != NULL); - dest_dir = t_strdup_until(dest_path, p); - temp_path = t_strdup_printf("%s/%s", dest_dir, - dbox_generate_tmp_filename()); - - /* first copy the file. make sure to catch every possible error - since we really don't want to break the file. */ - out_fd = file->storage->v.file_create_fd(file, temp_path, TRUE); - if (out_fd == -1) - return -1; - - output = o_stream_create_fd_file(out_fd, 0, FALSE); - i_stream_seek(file->input, 0); - while ((ret = o_stream_send_istream(output, file->input)) > 0) ; - if (ret == 0) - ret = o_stream_flush(output); - if (output->stream_errno != 0) { - errno = output->stream_errno; - mail_storage_set_critical(storage, "write(%s) failed: %m", - temp_path); - ret = -1; - } else if (file->input->stream_errno != 0) { - errno = file->input->stream_errno; - dbox_file_set_syscall_error(file, "ftruncate()"); - ret = -1; - } else if (ret < 0) { - mail_storage_set_critical(storage, - "o_stream_send_istream(%s, %s) " - "failed with unknown error", - temp_path, file->cur_path); - } - o_stream_unref(&output); - - if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER && ret == 0) { - if (fsync(out_fd) < 0) { - mail_storage_set_critical(storage, - "fsync(%s) failed: %m", temp_path); - ret = -1; - } - } - if (close(out_fd) < 0) { - mail_storage_set_critical(storage, - "close(%s) failed: %m", temp_path); - ret = -1; - } - if (ret < 0) { - (void)unlink(temp_path); - return -1; - } - - /* the temp file was successfully written. rename it now to the - destination file. the destination shouldn't exist, but if it does - its contents should be the same (except for maybe older metadata) */ - if (rename(temp_path, dest_path) < 0) { - mail_storage_set_critical(storage, - "rename(%s, %s) failed: %m", temp_path, dest_path); - (void)unlink(temp_path); - return -1; - } - if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER) { - if (fdatasync_path(dest_dir) < 0) { - mail_storage_set_critical(storage, - "fdatasync(%s) failed: %m", dest_dir); - (void)unlink(dest_path); - return -1; - } - } - if (unlink(file->cur_path) < 0) { - dbox_file_set_syscall_error(file, "unlink()"); - if (errno == EACCES) { - /* configuration problem? revert the write */ - (void)unlink(dest_path); - } - /* who knows what happened to the file. keep both just to be - sure both won't get deleted. */ - return -1; - } - - /* file was successfully moved - reopen it */ - dbox_file_close(file); - if (dbox_file_open(file, &deleted) <= 0) { - mail_storage_set_critical(storage, - "dbox_file_move(%s): reopening file failed", dest_path); - return -1; - } - return 0; -} - void dbox_msg_header_fill(struct dbox_message_header *dbox_msg_hdr, uoff_t message_size) { diff --git a/src/lib-storage/index/dbox-common/dbox-file.h b/src/lib-storage/index/dbox-common/dbox-file.h index 77e7ea6d90..316610b158 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.h +++ b/src/lib-storage/index/dbox-common/dbox-file.h @@ -184,8 +184,6 @@ int dbox_file_metadata_read(struct dbox_file *file); const char *dbox_file_metadata_get(struct dbox_file *file, enum dbox_metadata_key key); -/* Move the file to alt path or back. */ -int dbox_file_move(struct dbox_file *file, bool alt_path); /* Fix a broken dbox file by rename()ing over it with a fixed file. Everything before start_offset is assumed to be valid and is simply copied. The file is reopened afterwards. Returns 0 if ok, -1 if I/O error. */ diff --git a/src/lib-storage/index/dbox-single/sdbox-file.c b/src/lib-storage/index/dbox-single/sdbox-file.c index 22210b33a4..4f2d202f03 100644 --- a/src/lib-storage/index/dbox-single/sdbox-file.c +++ b/src/lib-storage/index/dbox-single/sdbox-file.c @@ -2,7 +2,10 @@ #include "lib.h" #include "eacces-error.h" +#include "fdatasync-path.h" #include "mkdir-parents.h" +#include "istream.h" +#include "ostream.h" #include "sdbox-storage.h" #include "sdbox-file.h" @@ -126,3 +129,112 @@ int sdbox_file_create_fd(struct dbox_file *file, const char *path, bool parents) } return fd; } + +int sdbox_file_move(struct dbox_file *file, bool alt_path) +{ + struct mail_storage *storage = &file->storage->storage; + struct ostream *output; + const char *dest_dir, *temp_path, *dest_path, *p; + struct stat st; + bool deleted; + int out_fd, ret = 0; + + i_assert(file->input != NULL); + + if (dbox_file_is_in_alt(file) == alt_path) + return 0; + + if (stat(file->cur_path, &st) < 0 && errno == ENOENT) { + /* already expunged/moved by another session */ + return 0; + } + + dest_path = !alt_path ? file->primary_path : file->alt_path; + p = strrchr(dest_path, '/'); + i_assert(p != NULL); + dest_dir = t_strdup_until(dest_path, p); + temp_path = t_strdup_printf("%s/%s", dest_dir, + dbox_generate_tmp_filename()); + + /* first copy the file. make sure to catch every possible error + since we really don't want to break the file. */ + out_fd = file->storage->v.file_create_fd(file, temp_path, TRUE); + if (out_fd == -1) + return -1; + + output = o_stream_create_fd_file(out_fd, 0, FALSE); + i_stream_seek(file->input, 0); + while ((ret = o_stream_send_istream(output, file->input)) > 0) ; + if (ret == 0) + ret = o_stream_flush(output); + if (output->stream_errno != 0) { + errno = output->stream_errno; + mail_storage_set_critical(storage, "write(%s) failed: %m", + temp_path); + ret = -1; + } else if (file->input->stream_errno != 0) { + errno = file->input->stream_errno; + dbox_file_set_syscall_error(file, "ftruncate()"); + ret = -1; + } else if (ret < 0) { + mail_storage_set_critical(storage, + "o_stream_send_istream(%s, %s) " + "failed with unknown error", + temp_path, file->cur_path); + } + o_stream_unref(&output); + + if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER && ret == 0) { + if (fsync(out_fd) < 0) { + mail_storage_set_critical(storage, + "fsync(%s) failed: %m", temp_path); + ret = -1; + } + } + if (close(out_fd) < 0) { + mail_storage_set_critical(storage, + "close(%s) failed: %m", temp_path); + ret = -1; + } + if (ret < 0) { + (void)unlink(temp_path); + return -1; + } + + /* the temp file was successfully written. rename it now to the + destination file. the destination shouldn't exist, but if it does + its contents should be the same (except for maybe older metadata) */ + if (rename(temp_path, dest_path) < 0) { + mail_storage_set_critical(storage, + "rename(%s, %s) failed: %m", temp_path, dest_path); + (void)unlink(temp_path); + return -1; + } + if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER) { + if (fdatasync_path(dest_dir) < 0) { + mail_storage_set_critical(storage, + "fdatasync(%s) failed: %m", dest_dir); + (void)unlink(dest_path); + return -1; + } + } + if (unlink(file->cur_path) < 0) { + dbox_file_set_syscall_error(file, "unlink()"); + if (errno == EACCES) { + /* configuration problem? revert the write */ + (void)unlink(dest_path); + } + /* who knows what happened to the file. keep both just to be + sure both won't get deleted. */ + return -1; + } + + /* file was successfully moved - reopen it */ + dbox_file_close(file); + if (dbox_file_open(file, &deleted) <= 0) { + mail_storage_set_critical(storage, + "dbox_file_move(%s): reopening file failed", dest_path); + return -1; + } + return 0; +} diff --git a/src/lib-storage/index/dbox-single/sdbox-file.h b/src/lib-storage/index/dbox-single/sdbox-file.h index 4d4c088100..fb12f70d70 100644 --- a/src/lib-storage/index/dbox-single/sdbox-file.h +++ b/src/lib-storage/index/dbox-single/sdbox-file.h @@ -19,5 +19,7 @@ int sdbox_file_assign_uid(struct sdbox_file *file, uint32_t uid); int sdbox_file_create_fd(struct dbox_file *file, const char *path, bool parents); +/* Move the file to alt path or back. */ +int sdbox_file_move(struct dbox_file *file, bool alt_path); #endif diff --git a/src/lib-storage/index/dbox-single/sdbox-sync.c b/src/lib-storage/index/dbox-single/sdbox-sync.c index d6334a0221..f191d394cf 100644 --- a/src/lib-storage/index/dbox-single/sdbox-sync.c +++ b/src/lib-storage/index/dbox-single/sdbox-sync.c @@ -18,7 +18,7 @@ dbox_sync_file_move_if_needed(struct dbox_file *file, /* move the file. if it fails, nothing broke so don't worry about it. */ if (dbox_file_open(file, &deleted) > 0 && !deleted) - (void)dbox_file_move(file, move_to_alt); + (void)sdbox_file_move(file, move_to_alt); } }