Improve object deserialization: properly parse object headers.
[bluesky.git] / bluesky / log.c
index f8062cf..7f2eea4 100644 (file)
 #define HEADER_MAGIC 0x676f4c0a
 #define FOOTER_MAGIC 0x2e435243
 
-struct log_header {
-    uint32_t magic;             // HEADER_MAGIC
-    uint8_t type;               // Object type + '0'
-    uint32_t offset;            // Starting byte offset of the log header
-    uint32_t size1;             // Size of the data item (bytes)
-    uint32_t size2;             //
-    uint32_t size3;             //
-    uint64_t inum;              // Inode which owns this data, if any
-    BlueSkyCloudID id;          // Object identifier
-} __attribute__((packed));
-
-struct log_footer {
-    uint32_t magic;             // FOOTER_MAGIC
-    uint32_t crc;               // Computed from log_header to log_footer.magic
-} __attribute__((packed));
-
 static void writebuf(int fd, const char *buf, size_t len)
 {
     while (len > 0) {
@@ -226,10 +210,11 @@ static gpointer log_thread(gpointer d)
         writebuf(log->fd, (const char *)&footer, sizeof(footer));
 
         item->log_seq = log->seq_num;
-        item->log_offset = offset + sizeof(header);
-        item->log_size = item->data->len;
+        item->log_offset = offset;
+        item->log_size = size;
+        item->data_size = item->data->len;
 
-        offset += sizeof(header) + sizeof(footer) + item->data->len;
+        offset += size;
 
         g_string_free(data1, TRUE);
         g_string_free(data2, TRUE);
@@ -718,18 +703,8 @@ static void bluesky_replay_scan_journal2(BlueSkyFS *fs, GList **objects,
                        + GUINT32_FROM_LE(header->size2)
                        + GUINT32_FROM_LE(header->size3);
 
-        g_mutex_lock(fs->lock);
-        BlueSkyCloudLog *log_item;
-        log_item = g_hash_table_lookup(fs->locations, &header->id);
-        if (log_item == NULL) {
-            log_item = bluesky_cloudlog_new(fs, &header->id);
-            g_hash_table_insert(fs->locations, &log_item->id, log_item);
-            g_mutex_lock(log_item->lock);
-        } else {
-            bluesky_cloudlog_ref(log_item);
-            g_mutex_lock(log_item->lock);
-        }
-        g_mutex_unlock(fs->lock);
+        BlueSkyCloudLog *log_item = bluesky_cloudlog_get(fs, header->id);
+        g_mutex_lock(log_item->lock);
         *objects = g_list_prepend(*objects, log_item);
 
         log_item->inum = GUINT64_FROM_LE(header->inum);
@@ -757,9 +732,20 @@ static void bluesky_replay_scan_journal2(BlueSkyFS *fs, GList **objects,
                 bluesky_insert_inode(fs, inode);
             }
             g_mutex_lock(inode->lock);
+            bluesky_inode_free_resources(inode);
             if (!bluesky_deserialize_inode(inode, log_item))
                 g_print("Error deserializing inode %"PRIu64"\n", inum);
             fs->next_inum = MAX(fs->next_inum, inum + 1);
+            bluesky_list_unlink(&fs->accessed_list, inode->accessed_list);
+            inode->accessed_list = bluesky_list_prepend(&fs->accessed_list, inode);
+            bluesky_list_unlink(&fs->dirty_list, inode->dirty_list);
+            inode->dirty_list = bluesky_list_prepend(&fs->dirty_list, inode);
+            bluesky_list_unlink(&fs->unlogged_list, inode->unlogged_list);
+            inode->unlogged_list = NULL;
+            inode->change_cloud = inode->change_commit;
+            bluesky_cloudlog_ref(log_item);
+            bluesky_cloudlog_unref(inode->committed_item);
+            inode->committed_item = log_item;
             g_mutex_unlock(inode->lock);
             g_mutex_unlock(fs->lock);
         }