From: Joe Thornber <ejt@xxxxxxxxxx> The holder can be passed down to lower devices which may want to use bi_next themselves. Also add BUG_ON check to confirm fix. When releasing bios that have been detained in a cell, fix the order in which the holder and other cellmates are added to the inmates list: append holder first followed by the other cellmates. Signed-off-by: Joe Thornber <ejt@xxxxxxxxxx> Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> --- drivers/md/dm-thin.c | 29 +++++++++++++++++------------ 1 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index f796afb..a148532 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -125,7 +125,7 @@ struct cell { struct hlist_node list; struct bio_prison *prison; struct cell_key key; - unsigned count; + struct bio *holder; struct bio_list bios; }; @@ -221,8 +221,7 @@ static struct cell *__search_bucket(struct hlist_head *bucket, * This may block if a new cell needs allocating. You must ensure that * cells will be unlocked even if the calling thread is blocked. * - * Returns the number of entries in the cell prior to the new addition - * or < 0 on failure. + * Returns 1 if the cell was already held, 0 if @inmate is the new holder. */ static int bio_detain(struct bio_prison *prison, struct cell_key *key, struct bio *inmate, struct cell **ref) @@ -257,21 +256,25 @@ static int bio_detain(struct bio_prison *prison, struct cell_key *key, cell->prison = prison; memcpy(&cell->key, key, sizeof(cell->key)); - cell->count = 0; + cell->holder = inmate; bio_list_init(&cell->bios); hlist_add_head(&cell->list, prison->cells + hash); + r = 0; + + } else { + mempool_free(cell2, prison->cell_pool); + cell2 = NULL; + r = 1; + bio_list_add(&cell->bios, inmate); } - } - r = cell->count++; - bio_list_add(&cell->bios, inmate); + } else { + r = 1; + bio_list_add(&cell->bios, inmate); + } spin_unlock_irqrestore(&prison->lock, flags); - if (cell2) - mempool_free(cell2, prison->cell_pool); - *ref = cell; - return r; } @@ -284,8 +287,10 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates) hlist_del(&cell->list); - if (inmates) + if (inmates) { + bio_list_add(inmates, cell->holder); bio_list_merge(inmates, &cell->bios); + } mempool_free(cell, prison->cell_pool); } -- 1.7.1 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel