^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2011-2017 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is released under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #ifndef DM_BIO_PRISON_V2_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define DM_BIO_PRISON_V2_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "persistent-data/dm-block-manager.h" /* FIXME: for dm_block_t */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "dm-thin-metadata.h" /* FIXME: for dm_thin_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int dm_bio_prison_init_v2(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) void dm_bio_prison_exit_v2(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Sometimes we can't deal with a bio straight away. We put them in prison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * where they can't cause any mischief. Bios are put in a cell identified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * by a key, multiple bios can be in the same cell. When the cell is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * subsequently unlocked the bios become available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct dm_bio_prison_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Keys define a range of blocks within either a virtual or physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct dm_cell_key_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) dm_thin_id dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) dm_block_t block_begin, block_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Treat this as opaque, only in header so callers can manage allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * themselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct dm_bio_prison_cell_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) // FIXME: pack these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) bool exclusive_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned exclusive_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned shared_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct work_struct *quiesce_continuation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct rb_node node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct dm_cell_key_v2 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct bio_list bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct dm_bio_prison_v2 *dm_bio_prison_create_v2(struct workqueue_struct *wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void dm_bio_prison_destroy_v2(struct dm_bio_prison_v2 *prison);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * These two functions just wrap a mempool. This is a transitory step:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Eventually all bio prison clients should manage their own cell memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Like mempool_alloc(), dm_bio_prison_alloc_cell_v2() can only fail if called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * in interrupt context or passed GFP_NOWAIT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct dm_bio_prison_cell_v2 *dm_bio_prison_alloc_cell_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void dm_bio_prison_free_cell_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct dm_bio_prison_cell_v2 *cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Shared locks have a bio associated with them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * If the lock is granted the caller can continue to use the bio, and must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * call dm_cell_put_v2() to drop the reference count when finished using it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * If the lock cannot be granted then the bio will be tracked within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * cell, and later given to the holder of the exclusive lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * See dm_cell_lock_v2() for discussion of the lock_level parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Compare *cell_result with cell_prealloc to see if the prealloc was used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * If cell_prealloc was used then inmate wasn't added to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Returns true if the lock is granted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) bool dm_cell_get_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct dm_cell_key_v2 *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned lock_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct bio *inmate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct dm_bio_prison_cell_v2 *cell_prealloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct dm_bio_prison_cell_v2 **cell_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Decrement the shared reference count for the lock. Returns true if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * returning ownership of the cell (ie. you should free it).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bool dm_cell_put_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct dm_bio_prison_cell_v2 *cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Locks a cell. No associated bio. Exclusive locks get priority. These
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * locks constrain whether the io locks are granted according to level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Shared locks will still be granted if the lock_level is > (not = to) the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * exclusive lock level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * If an _exclusive_ lock is already held then -EBUSY is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Return values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * < 0 - error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * 0 - locked; no quiescing needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * 1 - locked; quiescing needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int dm_cell_lock_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct dm_cell_key_v2 *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned lock_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct dm_bio_prison_cell_v2 *cell_prealloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct dm_bio_prison_cell_v2 **cell_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void dm_cell_quiesce_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct dm_bio_prison_cell_v2 *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct work_struct *continuation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Promotes an _exclusive_ lock to a higher lock level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Return values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * < 0 - error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * 0 - promoted; no quiescing needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * 1 - promoted; quiescing needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int dm_cell_lock_promote_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct dm_bio_prison_cell_v2 *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned new_lock_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Adds any held bios to the bio list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * There may be shared locks still held at this point even if you quiesced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * (ie. different lock levels).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Returns true if returning ownership of the cell (ie. you should free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * it).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) bool dm_cell_unlock_v2(struct dm_bio_prison_v2 *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct dm_bio_prison_cell_v2 *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct bio_list *bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #endif