block.c (53e96d1e9f95606410d66bf6449214088970bbf8) block.c (3bf416ba0fdc0667e34ef912fbe1074ad259f533)
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 2012 unchanged lines hidden (view full) ---

2021 * the same as !bdrv_is_read_only(bs), as inactivated images may not
2022 * be written to but do not count as read-only images.
2023 */
2024bool bdrv_is_writable(BlockDriverState *bs)
2025{
2026 return bdrv_is_writable_after_reopen(bs, NULL);
2027}
2028
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 2012 unchanged lines hidden (view full) ---

2021 * the same as !bdrv_is_read_only(bs), as inactivated images may not
2022 * be written to but do not count as read-only images.
2023 */
2024bool bdrv_is_writable(BlockDriverState *bs)
2025{
2026 return bdrv_is_writable_after_reopen(bs, NULL);
2027}
2028
2029static char *bdrv_child_user_desc(BdrvChild *c)
2030{
2031 if (c->klass->get_parent_desc) {
2032 return c->klass->get_parent_desc(c);
2033 }
2034
2035 return g_strdup("another user");
2036}
2037
2038static bool bdrv_a_allow_b(BdrvChild *a, BdrvChild *b, Error **errp)
2039{
2040 g_autofree char *user = NULL;
2041 g_autofree char *perm_names = NULL;
2042
2043 if ((b->perm & a->shared_perm) == b->perm) {
2044 return true;
2045 }
2046
2047 perm_names = bdrv_perm_names(b->perm & ~a->shared_perm);
2048 user = bdrv_child_user_desc(a);
2049 error_setg(errp, "Conflicts with use by %s as '%s', which does not "
2050 "allow '%s' on %s",
2051 user, a->name, perm_names, bdrv_get_node_name(b->bs));
2052
2053 return false;
2054}
2055
2056static bool bdrv_parent_perms_conflict(BlockDriverState *bs, Error **errp)
2057{
2058 BdrvChild *a, *b;
2059
2060 /*
2061 * During the loop we'll look at each pair twice. That's correct because
2062 * bdrv_a_allow_b() is asymmetric and we should check each pair in both
2063 * directions.
2064 */
2065 QLIST_FOREACH(a, &bs->parents, next_parent) {
2066 QLIST_FOREACH(b, &bs->parents, next_parent) {
2067 if (a == b) {
2068 continue;
2069 }
2070
2071 if (!bdrv_a_allow_b(a, b, errp)) {
2072 return true;
2073 }
2074 }
2075 }
2076
2077 return false;
2078}
2079
2029static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
2030 BdrvChild *c, BdrvChildRole role,
2031 BlockReopenQueue *reopen_queue,
2032 uint64_t parent_perm, uint64_t parent_shared,
2033 uint64_t *nperm, uint64_t *nshared)
2034{
2035 assert(bs->drv && bs->drv->bdrv_child_perm);
2036 bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,

--- 161 unchanged lines hidden (view full) ---

2198 cumulative_perms |= c->perm;
2199 cumulative_shared_perms &= c->shared_perm;
2200 }
2201
2202 *perm = cumulative_perms;
2203 *shared_perm = cumulative_shared_perms;
2204}
2205
2080static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
2081 BdrvChild *c, BdrvChildRole role,
2082 BlockReopenQueue *reopen_queue,
2083 uint64_t parent_perm, uint64_t parent_shared,
2084 uint64_t *nperm, uint64_t *nshared)
2085{
2086 assert(bs->drv && bs->drv->bdrv_child_perm);
2087 bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,

--- 161 unchanged lines hidden (view full) ---

2249 cumulative_perms |= c->perm;
2250 cumulative_shared_perms &= c->shared_perm;
2251 }
2252
2253 *perm = cumulative_perms;
2254 *shared_perm = cumulative_shared_perms;
2255}
2256
2206static char *bdrv_child_user_desc(BdrvChild *c)
2207{
2208 if (c->klass->get_parent_desc) {
2209 return c->klass->get_parent_desc(c);
2210 }
2211
2212 return g_strdup("another user");
2213}
2214
2215char *bdrv_perm_names(uint64_t perm)
2216{
2217 struct perm_name {
2218 uint64_t perm;
2219 const char *name;
2220 } permissions[] = {
2221 { BLK_PERM_CONSISTENT_READ, "consistent read" },
2222 { BLK_PERM_WRITE, "write" },

--- 127 unchanged lines hidden (view full) ---

2350 bdrv_abort_perm_update(c->bs);
2351}
2352
2353static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
2354{
2355 int ret;
2356 uint64_t perm, shared_perm;
2357
2257char *bdrv_perm_names(uint64_t perm)
2258{
2259 struct perm_name {
2260 uint64_t perm;
2261 const char *name;
2262 } permissions[] = {
2263 { BLK_PERM_CONSISTENT_READ, "consistent read" },
2264 { BLK_PERM_WRITE, "write" },

--- 127 unchanged lines hidden (view full) ---

2392 bdrv_abort_perm_update(c->bs);
2393}
2394
2395static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
2396{
2397 int ret;
2398 uint64_t perm, shared_perm;
2399
2400 if (bdrv_parent_perms_conflict(bs, errp)) {
2401 return -EPERM;
2402 }
2358 bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
2359 ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, errp);
2360 if (ret < 0) {
2361 bdrv_abort_perm_update(bs);
2362 return ret;
2363 }
2364 bdrv_set_perm(bs);
2365

--- 4952 unchanged lines hidden ---
2403 bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
2404 ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, errp);
2405 if (ret < 0) {
2406 bdrv_abort_perm_update(bs);
2407 return ret;
2408 }
2409 bdrv_set_perm(bs);
2410

--- 4952 unchanged lines hidden ---