void bluesky_directory_dump(BlueSkyInode *dir);
void bluesky_block_touch(BlueSkyInode *inode, uint64_t i);
+void bluesky_block_fetch(BlueSkyFS *fs, BlueSkyBlock *block);
void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block);
void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size);
void bluesky_file_write(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);
}
}
+/* 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);
+
+ g_free(block->data);
+ block->data = g_memdup(string->data, BLUESKY_BLOCK_SIZE);
+ block->type = BLUESKY_BLOCK_CACHED;
+ bluesky_string_unref(string);
+}
+
/* Write the given block to cloud-backed storage and mark it clean. */
void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block)
{
s3store_put(fs->store, name, data);
g_free(block->ref);
block->ref = g_strdup(name);
- block->type = BLUESKY_BLOCK_CACHED;
+
+ /* block->type = BLUESKY_BLOCK_CACHED; */
+ g_free(block->data);
+ block->data = NULL;
+ block->type = BLUESKY_BLOCK_REF;
g_checksum_free(csum);
bluesky_string_unref(data);
return store;
}
-BlueSkyRCStr *s3store_get(S3Store *store, const gchar *key)
+struct get_info {
+ gchar *buf;
+ gint offset;
+};
+
+static S3Status s3store_get_handler(int bufferSize, const char *buffer,
+ void *callbackData)
{
- return NULL;
+ struct get_info *info = (struct get_info *)callbackData;
+ gint bytes = MIN(bufferSize, (int)(BLUESKY_BLOCK_SIZE - info->offset));
+ memcpy(info->buf + info->offset, buffer, bytes);
+ info->offset += bytes;
+ return S3StatusOK;
}
struct put_info {
}
}
+BlueSkyRCStr *s3store_get(S3Store *store, const gchar *key)
+{
+ struct get_info info;
+ info.buf = (char *)g_malloc0(BLUESKY_BLOCK_SIZE);
+ info.offset = 0;
+
+ struct S3GetObjectHandler handler;
+ handler.responseHandler.propertiesCallback = s3store_properties_callback;
+ handler.responseHandler.completeCallback = s3store_response_callback;
+ handler.getObjectDataCallback = s3store_get_handler;
+
+ g_print("Starting fetch of %s from S3...\n", key);
+ S3_get_object(&store->bucket, key, NULL, 0, 0, NULL,
+ &handler, &info);
+
+ return bluesky_string_new(info.buf, BLUESKY_BLOCK_SIZE);
+}
+
void s3store_put(S3Store *store, const gchar *key, BlueSkyRCStr *val)
{
struct put_info info;