^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_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define DM_BIO_PRISON_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)
^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) * Sometimes we can't deal with a bio straight away. We put them in prison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * where they can't cause any mischief. Bios are put in a cell identified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * by a key, multiple bios can be in the same cell. When the cell is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * subsequently unlocked the bios become available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct dm_bio_prison;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Keys define a range of blocks within either a virtual or physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct dm_cell_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) dm_thin_id dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) dm_block_t block_begin, block_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Treat this as opaque, only in header so callers can manage allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * themselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct dm_bio_prison_cell {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct list_head user_list; /* for client use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct rb_node node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct dm_cell_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct bio *holder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct bio_list bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct dm_bio_prison *dm_bio_prison_create(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void dm_bio_prison_destroy(struct dm_bio_prison *prison);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * These two functions just wrap a mempool. This is a transitory step:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Eventually all bio prison clients should manage their own cell memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Like mempool_alloc(), dm_bio_prison_alloc_cell() can only fail if called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * in interrupt context or passed GFP_NOWAIT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct dm_bio_prison_cell *dm_bio_prison_alloc_cell(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) void dm_bio_prison_free_cell(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct dm_bio_prison_cell *cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Creates, or retrieves a cell that overlaps the given key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Returns 1 if pre-existing cell returned, zero if new cell created using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @cell_prealloc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int dm_get_cell(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct dm_cell_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct dm_bio_prison_cell *cell_prealloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct dm_bio_prison_cell **cell_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * An atomic op that combines retrieving or creating a cell, and adding a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * bio to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int dm_bio_detain(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct dm_cell_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct bio *inmate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct dm_bio_prison_cell *cell_prealloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct dm_bio_prison_cell **cell_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void dm_cell_release(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct dm_bio_prison_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct bio_list *bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) void dm_cell_release_no_holder(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct dm_bio_prison_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct bio_list *inmates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) void dm_cell_error(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct dm_bio_prison_cell *cell, blk_status_t error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Visits the cell and then releases. Guarantees no new inmates are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * inserted between the visit and release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void dm_cell_visit_release(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void (*visit_fn)(void *, struct dm_bio_prison_cell *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) void *context, struct dm_bio_prison_cell *cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Rather than always releasing the prisoners in a cell, the client may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * want to promote one of them to be the new holder. There is a race here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * though between releasing an empty cell, and other threads adding new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * inmates. So this function makes the decision with its lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * This function can have two outcomes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * i) An inmate is promoted to be the holder of the cell (return value of 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * ii) The cell has no inmate for promotion and is released (return value of 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int dm_cell_promote_or_release(struct dm_bio_prison *prison,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct dm_bio_prison_cell *cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * We use the deferred set to keep track of pending reads to shared blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * We do this to ensure the new mapping caused by a write isn't performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * until these prior reads have completed. Otherwise the insertion of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * new mapping could free the old block that the read bios are mapped to.
^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) struct dm_deferred_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct dm_deferred_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct dm_deferred_set *dm_deferred_set_create(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void dm_deferred_set_destroy(struct dm_deferred_set *ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct dm_deferred_entry *dm_deferred_entry_inc(struct dm_deferred_set *ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) void dm_deferred_entry_dec(struct dm_deferred_entry *entry, struct list_head *head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int dm_deferred_set_add_work(struct dm_deferred_set *ds, struct list_head *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^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) #endif