dm bio prison: add dm_cell_promote_or_release()
Rather than always releasing the prisoners in a cell, the client may want to promote one of them to be the new holder. There is a race here though between releasing an empty cell, and other threads adding new inmates. So this function makes the decision with its lock held. This function can have two outcomes: i) An inmate is promoted to be the holder of the cell (return value of 0). ii) The cell has no inmate for promotion and is released (return value of 1). Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
这个提交包含在:
@@ -255,6 +255,32 @@ void dm_cell_visit_release(struct dm_bio_prison *prison,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_cell_visit_release);
|
||||
|
||||
static int __promote_or_release(struct dm_bio_prison *prison,
|
||||
struct dm_bio_prison_cell *cell)
|
||||
{
|
||||
if (bio_list_empty(&cell->bios)) {
|
||||
rb_erase(&cell->node, &prison->cells);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cell->holder = bio_list_pop(&cell->bios);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_cell_promote_or_release(struct dm_bio_prison *prison,
|
||||
struct dm_bio_prison_cell *cell)
|
||||
{
|
||||
int r;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&prison->lock, flags);
|
||||
r = __promote_or_release(prison, cell);
|
||||
spin_unlock_irqrestore(&prison->lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_cell_promote_or_release);
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
#define DEFERRED_SET_SIZE 64
|
||||
|
在新工单中引用
屏蔽一个用户