diff mbox

[v7,08/10] block: Add checks of blocker in block operations

Message ID 1386836626-6436-9-git-send-email-famz@redhat.com
State New
Headers show

Commit Message

Fam Zheng Dec. 12, 2013, 8:23 a.m. UTC
Before operate on a BlockDriverState, respective types are checked
against bs->op_blockers and it will error out if there's a blocker.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 block/snapshot.c | 11 +++++++++++
 blockdev.c       |  8 ++++++++
 2 files changed, 19 insertions(+)

Comments

Markus Armbruster Dec. 12, 2013, 1:56 p.m. UTC | #1
Fam Zheng <famz@redhat.com> writes:

> Before operate on a BlockDriverState, respective types are checked
> against bs->op_blockers and it will error out if there's a blocker.
>
> Signed-off-by: Fam Zheng <famz@redhat.com>

So this patch adds protection against "two of the same kind
simultaneously".  How could we check it's complete?

Have we pondered the more general problem of which "operations"
(whatever that is) exclude each other?

[...]
Fam Zheng Dec. 13, 2013, 3:29 a.m. UTC | #2
On 2013年12月12日 21:56, Markus Armbruster wrote:
> Fam Zheng <famz@redhat.com> writes:
>
>> Before operate on a BlockDriverState, respective types are checked
>> against bs->op_blockers and it will error out if there's a blocker.
>>
>> Signed-off-by: Fam Zheng <famz@redhat.com>
>
> So this patch adds protection against "two of the same kind
> simultaneously".  How could we check it's complete?
>
> Have we pondered the more general problem of which "operations"
> (whatever that is) exclude each other?
>

Good point. For what we want now, I think these extra checks are not 
required. I think these could be added in a separate series if any. 
Planning to drop it for next revision but the discussion is still open.

Thanks,
Fam
diff mbox

Patch

diff --git a/block/snapshot.c b/block/snapshot.c
index 02cfb07..0dc8f40 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -164,6 +164,11 @@  int bdrv_snapshot_create(BlockDriverState *bs,
     if (!drv) {
         return -ENOMEDIUM;
     }
+
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
+        return -EPERM;
+    }
+
     if (drv->bdrv_snapshot_create) {
         return drv->bdrv_snapshot_create(bs, sn_info);
     }
@@ -233,6 +238,12 @@  int bdrv_snapshot_delete(BlockDriverState *bs,
         error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
         return -ENOMEDIUM;
     }
+
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
+                           errp)) {
+        return -EPERM;
+    }
+
     if (!snapshot_id && !name) {
         error_setg(errp, "snapshot_id and name are both NULL");
         return -EINVAL;
diff --git a/blockdev.c b/blockdev.c
index 404159e..5e5d1b0 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1536,6 +1536,10 @@  void qmp_change_blockdev(const char *device, const char *filename,
         return;
     }
 
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) {
+        return;
+    }
+
     if (format) {
         drv = bdrv_find_whitelisted_format(format, bs->read_only);
         if (!drv) {
@@ -1684,6 +1688,10 @@  void qmp_block_resize(const char *device, int64_t size, Error **errp)
         return;
     }
 
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_RESIZE, errp)) {
+        return;
+    }
+
     if (size < 0) {
         error_set(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");
         return;