Am 27.11.2020 um 15:44 hat Vladimir Sementsov-Ogievskiy geschrieben: > Split out non-recursive parts, and refactor as block graph transaction > action. > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> > --- > block.c | 79 ++++++++++++++++++++++++++++++++++++++++++--------------- > 1 file changed, 59 insertions(+), 20 deletions(-) > > diff --git a/block.c b/block.c > index a756f3e8ad..7267b4a3e9 100644 > --- a/block.c > +++ b/block.c > @@ -48,6 +48,7 @@ > #include "qemu/timer.h" > #include "qemu/cutils.h" > #include "qemu/id.h" > +#include "qemu/transactions.h" > #include "block/coroutines.h" > > #ifdef CONFIG_BSD > @@ -2033,6 +2034,61 @@ static void bdrv_child_perm(BlockDriverState *bs, > BlockDriverState *child_bs, > } > } > > +static void bdrv_child_set_perm_commit(void *opaque) > +{ > + BdrvChild *c = opaque; > + > + c->has_backup_perm = false; > +} > + > +static void bdrv_child_set_perm_abort(void *opaque) > +{ > + BdrvChild *c = opaque; > + /* > + * We may have child->has_backup_perm unset at this point, as in case of > + * _check_ stage of permission update failure we may _check_ not the > whole > + * subtree. Still, _abort_ is called on the whole subtree anyway. > + */ > + if (c->has_backup_perm) { > + c->perm = c->backup_perm; > + c->shared_perm = c->backup_shared_perm; > + c->has_backup_perm = false; > + } > +} > + > +static TransactionActionDrv bdrv_child_set_pem_drv = { > + .abort = bdrv_child_set_perm_abort, > + .commit = bdrv_child_set_perm_commit, > +}; > + > +/* > + * With tran=NULL needs to be followed by direct call to either > + * bdrv_child_set_perm_commit() or bdrv_child_set_perm_abort(). > + * > + * With non-NUll tran needs to be followed by tran_abort() or tran_commit()
s/NUll/NULL/ > + * instead. > + */ > +static void bdrv_child_set_perm_safe(BdrvChild *c, uint64_t perm, > + uint64_t shared, GSList **tran) > +{ > + if (!c->has_backup_perm) { > + c->has_backup_perm = true; > + c->backup_perm = c->perm; > + c->backup_shared_perm = c->shared_perm; > + } This is the obvious refactoring at this point, and it's fine as such. However, when you start to actually use tran (and in new places), it means that I have to check that we can never end up here recursively with a different tran. It would probably be much cleaner if the next patch moved the backup state into the opaque struct for BdrvAction. Kevin