+ sprintf(key, "inode-%016"PRIx64, inode->inum);
+
+ BlueSkyCloudLog *cloudlog = bluesky_cloudlog_new(fs);
+ cloudlog->type = LOGTYPE_INODE;
+ cloudlog->inum = inode->inum;
+ cloudlog->data = data;
+ bluesky_string_ref(data);
+
+ if (inode->type == BLUESKY_REGULAR) {
+ for (int i = 0; i < inode->blocks->len; i++) {
+ BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i);
+ if (b->type == BLUESKY_BLOCK_CACHED
+ || b->type == BLUESKY_BLOCK_REF)
+ {
+ BlueSkyCloudID id = bluesky_cloudlog_id_from_string(b->ref);
+ g_array_append_val(cloudlog->pointers, id);
+ }
+ }
+ }
+
+ log_items = g_list_prepend(log_items, bluesky_cloudlog_sync(cloudlog));
+
+ bluesky_cloudlog_insert(cloudlog);
+
+ /* Wait for all log items to be committed to disk. */
+ while (log_items != NULL) {
+ BlueSkyLogItem *log_item = (BlueSkyLogItem *)log_items->data;
+ bluesky_log_item_finish(log_item);
+ log_items = g_list_delete_link(log_items, log_items);
+ }
+
+ BlueSkyStoreAsync *async = bluesky_store_async_new(fs->store);
+ async->op = STORE_OP_PUT;
+ async->key = g_strdup(key);
+ async->data = data;
+ bluesky_store_async_submit(async);
+ if (barrier != NULL)
+ bluesky_store_add_barrier(barrier, async);
+ bluesky_store_async_unref(async);
+}
+
+/* Write back an inode and all associated data and wait for completion. Inode
+ * should already be locked. */
+void bluesky_inode_do_sync(BlueSkyInode *inode)
+{
+ BlueSkyStoreAsync *barrier = bluesky_store_async_new(inode->fs->store);
+ barrier->op = STORE_OP_BARRIER;