From e1cac3d9a3fe157e0e874225bb85b57e86e1a020 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Sun, 27 Dec 2009 22:32:07 -0800 Subject: [PATCH] Fix up logic for handling short data blocks. This fixes a crash when there are writes that are not a multiple of the block size. --- bluesky/file.c | 22 +++++++++++++++++++--- bluesky/util.c | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/bluesky/file.c b/bluesky/file.c index 3be40f0..ae49d71 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); diff --git a/bluesky/util.c b/bluesky/util.c index 7f977a6..eab6a14 100644 --- a/bluesky/util.c +++ b/bluesky/util.c @@ -109,4 +109,5 @@ void bluesky_string_resize(BlueSkyRCStr *string, gsize len) return; string->data = g_realloc(string->data, len); + string->len = len; } -- 2.20.1