aboutsummaryrefslogtreecommitdiff
path: root/include/block/block_int.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/block/block_int.h')
-rw-r--r--include/block/block_int.h15
1 files changed, 14 insertions, 1 deletions
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 5090253..3aa1e83 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -664,11 +664,15 @@ struct BdrvChildRole {
* These functions must not change the graph (and therefore also must not
* call aio_poll(), which could change the graph indirectly).
*
+ * If drained_end() schedules background operations, it must atomically
+ * increment *drained_end_counter for each such operation and atomically
+ * decrement it once the operation has settled.
+ *
* Note that this can be nested. If drained_begin() was called twice, new
* I/O is allowed only after drained_end() was called twice, too.
*/
void (*drained_begin)(BdrvChild *child);
- void (*drained_end)(BdrvChild *child);
+ void (*drained_end)(BdrvChild *child, int *drained_end_counter);
/*
* Returns whether the parent has pending requests for the child. This
@@ -729,6 +733,15 @@ struct BdrvChild {
*/
bool frozen;
+ /*
+ * How many times the parent of this child has been drained
+ * (through role->drained_*).
+ * Usually, this is equal to bs->quiesce_counter (potentially
+ * reduced by bdrv_drain_all_count). It may differ while the
+ * child is entering or leaving a drained section.
+ */
+ int parent_quiesce_counter;
+
QLIST_ENTRY(BdrvChild) next;
QLIST_ENTRY(BdrvChild) next_parent;
};