X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Ffile.c;h=09e4805547a229d5b4884b54e2de21951e578405;hb=4bef26446b9100f63ac3c953b7f96f1966673980;hp=f7e8fcac894ffdc125a8400243ad055b17f79062;hpb=625d4ed1c01e01a5f2a508264f8605fb79a620fb;p=bluesky.git diff --git a/bluesky/file.c b/bluesky/file.c index f7e8fca..09e4805 100644 --- a/bluesky/file.c +++ b/bluesky/file.c @@ -63,7 +63,23 @@ void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size) if (blocks > inode->blocks->len) { /* Need to add new blocks to the end of a file. New block structures * are automatically zeroed, which initializes them to be pointers to - * zero blocks so we don't need to do any more work. */ + * zero blocks so we don't need to do any more work. If the + * previously-last block in the file is smaller than + * BLUESKY_BLOCK_SIZE, extend it to full size. */ + if (inode->blocks->len > 0) { + BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, + inode->blocks->len - 1); + + if (b->type != BLUESKY_BLOCK_ZERO + && b->data->len < BLUESKY_BLOCK_SIZE) { + bluesky_block_touch(inode, inode->blocks->len - 1); + gsize old_size = b->data->len; + bluesky_string_resize(b->data, BLUESKY_BLOCK_SIZE); + memset(&b->data->data[old_size], 0, + BLUESKY_BLOCK_SIZE - old_size); + } + } + g_array_set_size(inode->blocks, blocks); } else if (blocks < inode->blocks->len) { /* Delete blocks from a file. Must reclaim memory. */ @@ -75,8 +91,8 @@ void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size) g_array_set_size(inode->blocks, blocks); } - /* Ensure the last block of the file is properly sized. If the block is - * extended, newly-added bytes must be zeroed. */ + /* Ensure the new last block of the file is properly sized. If the block + * is extended, newly-added bytes must be zeroed. */ if (blocks > 0) { BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, blocks - 1); @@ -119,7 +135,6 @@ void bluesky_file_write(BlueSkyInode *inode, uint64_t offset, BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, block_num); memcpy(&b->data->data[block_offset], data, bytes); - bluesky_block_flush(inode->fs, b); offset += bytes; data += bytes; @@ -127,7 +142,6 @@ void bluesky_file_write(BlueSkyInode *inode, uint64_t offset, } bluesky_inode_update_ctime(inode, 1); - bluesky_inode_flush(inode->fs, inode); } void bluesky_file_read(BlueSkyInode *inode, uint64_t offset, @@ -182,13 +196,9 @@ void bluesky_block_fetch(BlueSkyFS *fs, BlueSkyBlock *block) block->type = BLUESKY_BLOCK_CACHED; } -static void finished(gpointer a, gpointer b) -{ - g_print("Barrier completed!\n"); -} - /* Write the given block to cloud-backed storage and mark it clean. */ -void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block) +void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block, + BlueSkyStoreAsync *barrier) { if (block->type != BLUESKY_BLOCK_DIRTY) return; @@ -196,7 +206,7 @@ void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block) BlueSkyRCStr *data = block->data; GChecksum *csum = g_checksum_new(G_CHECKSUM_SHA256); - g_checksum_update(csum, data->data, data->len); + g_checksum_update(csum, (const guchar *)data->data, data->len); gchar *name = g_strdup(g_checksum_get_string(csum)); /* Store the file data asynchronously, and don't bother waiting for a @@ -207,18 +217,13 @@ void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block) bluesky_string_ref(data); async->data = data; bluesky_store_async_submit(async); + if (barrier != NULL) + bluesky_store_add_barrier(barrier, async); bluesky_store_async_unref(async); g_free(block->ref); block->ref = name; - BlueSkyStoreAsync *barrier = bluesky_store_async_new(fs->store); - barrier->op = STORE_OP_BARRIER; - bluesky_store_add_barrier(barrier, async); - bluesky_store_async_add_notifier(barrier, finished, NULL); - bluesky_store_async_submit(barrier); - bluesky_store_async_unref(barrier); - /* block->type = BLUESKY_BLOCK_CACHED; */ bluesky_string_unref(block->data); block->data = NULL; @@ -229,12 +234,12 @@ void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block) } /* Flush all blocks in a file to stable storage. */ -void bluesky_file_flush(BlueSkyInode *inode) +void bluesky_file_flush(BlueSkyInode *inode, BlueSkyStoreAsync *barrier) { g_return_if_fail(inode->type == BLUESKY_REGULAR); for (int i = 0; i < inode->blocks->len; i++) { BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i); - bluesky_block_flush(inode->fs, b); + bluesky_block_flush(inode->fs, b, barrier); } }