Revision b64ec4e4 block.c
b/block.c | ||
---|---|---|
328 | 328 |
return NULL; |
329 | 329 |
} |
330 | 330 |
|
331 |
static int bdrv_is_whitelisted(BlockDriver *drv) |
|
331 |
static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
|
|
332 | 332 |
{ |
333 |
static const char *whitelist[] = { |
|
334 |
CONFIG_BDRV_WHITELIST |
|
333 |
static const char *whitelist_rw[] = { |
|
334 |
CONFIG_BDRV_RW_WHITELIST |
|
335 |
}; |
|
336 |
static const char *whitelist_ro[] = { |
|
337 |
CONFIG_BDRV_RO_WHITELIST |
|
335 | 338 |
}; |
336 | 339 |
const char **p; |
337 | 340 |
|
338 |
if (!whitelist[0])
|
|
341 |
if (!whitelist_rw[0] && !whitelist_ro[0]) {
|
|
339 | 342 |
return 1; /* no whitelist, anything goes */ |
343 |
} |
|
340 | 344 |
|
341 |
for (p = whitelist; *p; p++) { |
|
345 |
for (p = whitelist_rw; *p; p++) {
|
|
342 | 346 |
if (!strcmp(drv->format_name, *p)) { |
343 | 347 |
return 1; |
344 | 348 |
} |
345 | 349 |
} |
350 |
if (read_only) { |
|
351 |
for (p = whitelist_ro; *p; p++) { |
|
352 |
if (!strcmp(drv->format_name, *p)) { |
|
353 |
return 1; |
|
354 |
} |
|
355 |
} |
|
356 |
} |
|
346 | 357 |
return 0; |
347 | 358 |
} |
348 | 359 |
|
349 |
BlockDriver *bdrv_find_whitelisted_format(const char *format_name) |
|
360 |
BlockDriver *bdrv_find_whitelisted_format(const char *format_name, |
|
361 |
bool read_only) |
|
350 | 362 |
{ |
351 | 363 |
BlockDriver *drv = bdrv_find_format(format_name); |
352 |
return drv && bdrv_is_whitelisted(drv) ? drv : NULL; |
|
364 |
return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
|
|
353 | 365 |
} |
354 | 366 |
|
355 | 367 |
typedef struct CreateCo { |
... | ... | |
684 | 696 |
|
685 | 697 |
trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name); |
686 | 698 |
|
687 |
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { |
|
688 |
return -ENOTSUP; |
|
689 |
} |
|
690 |
|
|
691 | 699 |
/* bdrv_open() with directly using a protocol as drv. This layer is already |
692 | 700 |
* opened, so assign it to bs (while file becomes a closed BlockDriverState) |
693 | 701 |
* and return immediately. */ |
... | ... | |
698 | 706 |
|
699 | 707 |
bs->open_flags = flags; |
700 | 708 |
bs->buffer_alignment = 512; |
709 |
open_flags = bdrv_open_flags(bs, flags); |
|
710 |
bs->read_only = !(open_flags & BDRV_O_RDWR); |
|
711 |
|
|
712 |
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) { |
|
713 |
return -ENOTSUP; |
|
714 |
} |
|
701 | 715 |
|
702 | 716 |
assert(bs->copy_on_read == 0); /* bdrv_new() and bdrv_close() make it so */ |
703 |
if ((flags & BDRV_O_RDWR) && (flags & BDRV_O_COPY_ON_READ)) {
|
|
717 |
if (!bs->read_only && (flags & BDRV_O_COPY_ON_READ)) {
|
|
704 | 718 |
bdrv_enable_copy_on_read(bs); |
705 | 719 |
} |
706 | 720 |
|
... | ... | |
714 | 728 |
bs->opaque = g_malloc0(drv->instance_size); |
715 | 729 |
|
716 | 730 |
bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB); |
717 |
open_flags = bdrv_open_flags(bs, flags); |
|
718 |
|
|
719 |
bs->read_only = !(open_flags & BDRV_O_RDWR); |
|
720 | 731 |
|
721 | 732 |
/* Open the image, either directly or using a protocol */ |
722 | 733 |
if (drv->bdrv_file_open) { |
... | ... | |
801 | 812 |
/* Find the right block driver */ |
802 | 813 |
drvname = qdict_get_try_str(options, "driver"); |
803 | 814 |
if (drvname) { |
804 |
drv = bdrv_find_whitelisted_format(drvname); |
|
815 |
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
|
|
805 | 816 |
qdict_del(options, "driver"); |
806 | 817 |
} else if (filename) { |
807 | 818 |
drv = bdrv_find_protocol(filename); |
Also available in: Unified diff