X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Ffile.c;h=75768d11434dd70617d541eeb27325c1c20c335b;hb=0325ee9e9afb02b08bdec3497e8cc54cb942989d;hp=607d61186abfbc26a98f8719b2cd7f70e787437f;hpb=98effa493bca2b6e97d98035be602993da27d26b;p=bluesky.git diff --git a/bluesky/file.c b/bluesky/file.c index 607d611..75768d1 100644 --- a/bluesky/file.c +++ b/bluesky/file.c @@ -21,10 +21,17 @@ void bluesky_block_touch(BlueSkyInode *inode, uint64_t i) g_return_if_fail(i < inode->blocks->len); BlueSkyBlock *block = &g_array_index(inode->blocks, BlueSkyBlock, i); + gsize block_len; + if (i < inode->blocks->len - 1) { + block_len = BLUESKY_BLOCK_SIZE; + } else { + block_len = inode->size - i * BLUESKY_BLOCK_SIZE; + } + switch (block->type) { case BLUESKY_BLOCK_ZERO: - block->data = bluesky_string_new(g_malloc0(BLUESKY_BLOCK_SIZE), - BLUESKY_BLOCK_SIZE); + g_print("Allocating zero block of size %zd\n", block_len); + block->data = bluesky_string_new(g_malloc0(block_len), block_len); break; case BLUESKY_BLOCK_REF: bluesky_block_fetch(inode->fs, block); @@ -65,17 +72,21 @@ void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size) g_array_set_size(inode->blocks, blocks); } - /* If the file size is being decreased, ensure that any trailing data in - * the last block is zeroed. */ - if (size < inode->size) { + /* Ensure the 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); + if (b->type != BLUESKY_BLOCK_ZERO) { bluesky_block_touch(inode, blocks - 1); - int end_offset = size % BLUESKY_BLOCK_SIZE; - if (end_offset > 0) { - memset(&b->data->data[end_offset], 0, - BLUESKY_BLOCK_SIZE - end_offset); + gsize old_size = b->data->len; + gsize new_size = size - (blocks - 1) * BLUESKY_BLOCK_SIZE; + + bluesky_string_resize(b->data, new_size); + + if (new_size > old_size) { + memset(&b->data->data[old_size], 0, new_size - old_size); } } }