@@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
8686 BlockDriverState * parent ,
8787 const BdrvChildClass * child_class ,
8888 BdrvChildRole child_role ,
89+ bool parse_filename ,
8990 Error * * errp );
9091
9192static bool bdrv_recurse_has_child (BlockDriverState * bs ,
@@ -2058,7 +2059,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
20582059 * block driver has been specified explicitly.
20592060 */
20602061static int bdrv_fill_options (QDict * * options , const char * filename ,
2061- int * flags , Error * * errp )
2062+ int * flags , bool allow_parse_filename ,
2063+ Error * * errp )
20622064{
20632065 const char * drvname ;
20642066 bool protocol = * flags & BDRV_O_PROTOCOL ;
@@ -2100,7 +2102,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
21002102 if (protocol && filename ) {
21012103 if (!qdict_haskey (* options , "filename" )) {
21022104 qdict_put_str (* options , "filename" , filename );
2103- parse_filename = true ;
2105+ parse_filename = allow_parse_filename ;
21042106 } else {
21052107 error_setg (errp , "Can't specify 'file' and 'filename' options at "
21062108 "the same time" );
@@ -3663,7 +3665,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
36633665 }
36643666
36653667 backing_hd = bdrv_open_inherit (backing_filename , reference , options , 0 , bs ,
3666- & child_of_bds , bdrv_backing_role (bs ), errp );
3668+ & child_of_bds , bdrv_backing_role (bs ), true,
3669+ errp );
36673670 if (!backing_hd ) {
36683671 bs -> open_flags |= BDRV_O_NO_BACKING ;
36693672 error_prepend (errp , "Could not open backing file: " );
@@ -3697,7 +3700,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
36973700static BlockDriverState *
36983701bdrv_open_child_bs (const char * filename , QDict * options , const char * bdref_key ,
36993702 BlockDriverState * parent , const BdrvChildClass * child_class ,
3700- BdrvChildRole child_role , bool allow_none , Error * * errp )
3703+ BdrvChildRole child_role , bool allow_none ,
3704+ bool parse_filename , Error * * errp )
37013705{
37023706 BlockDriverState * bs = NULL ;
37033707 QDict * image_options ;
@@ -3728,7 +3732,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
37283732 }
37293733
37303734 bs = bdrv_open_inherit (filename , reference , image_options , 0 ,
3731- parent , child_class , child_role , errp );
3735+ parent , child_class , child_role , parse_filename ,
3736+ errp );
37323737 if (!bs ) {
37333738 goto done ;
37343739 }
@@ -3738,6 +3743,33 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
37383743 return bs ;
37393744}
37403745
3746+ static BdrvChild * bdrv_open_child_common (const char * filename ,
3747+ QDict * options , const char * bdref_key ,
3748+ BlockDriverState * parent ,
3749+ const BdrvChildClass * child_class ,
3750+ BdrvChildRole child_role ,
3751+ bool allow_none , bool parse_filename ,
3752+ Error * * errp )
3753+ {
3754+ BlockDriverState * bs ;
3755+ BdrvChild * child ;
3756+
3757+ GLOBAL_STATE_CODE ();
3758+
3759+ bs = bdrv_open_child_bs (filename , options , bdref_key , parent , child_class ,
3760+ child_role , allow_none , parse_filename , errp );
3761+ if (bs == NULL ) {
3762+ return NULL ;
3763+ }
3764+
3765+ bdrv_graph_wrlock ();
3766+ child = bdrv_attach_child (parent , bs , bdref_key , child_class , child_role ,
3767+ errp );
3768+ bdrv_graph_wrunlock ();
3769+
3770+ return child ;
3771+ }
3772+
37413773/*
37423774 * Opens a disk image whose options are given as BlockdevRef in another block
37433775 * device's options.
@@ -3761,27 +3793,15 @@ BdrvChild *bdrv_open_child(const char *filename,
37613793 BdrvChildRole child_role ,
37623794 bool allow_none , Error * * errp )
37633795{
3764- BlockDriverState * bs ;
3765- BdrvChild * child ;
3766-
3767- GLOBAL_STATE_CODE ();
3768-
3769- bs = bdrv_open_child_bs (filename , options , bdref_key , parent , child_class ,
3770- child_role , allow_none , errp );
3771- if (bs == NULL ) {
3772- return NULL ;
3773- }
3774-
3775- bdrv_graph_wrlock ();
3776- child = bdrv_attach_child (parent , bs , bdref_key , child_class , child_role ,
3777- errp );
3778- bdrv_graph_wrunlock ();
3779-
3780- return child ;
3796+ return bdrv_open_child_common (filename , options , bdref_key , parent ,
3797+ child_class , child_role , allow_none , false,
3798+ errp );
37813799}
37823800
37833801/*
3784- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
3802+ * This does mostly the same as bdrv_open_child(), but for opening the primary
3803+ * child of a node. A notable difference from bdrv_open_child() is that it
3804+ * enables filename parsing for protocol names (including json:).
37853805 *
37863806 * @parent can move to a different AioContext in this function.
37873807 */
@@ -3796,8 +3816,8 @@ int bdrv_open_file_child(const char *filename,
37963816 role = parent -> drv -> is_filter ?
37973817 (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY ) : BDRV_CHILD_IMAGE ;
37983818
3799- if (!bdrv_open_child (filename , options , bdref_key , parent ,
3800- & child_of_bds , role , false, errp ))
3819+ if (!bdrv_open_child_common (filename , options , bdref_key , parent ,
3820+ & child_of_bds , role , false, true , errp ))
38013821 {
38023822 return - EINVAL ;
38033823 }
@@ -3842,7 +3862,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
38423862
38433863 }
38443864
3845- bs = bdrv_open_inherit (NULL , reference , qdict , 0 , NULL , NULL , 0 , errp );
3865+ bs = bdrv_open_inherit (NULL , reference , qdict , 0 , NULL , NULL , 0 , false,
3866+ errp );
38463867 obj = NULL ;
38473868 qobject_unref (obj );
38483869 visit_free (v );
@@ -3932,7 +3953,7 @@ static BlockDriverState * no_coroutine_fn
39323953bdrv_open_inherit (const char * filename , const char * reference , QDict * options ,
39333954 int flags , BlockDriverState * parent ,
39343955 const BdrvChildClass * child_class , BdrvChildRole child_role ,
3935- Error * * errp )
3956+ bool parse_filename , Error * * errp )
39363957{
39373958 int ret ;
39383959 BlockBackend * file = NULL ;
@@ -3980,9 +4001,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
39804001 }
39814002
39824003 /* json: syntax counts as explicit options, as if in the QDict */
3983- parse_json_protocol (options , & filename , & local_err );
3984- if (local_err ) {
3985- goto fail ;
4004+ if (parse_filename ) {
4005+ parse_json_protocol (options , & filename , & local_err );
4006+ if (local_err ) {
4007+ goto fail ;
4008+ }
39864009 }
39874010
39884011 bs -> explicit_options = qdict_clone_shallow (options );
@@ -4007,7 +4030,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
40074030 parent -> open_flags , parent -> options );
40084031 }
40094032
4010- ret = bdrv_fill_options (& options , filename , & flags , & local_err );
4033+ ret = bdrv_fill_options (& options , filename , & flags , parse_filename ,
4034+ & local_err );
40114035 if (ret < 0 ) {
40124036 goto fail ;
40134037 }
@@ -4076,7 +4100,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
40764100
40774101 file_bs = bdrv_open_child_bs (filename , options , "file" , bs ,
40784102 & child_of_bds , BDRV_CHILD_IMAGE ,
4079- true, & local_err );
4103+ true, true, & local_err );
40804104 if (local_err ) {
40814105 goto fail ;
40824106 }
@@ -4225,7 +4249,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
42254249 GLOBAL_STATE_CODE ();
42264250
42274251 return bdrv_open_inherit (filename , reference , options , flags , NULL ,
4228- NULL , 0 , errp );
4252+ NULL , 0 , true, errp );
42294253}
42304254
42314255/* Return true if the NULL-terminated @list contains @str */
0 commit comments