diff --git a/src/storage-rbox/rbox-copy.cpp b/src/storage-rbox/rbox-copy.cpp index b223a8df..70430c13 100644 --- a/src/storage-rbox/rbox-copy.cpp +++ b/src/storage-rbox/rbox-copy.cpp @@ -115,7 +115,7 @@ static int rbox_mail_storage_try_copy(struct mail_save_context **_ctx, struct ma FUNC_END_RET("ret == -1, mail_save_copy_default_metadata failed"); return -1; } - + librados::ObjectWriteOperation write_op; if (ctx->moving != TRUE) { rbox_add_to_index(ctx); index_copy_cache_fields(ctx, mail, r_ctx->seq); @@ -124,7 +124,6 @@ static int rbox_mail_storage_try_copy(struct mail_save_context **_ctx, struct ma std::string src_oid = rmail->mail_object->get_oid(); std::string dest_oid = r_ctx->current_object->get_oid(); i_debug("rbox_mail_storage_try_copy: from source %s to dest %s", src_oid.c_str(), dest_oid.c_str()); - librados::ObjectWriteOperation write_op; if (strcmp(ns_src_mail, ns_dest_mail) != 0) { src_io_ctx.dup(dest_io_ctx); @@ -136,6 +135,15 @@ static int rbox_mail_storage_try_copy(struct mail_save_context **_ctx, struct ma i_debug("ns_compare: %s %s", ns_src_mail, ns_dest_mail); write_op.copy_from(src_oid, src_io_ctx, src_io_ctx.get_last_version()); + // we need to update the mailbox x attr. + { + std::string key(1, (char)RBOX_METADATA_MAILBOX_GUID); + librados::bufferlist bl; + struct rbox_mailbox *r_ctx = (struct rbox_mailbox *)ctx->dest_mail->box; + bl.append(guid_128_to_string(r_ctx->mailbox_guid)); + write_op.setxattr(key.c_str(), bl); + } + // because we create a copy, save date needs to be updated // as an alternative we could use &ctx->data.save_date here if we save it to xattribute in write_metadata // and restore it in read_metadata function. => save_date of copy/move will be same as source. @@ -143,10 +151,10 @@ static int rbox_mail_storage_try_copy(struct mail_save_context **_ctx, struct ma time_t save_time = time(NULL); write_op.mtime(&save_time); - i_debug("cpy_time: oid: %s, save_date: %s", src_oid.c_str(), std::ctime(&rmail->imail.data.save_date)); + i_debug("cpy_time: oid: %s, save_date: %s", src_oid.c_str(), std::ctime(&save_time)); ret_val = dest_io_ctx.operate(dest_oid, &write_op); - i_debug("copy finished: oid = %s, ret_val = %d, mtime = %ld", src_oid.c_str(), ret_val, ctx->data.save_date); + i_debug("copy finished: oid = %s, ret_val = %d, mtime = %ld", src_oid.c_str(), ret_val, save_time); // reset io_ctx dest_io_ctx.set_namespace(ns_src_mail); @@ -159,6 +167,17 @@ static int rbox_mail_storage_try_copy(struct mail_save_context **_ctx, struct ma rbox_move_index(ctx); index_copy_cache_fields(ctx, mail, r_ctx->seq); mail_set_seq_saving(ctx->dest_mail, r_ctx->seq); + + // we need to update the mailbox x attr. + { + std::string key(1, (char)RBOX_METADATA_MAILBOX_GUID); + librados::bufferlist bl; + struct rbox_mailbox *r_ctx = (struct rbox_mailbox *)ctx->dest_mail->box; + bl.append(guid_128_to_string(r_ctx->mailbox_guid)); + write_op.setxattr(key.c_str(), bl); + int ret_val = dest_io_ctx.operate(src_oid, &write_op); + i_debug("move finished: oid = %s, ret_val = %d", src_oid.c_str(), ret_val); + } } } FUNC_END(); diff --git a/src/storage-rbox/rbox-mail.cpp b/src/storage-rbox/rbox-mail.cpp index 6bc973e3..38610852 100644 --- a/src/storage-rbox/rbox-mail.cpp +++ b/src/storage-rbox/rbox-mail.cpp @@ -179,6 +179,10 @@ static int rbox_mail_get_save_date(struct mail *_mail, time_t *date_r) { return 0; } + if (rbox_open_rados_connection(_mail->box) < 0) { + FUNC_END_RET("ret == -1; connection to rados failed"); + return -1; + } uint64_t object_size = 0; time_t save_date_rados = 0; int ret_val = ((r_storage->s)->get_io_ctx()).stat(rmail->mail_object->get_oid(), &object_size, &save_date_rados); @@ -222,6 +226,12 @@ static int rbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { return 0; } + + if (rbox_open_rados_connection(_mail->box) < 0) { + FUNC_END_RET("ret == -1; connection to rados failed"); + return -1; + } + int ret_val = ((r_storage->s)->get_io_ctx()).stat(rmail->mail_object->get_oid(), &file_size, &time); if (ret_val < 0) { if (ret_val == ((-1) * ENOENT)) { diff --git a/src/storage-rbox/rbox-mail.h b/src/storage-rbox/rbox-mail.h index 50cf009a..55631644 100644 --- a/src/storage-rbox/rbox-mail.h +++ b/src/storage-rbox/rbox-mail.h @@ -8,6 +8,10 @@ #include "rados-mail-object.h" enum rbox_metadata_key { + /* + * mailbox global unique id the mail currently is in. + */ + RBOX_METADATA_MAILBOX_GUID = 'M', /* Globally unique identifier for the message. Preserved when copying. */ RBOX_METADATA_GUID = 'G', diff --git a/src/storage-rbox/rbox-save.cpp b/src/storage-rbox/rbox-save.cpp index ee2fda3f..4ee03938 100644 --- a/src/storage-rbox/rbox-save.cpp +++ b/src/storage-rbox/rbox-save.cpp @@ -160,7 +160,7 @@ int rbox_save_begin(struct mail_save_context *_ctx, struct istream *input) { r_ctx->failed = FALSE; if (rbox_open_rados_connection(_ctx->dest_mail->box) < 0) { - FUNC_END_RET("ret == -1 connection to rados failed"); + FUNC_END_RET("ret == -1 connection to rados failed"); return -1; } @@ -250,6 +250,14 @@ int rbox_save_mail_write_metadata(struct rbox_save_context *ctx, librados::Objec version_bl.append(RadosMailObject::X_ATTR_VERSION_VALUE); write_op_xattr->setxattr(key.c_str(), version_bl); } + + { + std::string key(1, (char)RBOX_METADATA_MAILBOX_GUID); + bufferlist bl; + bl.append(guid_128_to_string(ctx->mbox->mailbox_guid)); + write_op_xattr->setxattr(key.c_str(), bl); + } + { std::string key(1, (char)RBOX_METADATA_GUID); bufferlist bl; @@ -452,7 +460,7 @@ int rbox_save_finish(struct mail_save_context *_ctx) { buffer_t *mail_buffer = (buffer_t *)r_ctx->current_object->get_mail_buffer(); size_t write_buffer_size = buffer_get_used_size(mail_buffer); - + rbox_save_mail_write_metadata(r_ctx, write_op_xattr, write_buffer_size); int max_write_size = r_storage->s->get_max_write_size_bytes(); i_debug("OSD_MAX_WRITE_SIZE=%dmb", (max_write_size / 1024 / 1024));