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. */
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);