char *buf, gint len);
void bluesky_inode_flush(BlueSkyFS *fs, BlueSkyInode *inode);
+void bluesky_inode_fetch(BlueSkyFS *fs, uint64_t inum);
void bluesky_serialize_inode(GString *out, BlueSkyInode *inode);
+BlueSkyInode *bluesky_deserialize_inode(BlueSkyFS *fs, const gchar *buf);
+
+gint bluesky_dirent_compare(gconstpointer a, gconstpointer b,
+ gpointer unused);
#ifdef __cplusplus
}
inode = (BlueSkyInode *)g_hash_table_lookup(fs->inodes, &inum);
g_mutex_unlock(fs->lock);
+ if (inode == NULL) {
+ bluesky_inode_fetch(fs, inum);
+ g_mutex_lock(fs->lock);
+ inode = (BlueSkyInode *)g_hash_table_lookup(fs->inodes, &inum);
+ g_mutex_unlock(fs->lock);
+ }
+
return inode;
}
bluesky_store_put(fs->store, key, data);
}
+
+/* Fetch an inode from stable storage. */
+void bluesky_inode_fetch(BlueSkyFS *fs, uint64_t inum)
+{
+ char key[64];
+ sprintf(key, "inode-%016llx", inum);
+ BlueSkyRCStr *data = bluesky_store_get(fs->store, key);
+
+ BlueSkyInode *inode = bluesky_deserialize_inode(fs, data->data);
+ if (inode != NULL) {
+ bluesky_insert_inode(fs, inode);
+ g_print("Loaded inode %lld\n", (long long)inum);
+ }
+}
buf += sizeof(struct serialized_inode);
+ g_print("Deserializing inode %lld...\n", (long long)inode->inum);
+
+ /* TODO: Bounds checking */
switch (inode->type) {
case BLUESKY_REGULAR:
g_array_set_size(inode->blocks,
buf += strlen(b->ref) + 1;
}
break;
+
+ case BLUESKY_DIRECTORY:
+ {
+ struct serialized_dirent {
+ uint32_t seq;
+ uint64_t inum;
+ gchar name[0];
+ } __attribute__((packed));
+
+ struct serialized_dirent *d = (struct serialized_dirent *)buf;
+ while (GUINT32_FROM_LE(d->seq) != 0) {
+ BlueSkyDirent *dirent = g_new(BlueSkyDirent, 1);
+ dirent->cookie = GUINT64_FROM_LE(d->seq);
+ dirent->inum = GUINT64_FROM_LE(d->inum);
+ dirent->name = g_strdup(d->name);
+
+ g_sequence_insert_sorted(inode->dirents, dirent,
+ bluesky_dirent_compare, NULL);
+ g_hash_table_insert(inode->dirhash, dirent->name, dirent);
+
+ g_print(" dirent[%08x]: %s -> %lld\n",
+ dirent->cookie, dirent->name, dirent->inum);
+
+ buf = strchr(d->name, '\0') + 1;
+ d = (struct serialized_dirent *)buf;
+ }
+ break;
+ }
default:
g_warning("Deserialization for inode type %d not implemented!\n",
inode->type);
}
+
+ return inode;
}
fs->encryption_key = filesystem_key;
BlueSkyInode *root;
- root = bluesky_new_inode(BLUESKY_ROOT_INUM, fs, BLUESKY_DIRECTORY);
- root->nlink = 1;
- root->mode = 0755;
- bluesky_insert_inode(fs, root);
-
- BlueSkyInode *file;
- file = bluesky_new_inode(bluesky_fs_alloc_inode(fs), fs, BLUESKY_REGULAR);
- file->nlink = 1;
- file->mode = 0755;
- bluesky_insert_inode(fs, file);
- bluesky_directory_insert(root, "demo", file->inum);
+ root = bluesky_get_inode(fs, BLUESKY_ROOT_INUM);
+ if (root == NULL) {
+ printf("Initializing fresh root inode...\n");
+ root = bluesky_new_inode(BLUESKY_ROOT_INUM, fs, BLUESKY_DIRECTORY);
+ root->nlink = 1;
+ root->mode = 0755;
+ bluesky_insert_inode(fs, root);
+ }
svc_run();
fprintf(stderr, "%s", "svc_run returned");