Support partial block overwrite in patch_io_manager (fixes the last test)

master
Vitaliy Filippov 2014-01-15 15:29:43 +00:00
parent d84383495c
commit 3df64ee3c1
1 changed files with 27 additions and 1 deletions

View File

@ -193,11 +193,11 @@ static errcode_t patch_set_blksize(io_channel channel, int blksize)
data = (struct patch_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
channel->block_size = (unsigned)blksize;
if (data->patch.block_size && data->patch.block_size != (unsigned)blksize)
return EINVAL;
if (data->real)
retval = io_channel_set_blksize(data->real, blksize);
channel->block_size = (unsigned)blksize;
return retval;
}
@ -264,6 +264,32 @@ static errcode_t patch_write_blk64(io_channel channel, unsigned long long block,
retval = ext2fs_patch_init_bmap(&data->patch, channel);
if (retval)
return retval;
// libext2fs changes block size to 1024 in order to write the superblock, so we must support it...
if ((__u32)channel->block_size < data->patch.block_size)
{
void *buf2 = NULL;
unsigned long long block_real = block / (data->patch.block_size / channel->block_size);
int count_real = ( (block % (data->patch.block_size / channel->block_size))
+ (count > 0 ? count*channel->block_size : -count)
+ data->patch.block_size - 1 ) / data->patch.block_size;
retval = ext2fs_get_mem(count_real * data->patch.block_size, &buf2);
if (retval)
goto out;
retval = patch_read_blk64(channel, block_real, count_real, buf2);
if (retval)
goto out;
memcpy(buf2 + (block % (data->patch.block_size / channel->block_size)) * channel->block_size,
buf, (count > 0 ? count*channel->block_size : -count));
retval = ext2fs_patch_write_blk64(&data->patch, block_real, count_real, buf2);
out:
if (buf2)
ext2fs_free_mem(&buf2);
return retval;
}
else if ((__u32)channel->block_size > data->patch.block_size)
{
return EXT2_ET_UNIMPLEMENTED;
}
return ext2fs_patch_write_blk64(&data->patch, block, count, buf);
}