+/* 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)
+{
+ InodeMapEntry *entry = bluesky_inode_map_lookup(fs->inode_map, inum, 0);
+ if (entry == NULL)
+ return;
+
+ /* Non-portable behavior: We take the inode lock here, and release it in
+ * the fetching thread. This works with the default Linux pthreads
+ * implementation but is not guaranteed. */
+
+ BlueSkyInode *inode = bluesky_new_inode(inum, fs, BLUESKY_PENDING);
+ inode->change_count = 0;
+ bluesky_inode_ref(inode); // Extra ref held by fetching process
+ g_mutex_lock(inode->lock);
+
+ inode->committed_item = entry->item;
+ bluesky_cloudlog_ref(entry->item);
+ bluesky_insert_inode(fs, inode);
+
+ inode->private_data = bluesky_profile_get();
+ g_thread_pool_push(fs->inode_fetch_thread_pool, inode, NULL);
+}