aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-bio-prison.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-bio-prison.h')
-rw-r--r--drivers/md/dm-bio-prison.h58
1 files changed, 49 insertions, 9 deletions
diff --git a/drivers/md/dm-bio-prison.h b/drivers/md/dm-bio-prison.h
index 53d1a7a84e2f..3f833190eadf 100644
--- a/drivers/md/dm-bio-prison.h
+++ b/drivers/md/dm-bio-prison.h
@@ -22,7 +22,6 @@
22 * subsequently unlocked the bios become available. 22 * subsequently unlocked the bios become available.
23 */ 23 */
24struct dm_bio_prison; 24struct dm_bio_prison;
25struct dm_bio_prison_cell;
26 25
27/* FIXME: this needs to be more abstract */ 26/* FIXME: this needs to be more abstract */
28struct dm_cell_key { 27struct dm_cell_key {
@@ -31,21 +30,62 @@ struct dm_cell_key {
31 dm_block_t block; 30 dm_block_t block;
32}; 31};
33 32
33/*
34 * Treat this as opaque, only in header so callers can manage allocation
35 * themselves.
36 */
37struct dm_bio_prison_cell {
38 struct hlist_node list;
39 struct dm_cell_key key;
40 struct bio *holder;
41 struct bio_list bios;
42};
43
34struct dm_bio_prison *dm_bio_prison_create(unsigned nr_cells); 44struct dm_bio_prison *dm_bio_prison_create(unsigned nr_cells);
35void dm_bio_prison_destroy(struct dm_bio_prison *prison); 45void dm_bio_prison_destroy(struct dm_bio_prison *prison);
36 46
37/* 47/*
38 * This may block if a new cell needs allocating. You must ensure that 48 * These two functions just wrap a mempool. This is a transitory step:
39 * cells will be unlocked even if the calling thread is blocked. 49 * Eventually all bio prison clients should manage their own cell memory.
40 * 50 *
41 * Returns 1 if the cell was already held, 0 if @inmate is the new holder. 51 * Like mempool_alloc(), dm_bio_prison_alloc_cell() can only fail if called
52 * in interrupt context or passed GFP_NOWAIT.
42 */ 53 */
43int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key, 54struct dm_bio_prison_cell *dm_bio_prison_alloc_cell(struct dm_bio_prison *prison,
44 struct bio *inmate, struct dm_bio_prison_cell **ref); 55 gfp_t gfp);
56void dm_bio_prison_free_cell(struct dm_bio_prison *prison,
57 struct dm_bio_prison_cell *cell);
45 58
46void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios); 59/*
47void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates); 60 * Creates, or retrieves a cell for the given key.
48void dm_cell_error(struct dm_bio_prison_cell *cell); 61 *
62 * Returns 1 if pre-existing cell returned, zero if new cell created using
63 * @cell_prealloc.
64 */
65int dm_get_cell(struct dm_bio_prison *prison,
66 struct dm_cell_key *key,
67 struct dm_bio_prison_cell *cell_prealloc,
68 struct dm_bio_prison_cell **cell_result);
69
70/*
71 * An atomic op that combines retrieving a cell, and adding a bio to it.
72 *
73 * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
74 */
75int dm_bio_detain(struct dm_bio_prison *prison,
76 struct dm_cell_key *key,
77 struct bio *inmate,
78 struct dm_bio_prison_cell *cell_prealloc,
79 struct dm_bio_prison_cell **cell_result);
80
81void dm_cell_release(struct dm_bio_prison *prison,
82 struct dm_bio_prison_cell *cell,
83 struct bio_list *bios);
84void dm_cell_release_no_holder(struct dm_bio_prison *prison,
85 struct dm_bio_prison_cell *cell,
86 struct bio_list *inmates);
87void dm_cell_error(struct dm_bio_prison *prison,
88 struct dm_bio_prison_cell *cell);
49 89
50/*----------------------------------------------------------------*/ 90/*----------------------------------------------------------------*/
51 91