On 4/26/22 10:51, Emanuele Giuseppe Esposito wrote:
The only problem here is ->attach and ->detach callbacks
could call bdrv_{un}apply_subtree_drain(), which itself
will use a rdlock to navigate through all nodes.
To avoid deadlocks, take the lock only outside the drains,
and if we need to both attach and detach, do it in a single
critical section.
Therefore change ->attach and ->detach to return true if they
are modifying the lock, so that we don't take it twice or release
temporarly.
An alternative way to implement this could be
struct GraphLockState {
bool taken;
}
void bdrv_graph_ensure_wrlock(GraphLockState *state)
{
if (state->taken) {
return;
}
bdrv_graph_wrlock();
state->taken = true;
}
void bdrv_graph_ensure_wrunlock(GraphLockState *state)
{
...
}
and pass the GraphLockState* to ->attach and ->detach.
Paolo