X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=inode.c;h=7ea8dbf2af026b0e74f4235003f040b6bac303c8;hb=d32328c00f54c2f6f4e6eeb8993d33d062e9477c;hp=b1071a63cbd6b5b4222916ad2babf27bb67b2fc4;hpb=3ebe1efb5570c4a678774ebdf33b36be6dc49bbc;p=bluesky.git diff --git a/inode.c b/inode.c index b1071a6..7ea8dbf 100644 --- a/inode.c +++ b/inode.c @@ -193,14 +193,16 @@ void bluesky_block_touch(BlueSkyInode *inode, uint64_t i) switch (block->type) { case BLUESKY_BLOCK_ZERO: - block->data = g_malloc0(BLUESKY_BLOCK_SIZE); + block->data = bluesky_string_new(g_malloc0(BLUESKY_BLOCK_SIZE), + BLUESKY_BLOCK_SIZE); break; case BLUESKY_BLOCK_REF: - /* TODO: Pull in data first */ - block->data = g_malloc0(BLUESKY_BLOCK_SIZE); - break; + bluesky_block_fetch(inode->fs, block); + g_assert(block->type == BLUESKY_BLOCK_CACHED); + /* Fall through */ case BLUESKY_BLOCK_CACHED: case BLUESKY_BLOCK_DIRTY: + block->data = bluesky_string_dup(block->data); break; } @@ -228,7 +230,7 @@ void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size) for (guint i = inode->blocks->len; i < blocks; i++) { BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i); g_free(b->ref); - g_free(b->data); + bluesky_string_unref(b->data); } g_array_set_size(inode->blocks, blocks); } @@ -242,7 +244,7 @@ void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size) bluesky_block_touch(inode, blocks - 1); int end_offset = size % BLUESKY_BLOCK_SIZE; if (end_offset > 0) { - memset(&b->data[end_offset], 0, + memset(&b->data->data[end_offset], 0, BLUESKY_BLOCK_SIZE - end_offset); } } @@ -270,7 +272,7 @@ void bluesky_file_write(BlueSkyInode *inode, uint64_t offset, bluesky_block_touch(inode, block_num); BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, block_num); - memcpy(&b->data[block_offset], data, bytes); + memcpy(&b->data->data[block_offset], data, bytes); bluesky_block_flush(inode->fs, b); offset += bytes; @@ -300,12 +302,11 @@ void bluesky_file_read(BlueSkyInode *inode, uint64_t offset, memset(buf, 0, bytes); break; case BLUESKY_BLOCK_REF: - /* TODO: Pull in data first */ - memset(buf, 0, bytes); - break; + bluesky_block_fetch(inode->fs, b); + /* Fall through */ case BLUESKY_BLOCK_CACHED: case BLUESKY_BLOCK_DIRTY: - memcpy(buf, &b->data[block_offset], bytes); + memcpy(buf, &b->data->data[block_offset], bytes); break; } @@ -315,26 +316,40 @@ void bluesky_file_read(BlueSkyInode *inode, uint64_t offset, } } +/* Read the given block from cloud-backed storage if the data is not already + * cached. */ +void bluesky_block_fetch(BlueSkyFS *fs, BlueSkyBlock *block) +{ + if (block->type != BLUESKY_BLOCK_REF) + return; + + g_print("Fetching block from %s\n", block->ref); + BlueSkyRCStr *string = s3store_get(fs->store, block->ref); + + bluesky_string_unref(block->data); + block->data = string; + block->type = BLUESKY_BLOCK_CACHED; +} + /* Write the given block to cloud-backed storage and mark it clean. */ void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block) { if (block->type != BLUESKY_BLOCK_DIRTY) return; - BlueSkyRCStr *data = bluesky_string_new(g_memdup(block->data, - BLUESKY_BLOCK_SIZE), - BLUESKY_BLOCK_SIZE); - GChecksum *csum = g_checksum_new(G_CHECKSUM_SHA256); - g_checksum_update(csum, data->data, data->len); - const gchar *name = g_checksum_get_string(csum); + g_checksum_update(csum, block->data->data, block->data->len); + gchar *name = g_strdup(g_checksum_get_string(csum)); g_print("Flushing block as %s\n", name); - s3store_put(fs->store, name, data); + s3store_put(fs->store, name, block->data); g_free(block->ref); - block->ref = g_strdup(name); - block->type = BLUESKY_BLOCK_CACHED; + block->ref = name; + + /* block->type = BLUESKY_BLOCK_CACHED; */ + bluesky_string_unref(block->data); + block->data = NULL; + block->type = BLUESKY_BLOCK_REF; g_checksum_free(csum); - bluesky_string_unref(data); }