Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2011-2017 Red Hat, Inc.
0003  *
0004  * This file is released under the GPL.
0005  */
0006 
0007 #ifndef DM_BIO_PRISON_H
0008 #define DM_BIO_PRISON_H
0009 
0010 #include "persistent-data/dm-block-manager.h" /* FIXME: for dm_block_t */
0011 #include "dm-thin-metadata.h" /* FIXME: for dm_thin_id */
0012 
0013 #include <linux/bio.h>
0014 #include <linux/rbtree.h>
0015 
0016 /*----------------------------------------------------------------*/
0017 
0018 /*
0019  * Sometimes we can't deal with a bio straight away.  We put them in prison
0020  * where they can't cause any mischief.  Bios are put in a cell identified
0021  * by a key, multiple bios can be in the same cell.  When the cell is
0022  * subsequently unlocked the bios become available.
0023  */
0024 struct dm_bio_prison;
0025 
0026 /*
0027  * Keys define a range of blocks within either a virtual or physical
0028  * device.
0029  */
0030 struct dm_cell_key {
0031     int virtual;
0032     dm_thin_id dev;
0033     dm_block_t block_begin, block_end;
0034 };
0035 
0036 /*
0037  * Treat this as opaque, only in header so callers can manage allocation
0038  * themselves.
0039  */
0040 struct dm_bio_prison_cell {
0041     struct list_head user_list; /* for client use */
0042     struct rb_node node;
0043 
0044     struct dm_cell_key key;
0045     struct bio *holder;
0046     struct bio_list bios;
0047 };
0048 
0049 struct dm_bio_prison *dm_bio_prison_create(void);
0050 void dm_bio_prison_destroy(struct dm_bio_prison *prison);
0051 
0052 /*
0053  * These two functions just wrap a mempool.  This is a transitory step:
0054  * Eventually all bio prison clients should manage their own cell memory.
0055  *
0056  * Like mempool_alloc(), dm_bio_prison_alloc_cell() can only fail if called
0057  * in interrupt context or passed GFP_NOWAIT.
0058  */
0059 struct dm_bio_prison_cell *dm_bio_prison_alloc_cell(struct dm_bio_prison *prison,
0060                             gfp_t gfp);
0061 void dm_bio_prison_free_cell(struct dm_bio_prison *prison,
0062                  struct dm_bio_prison_cell *cell);
0063 
0064 /*
0065  * Creates, or retrieves a cell that overlaps the given key.
0066  *
0067  * Returns 1 if pre-existing cell returned, zero if new cell created using
0068  * @cell_prealloc.
0069  */
0070 int dm_get_cell(struct dm_bio_prison *prison,
0071         struct dm_cell_key *key,
0072         struct dm_bio_prison_cell *cell_prealloc,
0073         struct dm_bio_prison_cell **cell_result);
0074 
0075 /*
0076  * An atomic op that combines retrieving or creating a cell, and adding a
0077  * bio to it.
0078  *
0079  * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
0080  */
0081 int dm_bio_detain(struct dm_bio_prison *prison,
0082           struct dm_cell_key *key,
0083           struct bio *inmate,
0084           struct dm_bio_prison_cell *cell_prealloc,
0085           struct dm_bio_prison_cell **cell_result);
0086 
0087 void dm_cell_release(struct dm_bio_prison *prison,
0088              struct dm_bio_prison_cell *cell,
0089              struct bio_list *bios);
0090 void dm_cell_release_no_holder(struct dm_bio_prison *prison,
0091                    struct dm_bio_prison_cell *cell,
0092                    struct bio_list *inmates);
0093 void dm_cell_error(struct dm_bio_prison *prison,
0094            struct dm_bio_prison_cell *cell, blk_status_t error);
0095 
0096 /*
0097  * Visits the cell and then releases.  Guarantees no new inmates are
0098  * inserted between the visit and release.
0099  */
0100 void dm_cell_visit_release(struct dm_bio_prison *prison,
0101                void (*visit_fn)(void *, struct dm_bio_prison_cell *),
0102                void *context, struct dm_bio_prison_cell *cell);
0103 
0104 /*
0105  * Rather than always releasing the prisoners in a cell, the client may
0106  * want to promote one of them to be the new holder.  There is a race here
0107  * though between releasing an empty cell, and other threads adding new
0108  * inmates.  So this function makes the decision with its lock held.
0109  *
0110  * This function can have two outcomes:
0111  * i) An inmate is promoted to be the holder of the cell (return value of 0).
0112  * ii) The cell has no inmate for promotion and is released (return value of 1).
0113  */
0114 int dm_cell_promote_or_release(struct dm_bio_prison *prison,
0115                    struct dm_bio_prison_cell *cell);
0116 
0117 /*----------------------------------------------------------------*/
0118 
0119 /*
0120  * We use the deferred set to keep track of pending reads to shared blocks.
0121  * We do this to ensure the new mapping caused by a write isn't performed
0122  * until these prior reads have completed.  Otherwise the insertion of the
0123  * new mapping could free the old block that the read bios are mapped to.
0124  */
0125 
0126 struct dm_deferred_set;
0127 struct dm_deferred_entry;
0128 
0129 struct dm_deferred_set *dm_deferred_set_create(void);
0130 void dm_deferred_set_destroy(struct dm_deferred_set *ds);
0131 
0132 struct dm_deferred_entry *dm_deferred_entry_inc(struct dm_deferred_set *ds);
0133 void dm_deferred_entry_dec(struct dm_deferred_entry *entry, struct list_head *head);
0134 int dm_deferred_set_add_work(struct dm_deferred_set *ds, struct list_head *work);
0135 
0136 /*----------------------------------------------------------------*/
0137 
0138 #endif