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


Reply via email to