func: static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm,
  
                                    uint64_t new_shared_perm,
  
                                    BdrvChild *ignore_child, Error **errp)
  
  {
  
      BdrvChild *c;
  
      uint64_t cumulative_perms = new_used_perm;
  
      uint64_t cumulative_shared_perms = new_shared_perm;
  
  
  
      /* There is no reason why anyone couldn't tolerate write_unchanged */
  
      assert(new_shared_perm & BLK_PERM_WRITE_UNCHANGED);
  
  
  
      QLIST_FOREACH(c, &bs->parents, next_parent) {
  
          if (c == ignore_child) {
  
              continue;
  
          }
  
  
  
          if ((new_used_perm & c->shared_perm) != new_used_perm) {
  
              char *user = bdrv_child_user_desc(c);
  
              char *perm_names = bdrv_perm_names(new_used_perm & ~c->shared_perm);
  
              error_setg(errp, "Conflicts with use by %s as '%s', which does not "
  
                               "allow '%s' on %s",
  
                         user, c->name, perm_names, bdrv_get_node_name(c->bs));
  
              g_free(user);
  
              g_free(perm_names);
  
              return -EPERM;
  
          }
  
  
  
          if ((c->perm & new_shared_perm) != c->perm) {
  
              char *user = bdrv_child_user_desc(c);
  
              char *perm_names = bdrv_perm_names(c->perm & ~new_shared_perm);
  
              error_setg(errp, "Conflicts with use by %s as '%s', which uses "
  
                               "'%s' on %s",
  
                         user, c->name, perm_names, bdrv_get_node_name(c->bs));
  
              g_free(user);
  
              g_free(perm_names);
  
              return -EPERM;
  
          }
  
  
  
          cumulative_perms |= c->perm;
  
          cumulative_shared_perms &= c->shared_perm;
  
      }
  
  
  
      return bdrv_check_perm(bs, cumulative_perms, cumulative_shared_perms, errp);
  
  }
  