On Thu, Feb 21, 2013 at 10:47:05AM +0100, Kevin Wolf wrote: > On Mon, Feb 18, 2013 at 04:46:49PM +0100, Stefan Hajnoczi wrote: > > On Wed, Feb 13, 2013 at 02:22:10PM +0100, Kevin Wolf wrote: > > > @@ -707,6 +710,16 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState > > > *bs, QCowL2Meta *m) > > > } > > > > > > /* Update L2 table. */ > > > + qemu_co_mutex_unlock(&s->lock); > > > + qemu_co_rwlock_wrlock(&m->l2_writeback_lock); > > > + has_wr_lock = true; > > > + qemu_co_mutex_lock(&s->lock); > > > + > > > + if (m->no_l2_update) { > > > > QcowL2Meta now has a no_l2_update field. A sign that we're abusing the > > QcowL2Meta struct and really need a different abstraction? > > I think the abstraction is the right one, even though maybe it could use > a rename. Maybe QcowL2Meta -> QcowCOWRequest or something. The comment > in qcow2.h correctly describes what it's meant for. > > /** > * Describes an in-flight (part of a) write request that writes to clusters > * that are not referenced in their L2 table yet. > */ > typedef struct QCowL2Meta > > However, I think m->no_l2_update is actually redundant: The goal is that > only one request that touches a cluster should be responsible for > updating the L2 table, and it makes sense to choose the first one to do > that. We already have this information in m->parent: The first one is > the root of the tree described by these parent links. So if I'm not > mistaken, m->no_l2_update == (m->parent != NULL).
Okay, that makes sense. Stefan