X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Finode.c;h=a264f350c24cee4115d29c7980502f75742a8e9d;hb=a4e456f91da9819e5a1517d4e505816bb4aa1007;hp=59b915a29f2298c2d443a34ed4d0620e375e7f77;hpb=0a6dbd76f58caad61a494a64e9bd421de61f6aa6;p=bluesky.git diff --git a/bluesky/inode.c b/bluesky/inode.c index 59b915a..a264f35 100644 --- a/bluesky/inode.c +++ b/bluesky/inode.c @@ -8,10 +8,11 @@ #include #include +#include #include #include -#include "bluesky.h" +#include "bluesky-private.h" /* Core filesystem. Different proxies, such as the NFSv3 one, interface to * this, but the core actually tracks the data which is stored. So far we just @@ -36,6 +37,9 @@ void bluesky_inode_update_ctime(BlueSkyInode *inode, gboolean update_mtime) inode->ctime = now; if (update_mtime) inode->mtime = now; + + if (inode->change_time == 0) + inode->change_time = now; } /* Unfortunately a glib hash table is only guaranteed to be able to store @@ -72,6 +76,36 @@ BlueSkyFS *bluesky_new_fs(gchar *name) return fs; } +BlueSkyFS *bluesky_init_fs(gchar *name, BlueSkyStore *store) +{ + BlueSkyRCStr *data = bluesky_store_get(store, "superblock"); + if (data != NULL) { + BlueSkyFS *fs = bluesky_deserialize_superblock(data->data); + if (fs != NULL) { + fs->store = store; + g_print("Loaded filesystem superblock\n"); + g_free(fs->name); + fs->name = g_strdup(name); + return fs; + } + } + + g_print("Initializing fresh filesystem\n"); + BlueSkyFS *fs = bluesky_new_fs(name); + fs->store = store; + + BlueSkyInode *root = bluesky_new_inode(BLUESKY_ROOT_INUM, fs, + BLUESKY_DIRECTORY); + root->nlink = 1; + root->mode = 0755; + bluesky_insert_inode(fs, root); + + bluesky_inode_flush(fs, root); + bluesky_superblock_flush(fs); + + return fs; +} + /* Inode reference counting. */ void bluesky_inode_ref(BlueSkyInode *inode) { @@ -81,7 +115,7 @@ void bluesky_inode_ref(BlueSkyInode *inode) void bluesky_inode_unref(BlueSkyInode *inode) { if (g_atomic_int_dec_and_test(&inode->refcount)) { - g_error("Reference count for inode %lld dropped to zero!\n", + g_error("Reference count for inode %"PRIu64" dropped to zero!\n", inode->inum); } } @@ -95,6 +129,8 @@ uint64_t bluesky_fs_alloc_inode(BlueSkyFS *fs) inum = fs->next_inum; fs->next_inum++; + bluesky_superblock_flush(fs); + return inum; } @@ -116,6 +152,7 @@ BlueSkyInode *bluesky_new_inode(uint64_t inum, BlueSkyFS *fs, case BLUESKY_DIRECTORY: i->dirents = g_sequence_new(bluesky_dirent_destroy); i->dirhash = g_hash_table_new(g_str_hash, g_str_equal); + i->dirhash_folded = g_hash_table_new(g_str_hash, g_str_equal); break; case BLUESKY_BLOCK: case BLUESKY_CHARACTER: @@ -136,6 +173,10 @@ BlueSkyInode *bluesky_get_inode(BlueSkyFS *fs, uint64_t inum) { BlueSkyInode *inode = NULL; + if (inum == 0) { + return NULL; + } + g_mutex_lock(fs->lock); inode = (BlueSkyInode *)g_hash_table_lookup(fs->inodes, &inum); @@ -164,21 +205,24 @@ void bluesky_inode_flush(BlueSkyFS *fs, BlueSkyInode *inode) { GString *buf = g_string_new(""); bluesky_serialize_inode(buf, inode); - - gsize len = buf->len; - BlueSkyRCStr *data = bluesky_string_new(g_string_free(buf, FALSE), len); + BlueSkyRCStr *data = bluesky_string_new_from_gstring(buf); char key[64]; - sprintf(key, "inode-%016llx", inode->inum); - - bluesky_store_put(fs->store, key, data); + sprintf(key, "inode-%016"PRIx64, inode->inum); + + BlueSkyStoreAsync *async = bluesky_store_async_new(fs->store); + async->op = STORE_OP_PUT; + async->key = g_strdup(key); + async->data = data; + bluesky_store_async_submit(async); + bluesky_store_async_unref(async); } /* Fetch an inode from stable storage. */ void bluesky_inode_fetch(BlueSkyFS *fs, uint64_t inum) { char key[64]; - sprintf(key, "inode-%016llx", inum); + sprintf(key, "inode-%016"PRIx64, inum); BlueSkyRCStr *data = bluesky_store_get(fs->store, key); if (data == NULL) return; @@ -186,6 +230,22 @@ void bluesky_inode_fetch(BlueSkyFS *fs, uint64_t inum) 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); } } + +/* Synchronize filesystem superblock to stable storage. */ +void bluesky_superblock_flush(BlueSkyFS *fs) +{ + GString *buf = g_string_new(""); + bluesky_serialize_superblock(buf, fs); + BlueSkyRCStr *data = bluesky_string_new_from_gstring(buf); + + BlueSkyStoreAsync *async = bluesky_store_async_new(fs->store); + async->op = STORE_OP_PUT; + async->key = g_strdup("superblock"); + async->data = data; + bluesky_store_async_submit(async); + bluesky_store_async_unref(async); + + bluesky_store_sync(fs->store); +}