+
+/* 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;
+}