Directory deserialization and loading of inodes from stable store.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Wed, 9 Sep 2009 23:58:28 +0000 (16:58 -0700)
committerMichael Vrable <mvrable@turin.ucsd.edu>
Wed, 9 Sep 2009 23:58:28 +0000 (16:58 -0700)
bluesky/bluesky.h
bluesky/inode.c
bluesky/serialize.c
nfs3/nfsd.c

index 2cf97f6..1d0b0b1 100644 (file)
@@ -200,7 +200,12 @@ void bluesky_file_read(BlueSkyInode *inode, uint64_t offset,
                        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
 }
index a20b23b..3430b19 100644 (file)
@@ -141,6 +141,13 @@ BlueSkyInode *bluesky_get_inode(BlueSkyFS *fs, uint64_t inum)
     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;
 }
 
@@ -166,3 +173,17 @@ void bluesky_inode_flush(BlueSkyFS *fs, BlueSkyInode *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);
+    }
+}
index d0273cc..8043cc0 100644 (file)
@@ -115,6 +115,9 @@ BlueSkyInode *bluesky_deserialize_inode(BlueSkyFS *fs, const gchar *buf)
 
     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,
@@ -127,8 +130,38 @@ BlueSkyInode *bluesky_deserialize_inode(BlueSkyFS *fs, const gchar *buf)
             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;
 }
index 8ba3ef0..e3862aa 100644 (file)
@@ -44,17 +44,14 @@ int main(int argc, char *argv[])
     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");