@ -641,55 +641,53 @@ out:
return ret ;
return ret ;
}
}
static int bdrv_qed_create ( const char * filename , QEMUOptionParameter * options ,
static int bdrv_qed_create ( const char * filename , QemuOpts * opts , Error * * errp )
Error * * errp )
{
{
uint64_t image_size = 0 ;
uint64_t image_size = 0 ;
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE ;
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE ;
uint32_t table_size = QED_DEFAULT_TABLE_SIZE ;
uint32_t table_size = QED_DEFAULT_TABLE_SIZE ;
const char * backing_file = NULL ;
char * backing_file = NULL ;
const char * backing_fmt = NULL ;
char * backing_fmt = NULL ;
int ret ;
while ( options & & options - > name ) {
if ( ! strcmp ( options - > name , BLOCK_OPT_SIZE ) ) {
image_size = qemu_opt_get_size_del ( opts , BLOCK_OPT_SIZE , 0 ) ;
image_size = options - > value . n ;
backing_file = qemu_opt_get_del ( opts , BLOCK_OPT_BACKING_FILE ) ;
} else if ( ! strcmp ( options - > name , BLOCK_OPT_BACKING_FILE ) ) {
backing_fmt = qemu_opt_get_del ( opts , BLOCK_OPT_BACKING_FMT ) ;
backing_file = options - > value . s ;
cluster_size = qemu_opt_get_size_del ( opts ,
} else if ( ! strcmp ( options - > name , BLOCK_OPT_BACKING_FMT ) ) {
BLOCK_OPT_CLUSTER_SIZE ,
backing_fmt = options - > value . s ;
QED_DEFAULT_CLUSTER_SIZE ) ;
} else if ( ! strcmp ( options - > name , BLOCK_OPT_CLUSTER_SIZE ) ) {
table_size = qemu_opt_get_size_del ( opts , BLOCK_OPT_TABLE_SIZE ,
if ( options - > value . n ) {
QED_DEFAULT_TABLE_SIZE ) ;
cluster_size = options - > value . n ;
}
} else if ( ! strcmp ( options - > name , BLOCK_OPT_TABLE_SIZE ) ) {
if ( options - > value . n ) {
table_size = options - > value . n ;
}
}
options + + ;
}
if ( ! qed_is_cluster_size_valid ( cluster_size ) ) {
if ( ! qed_is_cluster_size_valid ( cluster_size ) ) {
error_setg ( errp , " QED cluster size must be within range [%u, %u] "
error_setg ( errp , " QED cluster size must be within range [%u, %u] "
" and power of 2 " ,
" and power of 2 " ,
QED_MIN_CLUSTER_SIZE , QED_MAX_CLUSTER_SIZE ) ;
QED_MIN_CLUSTER_SIZE , QED_MAX_CLUSTER_SIZE ) ;
return - EINVAL ;
ret = - EINVAL ;
goto finish ;
}
}
if ( ! qed_is_table_size_valid ( table_size ) ) {
if ( ! qed_is_table_size_valid ( table_size ) ) {
error_setg ( errp , " QED table size must be within range [%u, %u] "
error_setg ( errp , " QED table size must be within range [%u, %u] "
" and power of 2 " ,
" and power of 2 " ,
QED_MIN_TABLE_SIZE , QED_MAX_TABLE_SIZE ) ;
QED_MIN_TABLE_SIZE , QED_MAX_TABLE_SIZE ) ;
return - EINVAL ;
ret = - EINVAL ;
goto finish ;
}
}
if ( ! qed_is_image_size_valid ( image_size , cluster_size , table_size ) ) {
if ( ! qed_is_image_size_valid ( image_size , cluster_size , table_size ) ) {
error_setg ( errp , " QED image size must be a non-zero multiple of "
error_setg ( errp , " QED image size must be a non-zero multiple of "
" cluster size and less than % " PRIu64 " bytes " ,
" cluster size and less than % " PRIu64 " bytes " ,
qed_max_image_size ( cluster_size , table_size ) ) ;
qed_max_image_size ( cluster_size , table_size ) ) ;
return - EINVAL ;
ret = - EINVAL ;
goto finish ;
}
}
return qed_create ( filename , cluster_size , image_size , table_size ,
ret = qed_create ( filename , cluster_size , image_size , table_size ,
backing_file , backing_fmt , errp ) ;
backing_file , backing_fmt , errp ) ;
finish :
g_free ( backing_file ) ;
g_free ( backing_fmt ) ;
return ret ;
}
}
typedef struct {
typedef struct {
@ -1616,43 +1614,51 @@ static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
return qed_check ( s , result , ! ! fix ) ;
return qed_check ( s , result , ! ! fix ) ;
}
}
static QEMUOptionParameter qed_create_options [ ] = {
static QemuOptsList qed_create_opts = {
{
. name = " qed-create-opts " ,
. name = BLOCK_OPT_SIZE ,
. head = QTAILQ_HEAD_INITIALIZER ( qed_create_opts . head ) ,
. type = OPT_SIZE ,
. desc = {
. help = " Virtual disk size (in bytes) "
{
} , {
. name = BLOCK_OPT_SIZE ,
. name = BLOCK_OPT_BACKING_FILE ,
. type = QEMU_OPT_SIZE ,
. type = OPT_STRING ,
. help = " Virtual disk size "
. help = " File name of a base image "
} ,
} , {
{
. name = BLOCK_OPT_BACKING_FMT ,
. name = BLOCK_OPT_BACKING_FILE ,
. type = OPT_STRING ,
. type = QEMU_OPT_STRING ,
. help = " Image format of the base image "
. help = " File name of a base image "
} , {
} ,
. name = BLOCK_OPT_CLUSTER_SIZE ,
{
. type = OPT_SIZE ,
. name = BLOCK_OPT_BACKING_FMT ,
. help = " Cluster size (in bytes) " ,
. type = QEMU_OPT_STRING ,
. value = { . n = QED_DEFAULT_CLUSTER_SIZE } ,
. help = " Image format of the base image "
} , {
} ,
. name = BLOCK_OPT_TABLE_SIZE ,
{
. type = OPT_SIZE ,
. name = BLOCK_OPT_CLUSTER_SIZE ,
. help = " L1/L2 table size (in clusters) "
. type = QEMU_OPT_SIZE ,
} ,
. help = " Cluster size (in bytes) " ,
{ /* end of list */ }
. def_value_str = stringify ( QED_DEFAULT_CLUSTER_SIZE )
} ,
{
. name = BLOCK_OPT_TABLE_SIZE ,
. type = QEMU_OPT_SIZE ,
. help = " L1/L2 table size (in clusters) "
} ,
{ /* end of list */ }
}
} ;
} ;
static BlockDriver bdrv_qed = {
static BlockDriver bdrv_qed = {
. format_name = " qed " ,
. format_name = " qed " ,
. instance_size = sizeof ( BDRVQEDState ) ,
. instance_size = sizeof ( BDRVQEDState ) ,
. create_options = qed_create_options ,
. create_opts = & qed_create_opts ,
. bdrv_probe = bdrv_qed_probe ,
. bdrv_probe = bdrv_qed_probe ,
. bdrv_rebind = bdrv_qed_rebind ,
. bdrv_rebind = bdrv_qed_rebind ,
. bdrv_open = bdrv_qed_open ,
. bdrv_open = bdrv_qed_open ,
. bdrv_close = bdrv_qed_close ,
. bdrv_close = bdrv_qed_close ,
. bdrv_reopen_prepare = bdrv_qed_reopen_prepare ,
. bdrv_reopen_prepare = bdrv_qed_reopen_prepare ,
. bdrv_create = bdrv_qed_create ,
. bdrv_create2 = bdrv_qed_create ,
. bdrv_has_zero_init = bdrv_has_zero_init_1 ,
. bdrv_has_zero_init = bdrv_has_zero_init_1 ,
. bdrv_co_get_block_status = bdrv_qed_co_get_block_status ,
. bdrv_co_get_block_status = bdrv_qed_co_get_block_status ,
. bdrv_aio_readv = bdrv_qed_aio_readv ,
. bdrv_aio_readv = bdrv_qed_aio_readv ,