"Writeback for inode %"PRIu64" complete", inode->inum);
}
-/* Fetch an inode from stable storage. */
+static void complete_inode_fetch(BlueSkyStoreAsync *async, BlueSkyInode *inode)
+{
+ g_print("Completing fetch of inode %"PRIu64"...\n", inode->inum);
+
+ if (async->result != 0
+ || !bluesky_deserialize_inode(inode, async->data->data))
+ {
+ g_print(" failed to load inode, cleaning up\n");
+ g_mutex_lock(inode->fs->lock);
+ g_hash_table_remove(inode->fs->inodes, &inode->inum);
+ g_mutex_unlock(inode->fs->lock);
+ bluesky_inode_unref(inode);
+ }
+
+ g_mutex_unlock(inode->lock);
+ bluesky_inode_unref(inode);
+}
+
+/* Fetch an inode from stable storage. The fetch can be performed
+ * asynchronously: the in-memory inode is allocated, but not filled with data
+ * immediately. It is kept locked until it has been filled in, so any users
+ * should try to acquire the lock on the inode before accessing any data. The
+ * fs lock must be held. */
void bluesky_inode_fetch(BlueSkyFS *fs, uint64_t inum)
{
char key[64];
sprintf(key, "inode-%016"PRIx64, inum);
- BlueSkyRCStr *data = bluesky_store_get(fs->store, key);
- if (data == NULL)
- return;
BlueSkyInode *inode = bluesky_new_inode(inum, fs, BLUESKY_PENDING);
- bluesky_inode_ref(inode);
+ bluesky_inode_ref(inode); // Extra ref held by fetching process
g_mutex_lock(inode->lock);
bluesky_insert_inode(fs, inode);
- if (!bluesky_deserialize_inode(inode, data->data)) {
- g_hash_table_remove(fs->inodes, &inode->inum);
- bluesky_inode_unref(inode);
- }
+ BlueSkyStoreAsync *async = bluesky_store_async_new(fs->store);
+ async->op = STORE_OP_GET;
+ async->key = g_strdup(key);
- g_mutex_unlock(inode->lock);
- bluesky_inode_unref(inode);
+ bluesky_store_async_add_notifier(async, (GFunc)complete_inode_fetch, inode);
+ bluesky_store_async_submit(async);
+
+ if (bluesky_options.sync_inode_fetches) {
+ bluesky_store_async_wait(async);
+ }
}
/* Synchronize filesystem superblock to stable storage. */