Start at writing out inode maps to cloud storage.
[bluesky.git] / bluesky / imap.c
index e9dd1d9..484f24f 100644 (file)
@@ -70,7 +70,7 @@ InodeMapEntry *bluesky_inode_map_lookup(GSequence *inode_map, uint64_t inum,
         range->start = 0;
         range->end = G_MAXUINT64;
         range->map_entries = g_sequence_new(NULL);
-        range->dirty = TRUE;
+        range->serialized = NULL;
 
         g_print("Creating inode map range, 1: start=%"PRIu64" end=%"PRIu64"\n",
                 range->start, range->end);
@@ -112,8 +112,10 @@ InodeMapEntry *bluesky_inode_map_lookup(GSequence *inode_map, uint64_t inum,
         g_print("Created inode map entry for %"PRIu64"\n", inum);
     }
 
-    if (action != 0)
-        range->dirty = TRUE;
+    if (action != 0) {
+        bluesky_cloudlog_unref(range->serialized);
+        range->serialized = NULL;
+    }
 
     /* Were we requested to delete the item? */
     if (action < 0) {
@@ -123,3 +125,56 @@ InodeMapEntry *bluesky_inode_map_lookup(GSequence *inode_map, uint64_t inum,
 
     return entry;
 }
+
+/* Convert a section of the inode map to serialized form, in preparation for
+ * writing it out to the cloud. */
+static void bluesky_inode_map_serialize_section(BlueSkyFS *fs,
+                                                InodeMapRange *range)
+{
+    if (range->serialized != NULL)
+        return;
+
+    GString *buf = g_string_new("");
+    BlueSkyCloudLog *log = bluesky_cloudlog_new(fs, NULL);
+    log->type = LOGTYPE_INODE_MAP;
+    log->inum = 0;
+
+    GSequenceIter *i = g_sequence_get_begin_iter(range->map_entries);
+    while (!g_sequence_iter_is_end(i)) {
+        InodeMapEntry *entry = (InodeMapEntry *)g_sequence_get(i);
+        uint64_t inum = GUINT64_TO_LE(entry->inum);
+        g_string_append_len(buf, (const char *)&inum, sizeof(inum));
+        g_array_append_val(log->links, entry->item);
+        i = g_sequence_iter_next(i);
+    }
+
+    log->data = bluesky_string_new_from_gstring(buf);
+    bluesky_cloudlog_unref(range->serialized);
+    range->serialized = log;
+}
+
+BlueSkyCloudLog *bluesky_inode_map_serialize(BlueSkyFS *fs)
+{
+    GString *buf = g_string_new("");
+    BlueSkyCloudLog *log = bluesky_cloudlog_new(fs, NULL);
+    log->type = LOGTYPE_CHECKPOINT;
+    log->inum = 0;
+
+    GSequenceIter *i = g_sequence_get_begin_iter(fs->inode_map);
+    while (!g_sequence_iter_is_end(i)) {
+        InodeMapRange *range = (InodeMapRange *)g_sequence_get(i);
+        uint64_t inum = GUINT64_TO_LE(range->start);
+        g_string_append_len(buf, (const char *)&inum, sizeof(inum));
+        inum = GUINT64_TO_LE(range->end);
+        g_string_append_len(buf, (const char *)&inum, sizeof(inum));
+
+        if (range->serialized == NULL)
+            bluesky_inode_map_serialize_section(fs, range);
+        bluesky_cloudlog_ref(range->serialized);
+        g_array_append_val(log->links, range->serialized);
+        i = g_sequence_iter_next(i);
+    }
+
+    log->data = bluesky_string_new_from_gstring(buf);
+    return log;
+}