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