X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Finode.c;h=8faafa412b9861e5dfabca5258407c7e44828369;hb=3ffb892cbb0b96a57595b9962d018191c5b3d5af;hp=d8b80cf5dd18f3801e1aca07c62abbf563a350fa;hpb=a5a9eca66728d271a442125ac52098378c70cf42;p=bluesky.git diff --git a/bluesky/inode.c b/bluesky/inode.c index d8b80cf..8faafa4 100644 --- a/bluesky/inode.c +++ b/bluesky/inode.c @@ -6,6 +6,7 @@ * TODO: Licensing */ +#include #include #include #include @@ -27,7 +28,7 @@ int64_t bluesky_get_current_time() /* Update an inode to indicate that a modification was made. This increases * the change counter, updates the ctime to the current time, and optionally - * updates the mtime. */ + * updates the mtime. inode must already be locked. */ void bluesky_inode_update_ctime(BlueSkyInode *inode, gboolean update_mtime) { int64_t now = bluesky_get_current_time(); @@ -37,54 +38,6 @@ void bluesky_inode_update_ctime(BlueSkyInode *inode, gboolean update_mtime) inode->mtime = now; } -/* Compute the HMAC keyed-hash function using the given hash algorithm, data, - * and key. */ -void compute_hmac(GChecksumType algo, - const guchar *data, gsize data_len, - const guchar *key, gsize key_len, - guint8 *buffer, gsize *digest_len) -{ - int block_size; - - switch (algo) { - case G_CHECKSUM_MD5: - case G_CHECKSUM_SHA1: - case G_CHECKSUM_SHA256: - block_size = 64; - break; - default: - g_error("Unknown hash algorithm for HMAC: %d\n", algo); - } - - gsize digest_size = g_checksum_type_get_length(algo); - - guchar keybuf[block_size]; - memset(keybuf, 0, block_size); - memcpy(keybuf, key, MIN(block_size, key_len)); - for (int i = 0; i < block_size; i++) - keybuf[i] ^= 0x36; - - GChecksum *csum1 = g_checksum_new(algo); - g_checksum_update(csum1, keybuf, block_size); - g_checksum_update(csum1, data, data_len); - guint8 digest[digest_size]; - g_checksum_get_digest(csum1, digest, &digest_size); - - memset(keybuf, 0, block_size); - memcpy(keybuf, key, MIN(block_size, key_len)); - for (int i = 0; i < block_size; i++) - keybuf[i] ^= 0x5c; - - GChecksum *csum2 = g_checksum_new(algo); - g_checksum_update(csum2, keybuf, block_size); - g_checksum_update(csum2, digest, digest_size); - - g_checksum_get_digest(csum2, buffer, digest_len); - - g_checksum_free(csum1); - g_checksum_free(csum2); -} - /* Unfortunately a glib hash table is only guaranteed to be able to store * 32-bit keys if we use the key directly. If we want 64-bit inode numbers, * we'll have to allocate memory to store the 64-bit inumber, and use a pointer @@ -134,15 +87,13 @@ void bluesky_inode_unref(BlueSkyInode *inode) } /* Allocate a fresh inode number which has not been used before within a - * filesystem. */ + * filesystem. fs must already be locked. */ uint64_t bluesky_fs_alloc_inode(BlueSkyFS *fs) { uint64_t inum; - g_mutex_lock(fs->lock); inum = fs->next_inum; fs->next_inum++; - g_mutex_unlock(fs->lock); return inum; } @@ -179,22 +130,63 @@ BlueSkyInode *bluesky_new_inode(uint64_t inum, BlueSkyFS *fs, /* Retrieve an inode from the filesystem. Eventually this will be a cache and * so we might need to go fetch the inode from elsewhere; for now all - * filesystem state is stored here. */ + * filesystem state is stored here. inode is returned locked with a reference + * held. */ BlueSkyInode *bluesky_get_inode(BlueSkyFS *fs, uint64_t inum) { BlueSkyInode *inode = NULL; g_mutex_lock(fs->lock); inode = (BlueSkyInode *)g_hash_table_lookup(fs->inodes, &inum); + + if (inode == NULL) { + bluesky_inode_fetch(fs, inum); + inode = (BlueSkyInode *)g_hash_table_lookup(fs->inodes, &inum); + } + + if (inode != NULL) { + g_mutex_lock(inode->lock); + bluesky_inode_ref(inode); + } + g_mutex_unlock(fs->lock); return inode; } -/* Insert an inode into the filesystem inode cache. */ +/* Insert an inode into the filesystem inode cache. fs should be locked. */ void bluesky_insert_inode(BlueSkyFS *fs, BlueSkyInode *inode) { - g_mutex_lock(fs->lock); g_hash_table_insert(fs->inodes, &inode->inum, inode); - g_mutex_unlock(fs->lock); +} + +/* Synchronize an inode to stable storage. */ +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); + + char key[64]; + sprintf(key, "inode-%016llx", inode->inum); + + 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); + if (data == NULL) + return; + + 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); + } }