diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2016-06-16 17:56:26 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2016-06-20 14:25:41 +0100 |
commit | e8a095dadb70e2ea6d5169d261920db3747bfa45 (patch) | |
tree | 3139d49c4ca3affbbd21565720366070c8f095a5 /include/block | |
parent | 9f6bc648c40da61a50ea1f51048368faeea5d9a1 (diff) |
block: use safe iteration over AioContext notifiers
It's possible that an AioContext notifier user was close to finishing
when .detach_aio_context() or .attached_aio_context() is called. In
that case they may call bdrv_remove_aio_context_notifier() during the
callback.
Use safe iteration to avoid crashing when the notifier list is modified
during iteration. We must not only handle the case where the current
aio notifier is removed during a callback but also the one where any
other aio notifier is removed.
The next patch adds an AioContext notifier for block jobs and they
really could be terminating just as .detach_aio_context() is invoked.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1466096189-6477-6-git-send-email-stefanha@redhat.com
Diffstat (limited to 'include/block')
-rw-r--r-- | include/block/block_int.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/block/block_int.h b/include/block/block_int.h index 688c6be009..205715600b 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -361,6 +361,7 @@ typedef struct BdrvAioNotifier { void (*detach_aio_context)(void *opaque); void *opaque; + bool deleted; QLIST_ENTRY(BdrvAioNotifier) list; } BdrvAioNotifier; @@ -427,6 +428,7 @@ struct BlockDriverState { * BDS may register themselves in this list to be notified of changes * regarding this BDS's context */ QLIST_HEAD(, BdrvAioNotifier) aio_notifiers; + bool walking_aio_notifiers; /* to make removal during iteration safe */ char filename[PATH_MAX]; char backing_file[PATH_MAX]; /* if non zero, the image is a diff of |