static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,

                           uint64_t cumulative_shared_perms, Error **errp)

{

    BlockDriver *drv = bs->drv;

    BdrvChild *c;

    int ret;



    /* Write permissions never work with read-only images */

    if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&

        bdrv_is_read_only(bs))

    {

        error_setg(errp, "Block node is read-only");

        return -EPERM;

    }



    /* Check this node */

    if (!drv) {

        return 0;

    }



    if (drv->bdrv_check_perm) {

        return drv->bdrv_check_perm(bs, cumulative_perms,

                                    cumulative_shared_perms, errp);

    }



    /* Drivers that never have children can omit .bdrv_child_perm() */

    if (!drv->bdrv_child_perm) {

        assert(QLIST_EMPTY(&bs->children));

        return 0;

    }



    /* Check all children */

    QLIST_FOREACH(c, &bs->children, next) {

        uint64_t cur_perm, cur_shared;

        drv->bdrv_child_perm(bs, c, c->role,

                             cumulative_perms, cumulative_shared_perms,

                             &cur_perm, &cur_shared);

        ret = bdrv_child_check_perm(c, cur_perm, cur_shared, errp);

        if (ret < 0) {

            return ret;

        }

    }



    return 0;

}

static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,

                           uint64_t cumulative_shared_perms, Error **errp)

{

    BlockDriver *drv = bs->drv;

    BdrvChild *c;

    int ret;



    

    if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&

        bdrv_is_read_only(bs))

    {

        error_setg(errp, "Block node is read-only");

        return -EPERM;

    }



    

    if (!drv) {

        return 0;

    }



    if (drv->bdrv_check_perm) {

        return drv->bdrv_check_perm(bs, cumulative_perms,

                                    cumulative_shared_perms, errp);

    }



    

    if (!drv->bdrv_child_perm) {

        assert(QLIST_EMPTY(&bs->children));

        return 0;

    }



    

    QLIST_FOREACH(c, &bs->children, next) {

        uint64_t cur_perm, cur_shared;

        drv->bdrv_child_perm(bs, c, c->role,

                             cumulative_perms, cumulative_shared_perms,

                             &cur_perm, &cur_shared);

        ret = bdrv_child_check_perm(c, cur_perm, cur_shared, errp);

        if (ret < 0) {

            return ret;

        }

    }



    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,

                           uint64_t VAR_2, Error **VAR_3)

{

    BlockDriver *drv = VAR_0->drv;

    BdrvChild *c;

    int VAR_4;



    

    if ((VAR_1 & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&

        bdrv_is_read_only(VAR_0))

    {

        error_setg(VAR_3, "Block node is read-only");

        return -EPERM;

    }



    

    if (!drv) {

        return 0;

    }



    if (drv->FUNC_0) {

        return drv->FUNC_0(VAR_0, VAR_1,

                                    VAR_2, VAR_3);

    }



    

    if (!drv->bdrv_child_perm) {

        assert(QLIST_EMPTY(&VAR_0->children));

        return 0;

    }



    

    QLIST_FOREACH(c, &VAR_0->children, next) {

        uint64_t cur_perm, cur_shared;

        drv->bdrv_child_perm(VAR_0, c, c->role,

                             VAR_1, VAR_2,

                             &cur_perm, &cur_shared);

        VAR_4 = bdrv_child_check_perm(c, cur_perm, cur_shared, VAR_3);

        if (VAR_4 < 0) {

            return VAR_4;

        }

    }



    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,
uint64_t VAR_2, Error **VAR_3)
{ BlockDriver *drv = VAR_0->drv; BdrvChild *c; int VAR_4; if ((VAR_1 & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
bdrv_is_read_only(VAR_0))
{ error_setg(VAR_3, "Block node is read-only"); return -EPERM; } if (!drv) { return 0; } if (drv->FUNC_0) { return drv->FUNC_0(VAR_0, VAR_1,
VAR_2, VAR_3); } if (!drv->bdrv_child_perm) { assert(QLIST_EMPTY(&VAR_0->children)); return 0; } QLIST_FOREACH(c, &VAR_0->children, next) { uint64_t cur_perm, cur_shared; drv->bdrv_child_perm(VAR_0, c, c->role,
VAR_1, VAR_2,
&cur_perm, &cur_shared); VAR_4 = bdrv_child_check_perm(c, cur_perm, cur_shared, VAR_3); if (VAR_4 < 0) { return VAR_4; } } return 0; }