Lines Matching +full:1 +full:- +full:cell

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012-2017 Red Hat, Inc.
9 #include "dm-bio-prison-v2.h"
17 /*----------------------------------------------------------------*/
31 /*----------------------------------------------------------------*/
45 prison->wq = wq; in dm_bio_prison_create_v2()
46 spin_lock_init(&prison->lock); in dm_bio_prison_create_v2()
48 ret = mempool_init_slab_pool(&prison->cell_pool, MIN_CELLS, _cell_cache); in dm_bio_prison_create_v2()
54 prison->cells = RB_ROOT; in dm_bio_prison_create_v2()
62 mempool_exit(&prison->cell_pool); in dm_bio_prison_destroy_v2()
69 return mempool_alloc(&prison->cell_pool, gfp); in dm_bio_prison_alloc_cell_v2()
74 struct dm_bio_prison_cell_v2 *cell) in dm_bio_prison_free_cell_v2() argument
76 mempool_free(cell, &prison->cell_pool); in dm_bio_prison_free_cell_v2()
81 struct dm_bio_prison_cell_v2 *cell) in __setup_new_cell() argument
83 memset(cell, 0, sizeof(*cell)); in __setup_new_cell()
84 memcpy(&cell->key, key, sizeof(cell->key)); in __setup_new_cell()
85 bio_list_init(&cell->bios); in __setup_new_cell()
91 if (lhs->virtual < rhs->virtual) in cmp_keys()
92 return -1; in cmp_keys()
94 if (lhs->virtual > rhs->virtual) in cmp_keys()
95 return 1; in cmp_keys()
97 if (lhs->dev < rhs->dev) in cmp_keys()
98 return -1; in cmp_keys()
100 if (lhs->dev > rhs->dev) in cmp_keys()
101 return 1; in cmp_keys()
103 if (lhs->block_end <= rhs->block_begin) in cmp_keys()
104 return -1; in cmp_keys()
106 if (lhs->block_begin >= rhs->block_end) in cmp_keys()
107 return 1; in cmp_keys()
121 struct rb_node **new = &prison->cells.rb_node, *parent = NULL; in __find_or_insert()
124 struct dm_bio_prison_cell_v2 *cell = in __find_or_insert() local
127 r = cmp_keys(key, &cell->key); in __find_or_insert()
131 new = &((*new)->rb_left); in __find_or_insert()
134 new = &((*new)->rb_right); in __find_or_insert()
137 *result = cell; in __find_or_insert()
144 rb_link_node(&cell_prealloc->node, parent, new); in __find_or_insert()
145 rb_insert_color(&cell_prealloc->node, &prison->cells); in __find_or_insert()
155 struct dm_bio_prison_cell_v2 **cell) in __get() argument
157 if (__find_or_insert(prison, key, cell_prealloc, cell)) { in __get()
158 if ((*cell)->exclusive_lock) { in __get()
159 if (lock_level <= (*cell)->exclusive_level) { in __get()
160 bio_list_add(&(*cell)->bios, inmate); in __get()
165 (*cell)->shared_count++; in __get()
168 (*cell)->shared_count = 1; in __get()
182 spin_lock_irq(&prison->lock); in dm_cell_get_v2()
184 spin_unlock_irq(&prison->lock); in dm_cell_get_v2()
191 struct dm_bio_prison_cell_v2 *cell) in __put() argument
193 BUG_ON(!cell->shared_count); in __put()
194 cell->shared_count--; in __put()
197 if (!cell->shared_count) { in __put()
198 if (cell->exclusive_lock) { in __put()
199 if (cell->quiesce_continuation) { in __put()
200 queue_work(prison->wq, cell->quiesce_continuation); in __put()
201 cell->quiesce_continuation = NULL; in __put()
204 rb_erase(&cell->node, &prison->cells); in __put()
213 struct dm_bio_prison_cell_v2 *cell) in dm_cell_put_v2() argument
218 spin_lock_irqsave(&prison->lock, flags); in dm_cell_put_v2()
219 r = __put(prison, cell); in dm_cell_put_v2()
220 spin_unlock_irqrestore(&prison->lock, flags); in dm_cell_put_v2()
232 struct dm_bio_prison_cell_v2 *cell; in __lock() local
234 if (__find_or_insert(prison, key, cell_prealloc, &cell)) { in __lock()
235 if (cell->exclusive_lock) in __lock()
236 return -EBUSY; in __lock()
238 cell->exclusive_lock = true; in __lock()
239 cell->exclusive_level = lock_level; in __lock()
240 *cell_result = cell; in __lock()
244 return cell->shared_count > 0; in __lock()
247 cell = cell_prealloc; in __lock()
248 cell->shared_count = 0; in __lock()
249 cell->exclusive_lock = true; in __lock()
250 cell->exclusive_level = lock_level; in __lock()
251 *cell_result = cell; in __lock()
265 spin_lock_irq(&prison->lock); in dm_cell_lock_v2()
267 spin_unlock_irq(&prison->lock); in dm_cell_lock_v2()
274 struct dm_bio_prison_cell_v2 *cell, in __quiesce() argument
277 if (!cell->shared_count) in __quiesce()
278 queue_work(prison->wq, continuation); in __quiesce()
280 cell->quiesce_continuation = continuation; in __quiesce()
284 struct dm_bio_prison_cell_v2 *cell, in dm_cell_quiesce_v2() argument
287 spin_lock_irq(&prison->lock); in dm_cell_quiesce_v2()
288 __quiesce(prison, cell, continuation); in dm_cell_quiesce_v2()
289 spin_unlock_irq(&prison->lock); in dm_cell_quiesce_v2()
294 struct dm_bio_prison_cell_v2 *cell, in __promote() argument
297 if (!cell->exclusive_lock) in __promote()
298 return -EINVAL; in __promote()
300 cell->exclusive_level = new_lock_level; in __promote()
301 return cell->shared_count > 0; in __promote()
305 struct dm_bio_prison_cell_v2 *cell, in dm_cell_lock_promote_v2() argument
310 spin_lock_irq(&prison->lock); in dm_cell_lock_promote_v2()
311 r = __promote(prison, cell, new_lock_level); in dm_cell_lock_promote_v2()
312 spin_unlock_irq(&prison->lock); in dm_cell_lock_promote_v2()
319 struct dm_bio_prison_cell_v2 *cell, in __unlock() argument
322 BUG_ON(!cell->exclusive_lock); in __unlock()
324 bio_list_merge_init(bios, &cell->bios); in __unlock()
326 if (cell->shared_count) { in __unlock()
327 cell->exclusive_lock = false; in __unlock()
331 rb_erase(&cell->node, &prison->cells); in __unlock()
336 struct dm_bio_prison_cell_v2 *cell, in dm_cell_unlock_v2() argument
341 spin_lock_irq(&prison->lock); in dm_cell_unlock_v2()
342 r = __unlock(prison, cell, bios); in dm_cell_unlock_v2()
343 spin_unlock_irq(&prison->lock); in dm_cell_unlock_v2()
349 /*----------------------------------------------------------------*/
355 return -ENOMEM; in dm_bio_prison_init_v2()