summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
Diffstat (limited to 'block.c')
-rw-r--r--block.c69
1 files changed, 57 insertions, 12 deletions
diff --git a/block.c b/block.c
index 1919d19732..af56ea7372 100644
--- a/block.c
+++ b/block.c
@@ -451,13 +451,20 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
bs->enable_write_cache = 1;
bs->read_only = (flags & BDRV_O_RDWR) == 0;
- if (!(flags & BDRV_O_FILE)) {
- open_flags = (flags & (BDRV_O_RDWR | BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
- if (bs->is_temporary) { /* snapshot should be writeable */
- open_flags |= BDRV_O_RDWR;
- }
- } else {
- open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
+
+ /*
+ * Clear flags that are internal to the block layer before opening the
+ * image.
+ */
+ open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+
+ /*
+ * Snapshots should be writeable.
+ *
+ * XXX(hch): and what is the point of a snapshot during a read-only open?
+ */
+ if (!(flags & BDRV_O_FILE) && bs->is_temporary) {
+ open_flags |= BDRV_O_RDWR;
}
ret = drv->bdrv_open(bs, filename, open_flags);
@@ -686,9 +693,15 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
bit = start % (sizeof(unsigned long) * 8);
val = bs->dirty_bitmap[idx];
if (dirty) {
- val |= 1 << bit;
+ if (!(val & (1 << bit))) {
+ bs->dirty_count++;
+ val |= 1 << bit;
+ }
} else {
- val &= ~(1 << bit);
+ if (val & (1 << bit)) {
+ bs->dirty_count--;
+ val &= ~(1 << bit);
+ }
}
bs->dirty_bitmap[idx] = val;
}
@@ -1164,6 +1177,35 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
}
+void bdrv_mon_event(const BlockDriverState *bdrv,
+ BlockMonEventAction action, int is_read)
+{
+ QObject *data;
+ const char *action_str;
+
+ switch (action) {
+ case BDRV_ACTION_REPORT:
+ action_str = "report";
+ break;
+ case BDRV_ACTION_IGNORE:
+ action_str = "ignore";
+ break;
+ case BDRV_ACTION_STOP:
+ action_str = "stop";
+ break;
+ default:
+ abort();
+ }
+
+ data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
+ bdrv->device_name,
+ action_str,
+ is_read ? "read" : "write");
+ monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
+
+ qobject_decref(data);
+}
+
static void bdrv_print_dict(QObject *obj, void *opaque)
{
QDict *bs_dict;
@@ -1259,7 +1301,6 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
"'removable': %i, 'locked': %i }",
bs->device_name, type, bs->removable,
bs->locked);
- assert(bs_obj != NULL);
if (bs->drv) {
QObject *obj;
@@ -1270,7 +1311,6 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
bs->filename, bs->read_only,
bs->drv->format_name,
bdrv_is_encrypted(bs));
- assert(obj != NULL);
if (bs->backing_file[0] != '\0') {
QDict *qdict = qobject_to_qdict(obj);
qdict_put(qdict, "backing_file",
@@ -1356,7 +1396,6 @@ void bdrv_info_stats(Monitor *mon, QObject **ret_data)
bs->device_name,
bs->rd_bytes, bs->wr_bytes,
bs->rd_ops, bs->wr_ops);
- assert(obj != NULL);
qlist_append_obj(devices, obj);
}
@@ -2139,6 +2178,7 @@ void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
{
int64_t bitmap_size;
+ bs->dirty_count = 0;
if (enable) {
if (!bs->dirty_bitmap) {
bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
@@ -2173,3 +2213,8 @@ void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
{
set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
}
+
+int64_t bdrv_get_dirty_count(BlockDriverState *bs)
+{
+ return bs->dirty_count;
+}