item = g_hash_table_lookup(fs->locations, &id);
if (item == NULL) {
item = bluesky_cloudlog_new(fs, &id);
+ bluesky_cloudlog_stats_update(item, 1);
bluesky_cloudlog_insert_locked(item);
} else {
bluesky_cloudlog_ref(item);
* Once that is done, we can fall through the case of remapping the data
* itself. */
if (log->type == LOGTYPE_UNKNOWN) {
- BlueSkyRCStr *raw = NULL;
- if ((log->location_flags | log->pending_write) & CLOUDLOG_JOURNAL) {
- raw = bluesky_log_map_object(log->fs, -1, log->log_seq,
- log->log_offset, log->log_size);
- }
-
- if (raw == NULL && (log->location_flags & CLOUDLOG_CLOUD)) {
- log->location_flags &= ~CLOUDLOG_JOURNAL;
- raw = bluesky_log_map_object(log->fs,
- log->location.directory,
- log->location.sequence,
- log->location.offset,
- log->location.size);
- }
-
+ BlueSkyRCStr *raw = bluesky_log_map_object(log, FALSE);
g_assert(raw != NULL);
bluesky_deserialize_cloudlog(log, raw->data, raw->len);
bluesky_string_unref(raw);
/* At this point all metadata should be available and we need only remap
* the object data. */
-
- int offset;
- if ((log->location_flags | log->pending_write) & CLOUDLOG_JOURNAL) {
- bluesky_cloudlog_stats_update(log, -1);
- offset = log->log_offset + sizeof(struct log_header);
- log->data = bluesky_log_map_object(log->fs, -1, log->log_seq,
- offset, log->data_size);
- bluesky_cloudlog_stats_update(log, 1);
- }
-
- if (log->data == NULL && (log->location_flags & CLOUDLOG_CLOUD)) {
- log->location_flags &= ~CLOUDLOG_JOURNAL;
- bluesky_cloudlog_stats_update(log, -1);
- offset = log->location.offset + sizeof(struct cloudlog_header);
- log->data = bluesky_log_map_object(log->fs, log->location.directory,
- log->location.sequence,
- offset, log->data_size);
- bluesky_cloudlog_stats_update(log, 1);
- }
+ log->data = bluesky_log_map_object(log, TRUE);
if (log->data == NULL) {
g_error("Unable to fetch cloudlog entry!");
g_mutex_lock(fs->lock);
InodeMapEntry *entry = bluesky_inode_map_lookup(fs->inode_map,
log->inum, 1);
+ bluesky_cloudlog_unref_delayed(entry->item);
entry->item = log;
bluesky_cloudlog_ref(entry->item);
g_mutex_unlock(fs->lock);
g_print("Serializing %zd bytes of data to cloud\n", state->data->len);
SerializedRecord *record = g_new0(SerializedRecord, 1);
+ bluesky_cloudlog_encrypt(state->data, fs->keys);
record->data = bluesky_string_new_from_gstring(state->data);
record->items = state->writeback_list;
record->lock = g_mutex_new();
state->location.offset = 0;
state->data = g_string_new("");
}
+
+/* Make an encryption pass over a cloud log segment to encrypt private data in
+ * it. */
+void bluesky_cloudlog_encrypt(GString *segment, BlueSkyCryptKeys *keys)
+{
+ char *data = segment->str;
+ size_t remaining_size = segment->len;
+
+ while (remaining_size >= sizeof(struct cloudlog_header)) {
+ struct cloudlog_header *header = (struct cloudlog_header *)data;
+ size_t item_size = sizeof(struct cloudlog_header)
+ + GUINT32_FROM_LE(header->size1)
+ + GUINT32_FROM_LE(header->size2)
+ + GUINT32_FROM_LE(header->size3);
+ if (item_size > remaining_size)
+ break;
+ bluesky_crypt_block_encrypt(data, item_size, keys);
+
+ data += item_size;
+ remaining_size -= item_size;
+ }
+}
+
+/* Make an decryption pass over a cloud log segment to decrypt items which were
+ * encrypted. Also computes a list of all offsets which at which valid
+ * cloud log items are found and adds those offsets to items (if non-NULL). */
+void bluesky_cloudlog_decrypt(char *segment, size_t len,
+ BlueSkyCryptKeys *keys,
+ BlueSkyRangeset *items)
+{
+ char *data = segment;
+ size_t remaining_size = len;
+ size_t offset = 0;
+
+ while (remaining_size >= sizeof(struct cloudlog_header)) {
+ struct cloudlog_header *header = (struct cloudlog_header *)data;
+ size_t item_size = sizeof(struct cloudlog_header)
+ + GUINT32_FROM_LE(header->size1)
+ + GUINT32_FROM_LE(header->size2)
+ + GUINT32_FROM_LE(header->size3);
+ if (item_size > remaining_size)
+ break;
+ if (bluesky_crypt_block_decrypt(data, item_size, keys)) {
+ if (items != NULL) {
+ g_print(" data item at %zx\n", offset);
+ bluesky_rangeset_insert(items, offset, item_size,
+ GINT_TO_POINTER(TRUE));
+ }
+ } else {
+ g_warning("Unauthenticated data at offset %zd", offset);
+ if (items != NULL) {
+ bluesky_rangeset_insert(items, offset, item_size,
+ GINT_TO_POINTER(TRUE));
+ }
+ }
+
+ data += item_size;
+ offset += item_size;
+ remaining_size -= item_size;
+ }
+}