Work to add inode serialization/deserialization routines.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Thu, 3 Sep 2009 23:49:13 +0000 (16:49 -0700)
committerMichael Vrable <mvrable@turin.ucsd.edu>
Thu, 3 Sep 2009 23:49:13 +0000 (16:49 -0700)
bluesky/CMakeLists.txt
bluesky/bluesky.h
bluesky/crypto.c
bluesky/serialize.c [new file with mode: 0644]
nfs3/nfs3.c

index 3500918..d576192 100644 (file)
@@ -1,6 +1,6 @@
 link_directories(/home/mvrable/scratch/libs3-1.4/build/lib)
 
-add_library(bluesky SHARED crypto.c dir.c inode.c store.c s3store.c)
+add_library(bluesky SHARED crypto.c dir.c inode.c serialize.c store.c s3store.c)
 add_executable(bluesky-test main.c)
 
 set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
index 831d850..b250206 100644 (file)
@@ -32,6 +32,9 @@ void bluesky_string_unref(BlueSkyRCStr *string);
 BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string);
 
 /* Cryptographic operations. */
+#define CRYPTO_BLOCK_SIZE 16        /* 128-bit AES */
+#define CRYPTO_KEY_SIZE   16
+
 void bluesky_crypt_init();
 void bluesky_crypt_random_bytes(guchar *buf, gint len);
 BlueSkyRCStr *bluesky_crypt_encrypt(BlueSkyRCStr *in, const uint8_t *key);
index defe1b3..8aeba3a 100644 (file)
@@ -19,9 +19,6 @@
  * the functions in this file, so this is the only point where we interface
  * with an external cryptographic library. */
 
-#define CRYPTO_BLOCK_SIZE 16        /* 128-bit AES */
-#define CRYPTO_KEY_SIZE   16
-
 GCRY_THREAD_OPTION_PTHREAD_IMPL;
 
 void bluesky_crypt_init()
diff --git a/bluesky/serialize.c b/bluesky/serialize.c
new file mode 100644 (file)
index 0000000..7cb16a5
--- /dev/null
@@ -0,0 +1,109 @@
+/* Blue Sky: File Systems in the Cloud
+ *
+ * Copyright (C) 2009  The Regents of the University of California
+ * Written by Michael Vrable <mvrable@cs.ucsd.edu>
+ *
+ * TODO: Licensing
+ */
+
+#include <stdint.h>
+#include <glib.h>
+#include <string.h>
+
+#include "bluesky.h"
+
+/* Serialization of in-memory filesystem data structures to bytestrings which
+ * can be written to persistent storage.  All data is stored in little-endian
+ * format. */
+
+/* Magic signature for serialized inodes. */
+
+#define INODE_MAGIC 0xa6832100943d71e5ULL
+
+struct serialized_inode {
+    uint64_t signature;         /* INODE_MAGIC */
+    int32_t type;
+    uint32_t mode;
+    uint32_t uid, gid;
+    uint32_t nlink;
+    uint64_t inum;
+    uint64_t change_count;
+    int64_t atime;
+    int64_t ctime;
+    int64_t mtime;
+    int64_t ntime;
+} __attribute__((packed));
+
+void bluesky_serialize_inode(GString *out, BlueSkyInode *inode)
+{
+    struct serialized_inode buf;
+
+    buf.signature = GUINT64_TO_LE(INODE_MAGIC);
+    buf.type = GUINT32_TO_LE(inode->type);
+    buf.mode = GUINT32_TO_LE(inode->mode);
+    buf.uid = GUINT32_TO_LE(inode->uid);
+    buf.gid = GUINT32_TO_LE(inode->gid);
+    buf.nlink = GUINT32_TO_LE(inode->nlink);
+    buf.inum = GUINT64_TO_LE(inode->inum);
+    buf.change_count = GUINT64_TO_LE(inode->change_count);
+    buf.atime = GINT64_TO_LE(inode->atime);
+    buf.ctime = GINT64_TO_LE(inode->ctime);
+    buf.mtime = GINT64_TO_LE(inode->mtime);
+    buf.ntime = GINT64_TO_LE(inode->ntime);
+
+    g_string_append_len(out, (gchar *)&buf, sizeof(buf));
+
+    switch (inode->type) {
+    case BLUESKY_REGULAR:
+        for (int i = 0; i < inode->blocks->len; i++) {
+            BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i);
+            if (b->ref != NULL)
+                g_string_append(out, b->ref);
+            g_string_append_c(out, '\0');
+        }
+        break;
+    default:
+        g_warning("Serialization for inode type %d not implemented!\n",
+                  inode->type);
+    }
+}
+
+BlueSkyInode *bluesky_deserialize_inode(BlueSkyFS *fs, const gchar *buf)
+{
+    struct serialized_inode *raw = (struct serialized_inode *)buf;
+
+    if (GUINT64_FROM_LE(raw->signature) != INODE_MAGIC)
+        return NULL;
+
+    BlueSkyInode *inode = bluesky_new_inode(GUINT64_FROM_LE(raw->inum),
+                                            fs, GUINT32_FROM_LE(raw->type));
+
+    inode->mode = GUINT32_FROM_LE(raw->mode);
+    inode->uid = GUINT32_FROM_LE(raw->uid);
+    inode->gid = GUINT32_FROM_LE(raw->gid);
+    inode->nlink = GUINT32_FROM_LE(raw->nlink);
+    inode->change_count = GUINT64_FROM_LE(raw->change_count);
+    inode->atime = GINT64_FROM_LE(raw->atime);
+    inode->ctime = GINT64_FROM_LE(raw->ctime);
+    inode->mtime = GINT64_FROM_LE(raw->mtime);
+    inode->ntime = GINT64_FROM_LE(raw->ntime);
+
+    buf += sizeof(struct serialized_inode);
+
+    switch (inode->type) {
+    case BLUESKY_REGULAR:
+        g_array_set_size(inode->blocks,
+                         (inode->size + BLUESKY_BLOCK_SIZE - 1)
+                          / BLUESKY_BLOCK_SIZE);
+        for (int i = 0; i < inode->blocks->len; i++) {
+            BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i);
+            b->type = BLUESKY_BLOCK_REF;
+            b->ref = g_strdup(buf);
+            buf += strlen(b->ref) + 1;
+        }
+        break;
+    default:
+        g_warning("Deserialization for inode type %d not implemented!\n",
+                  inode->type);
+    }
+}
index a5439f8..7fdd521 100644 (file)
@@ -374,6 +374,7 @@ nfsproc3_create_3_svc(create3args *argp, struct svc_req *rqstp)
     file->mtime = time;
     file->ctime = time;
     file->atime = time;
+    file->ntime = time;
     bluesky_insert_inode(fs, file);
     bluesky_directory_insert(dir, argp->where.name, file->inum);