Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.14-rc3 130 lines 4.1 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) 2011-2017 Red Hat, Inc. 4 * 5 * This file is released under the GPL. 6 */ 7 8#ifndef DM_BIO_PRISON_H 9#define DM_BIO_PRISON_H 10 11#include "persistent-data/dm-block-manager.h" /* FIXME: for dm_block_t */ 12#include "dm-thin-metadata.h" /* FIXME: for dm_thin_id */ 13 14#include <linux/bio.h> 15#include <linux/rbtree.h> 16 17/*----------------------------------------------------------------*/ 18 19/* 20 * Sometimes we can't deal with a bio straight away. We put them in prison 21 * where they can't cause any mischief. Bios are put in a cell identified 22 * by a key, multiple bios can be in the same cell. When the cell is 23 * subsequently unlocked the bios become available. 24 */ 25struct dm_bio_prison; 26 27/* 28 * Keys define a range of blocks within either a virtual or physical 29 * device. 30 */ 31struct dm_cell_key { 32 int virtual; 33 dm_thin_id dev; 34 dm_block_t block_begin, block_end; 35}; 36 37/* 38 * The range of a key (block_end - block_begin) must not 39 * exceed BIO_PRISON_MAX_RANGE. Also the range must not 40 * cross a similarly sized boundary. 41 * 42 * Must be a power of 2. 43 */ 44#define BIO_PRISON_MAX_RANGE 1024 45#define BIO_PRISON_MAX_RANGE_SHIFT 10 46 47/* 48 * Treat this as opaque, only in header so callers can manage allocation 49 * themselves. 50 */ 51struct dm_bio_prison_cell { 52 struct list_head user_list; /* for client use */ 53 struct rb_node node; 54 55 struct dm_cell_key key; 56 struct bio *holder; 57 struct bio_list bios; 58}; 59 60struct dm_bio_prison *dm_bio_prison_create(void); 61void dm_bio_prison_destroy(struct dm_bio_prison *prison); 62 63/* 64 * These two functions just wrap a mempool. This is a transitory step: 65 * Eventually all bio prison clients should manage their own cell memory. 66 * 67 * Like mempool_alloc(), dm_bio_prison_alloc_cell() can only fail if called 68 * in interrupt context or passed GFP_NOWAIT. 69 */ 70struct dm_bio_prison_cell *dm_bio_prison_alloc_cell(struct dm_bio_prison *prison, 71 gfp_t gfp); 72void dm_bio_prison_free_cell(struct dm_bio_prison *prison, 73 struct dm_bio_prison_cell *cell); 74 75/* 76 * Returns false if key is beyond BIO_PRISON_MAX_RANGE or spans a boundary. 77 */ 78bool dm_cell_key_has_valid_range(struct dm_cell_key *key); 79 80/* 81 * An atomic op that combines retrieving or creating a cell, and adding a 82 * bio to it. 83 * 84 * Returns 1 if the cell was already held, 0 if @inmate is the new holder. 85 */ 86int dm_bio_detain(struct dm_bio_prison *prison, 87 struct dm_cell_key *key, 88 struct bio *inmate, 89 struct dm_bio_prison_cell *cell_prealloc, 90 struct dm_bio_prison_cell **cell_result); 91 92void dm_cell_release(struct dm_bio_prison *prison, 93 struct dm_bio_prison_cell *cell, 94 struct bio_list *bios); 95void dm_cell_release_no_holder(struct dm_bio_prison *prison, 96 struct dm_bio_prison_cell *cell, 97 struct bio_list *inmates); 98void dm_cell_error(struct dm_bio_prison *prison, 99 struct dm_bio_prison_cell *cell, blk_status_t error); 100 101/* 102 * Visits the cell and then releases. Guarantees no new inmates are 103 * inserted between the visit and release. 104 */ 105void dm_cell_visit_release(struct dm_bio_prison *prison, 106 void (*visit_fn)(void *, struct dm_bio_prison_cell *), 107 void *context, struct dm_bio_prison_cell *cell); 108 109/*----------------------------------------------------------------*/ 110 111/* 112 * We use the deferred set to keep track of pending reads to shared blocks. 113 * We do this to ensure the new mapping caused by a write isn't performed 114 * until these prior reads have completed. Otherwise the insertion of the 115 * new mapping could free the old block that the read bios are mapped to. 116 */ 117 118struct dm_deferred_set; 119struct dm_deferred_entry; 120 121struct dm_deferred_set *dm_deferred_set_create(void); 122void dm_deferred_set_destroy(struct dm_deferred_set *ds); 123 124struct dm_deferred_entry *dm_deferred_entry_inc(struct dm_deferred_set *ds); 125void dm_deferred_entry_dec(struct dm_deferred_entry *entry, struct list_head *head); 126int dm_deferred_set_add_work(struct dm_deferred_set *ds, struct list_head *work); 127 128/*----------------------------------------------------------------*/ 129 130#endif