1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

o split struct mapped_device into mapped_device and dm_table

o seperated loading of a table from binding a table to the device

These should allow multiple tables to be managed by dm-fs
This commit is contained in:
Joe Thornber 2001-08-31 15:13:33 +00:00
parent 4183d3fe6c
commit 0f29dc2f2d
6 changed files with 321 additions and 199 deletions

View File

@ -35,11 +35,11 @@
/* FIXME: Use value from local range for now, for co-existence with LVM 1 */
#define DM_BLK_MAJOR 124
struct mapped_device;
struct dm_table;
typedef unsigned int offset_t;
/* constructor, destructor and map fn types */
typedef int (*dm_ctr_fn)(offset_t b, offset_t e, struct mapped_device *md,
typedef int (*dm_ctr_fn)(offset_t b, offset_t e, struct dm_table *t,
const char *cb, const char *ce, void **result);
typedef void (*dm_dtr_fn)(void *c);
typedef int (*dm_map_fn)(struct buffer_head *bh, void *context);
@ -47,9 +47,12 @@ typedef int (*dm_map_fn)(struct buffer_head *bh, void *context);
int register_map_target(const char *name, dm_ctr_fn ctr, dm_dtr_fn dtr,
dm_map_fn map);
/* contructors should call this to make sure any destination devices
are handled correctly (ie. opened/closed) */
int dm_add_device(struct mapped_device *md, kdev_t dev);
/* contructors should call this to make sure any
* destination devices are handled correctly
* (ie. opened/closed).
*/
int dm_table_add_device(struct dm_table *t, kdev_t dev);
#endif
#endif

View File

@ -49,21 +49,25 @@ static struct proc_dir_entry *_control;
static devfs_handle_t _dev_dir;
static int process_control(const char *b, const char *e, int minor,
struct dm_table **map);
static int process_table(const char *b, const char *e, int minor,
struct dm_table **map);
static int line_splitter(struct file *file, const char *buffer,
unsigned long count, void *data);
static int process_control(const char *b, const char *e, int minor);
static int process_table(const char *b, const char *e, int minor);
static int get_word(const char *b, const char *e,
const char **wb, const char **we);
static int tok_cmp(const char *str, const char *b, const char *e);
static void tok_cpy(char *dest, size_t max,
const char *b, const char *e);
typedef int (*process_fn)(const char *b, const char *e, int minor);
typedef int (*process_fn)(const char *b, const char *e, int minor,
struct dm_table **map);
struct pf_data {
process_fn fn;
int minor;
struct dm_table *map;
};
int dm_fs_init(void)
@ -119,6 +123,7 @@ int dm_fs_add(struct mapped_device *md)
pfd->fn = process_table;
pfd->minor = MINOR(md->dev);
pfd->map = 0;
if (!(md->pde = create_proc_entry(md->name, S_IRUGO | S_IWUSR,
_proc_dir))) {
@ -148,6 +153,11 @@ int dm_fs_add(struct mapped_device *md)
int dm_fs_remove(struct mapped_device *md)
{
if (md->pde) {
struct pf_data *pfd = (struct pf_data *) md->pde->data;
if (pfd->map)
dm_table_destroy(pfd->map);
kfree(md->pde->data);
remove_proc_entry(md->name, _proc_dir);
md->pde = 0;
@ -158,7 +168,8 @@ int dm_fs_remove(struct mapped_device *md)
return 0;
}
static int process_control(const char *b, const char *e, int minor)
static int process_control(const char *b, const char *e, int minor,
struct dm_table **map)
{
const char *wb, *we;
char name[64];
@ -201,10 +212,12 @@ static int process_control(const char *b, const char *e, int minor)
return -EINVAL;
}
static int process_table(const char *b, const char *e, int minor)
static int process_table(const char *b, const char *e, int minor,
struct dm_table **map)
{
const char *wb, *we;
struct mapped_device *md = dm_find_by_minor(minor);
struct dm_table *table = *map;
void *context;
int r;
@ -219,12 +232,15 @@ static int process_table(const char *b, const char *e, int minor)
dm_suspend(md);
/* start loading a table */
dm_table_start(md);
table = *map = dm_table_create();
} else if (!tok_cmp("end", b, e)) {
/* activate the device ... <evil chuckle> ... */
dm_table_complete(md);
if (table) {
dm_table_complete(table);
dm_bind(md, table);
dm_activate(md);
}
} else {
/* add the new entry */
@ -253,18 +269,18 @@ static int process_table(const char *b, const char *e, int minor)
return -EINVAL;
/* check there isn't a gap */
if ((md->num_targets &&
start != md->highs[md->num_targets - 1] + 1) ||
(!md->num_targets && start)) {
if ((table->num_targets &&
start != table->highs[table->num_targets - 1] + 1) ||
(!table->num_targets && start)) {
WARN("gap in target ranges");
return -EINVAL;
}
high = start + (size - 1);
if ((r = t->ctr(start, high, md, we, e, &context)))
if ((r = t->ctr(start, high, table, we, e, &context)))
return r;
if ((r = dm_table_add_entry(md, high, t->map, context)))
if ((r = dm_table_add_entry(table, high, t->map, context)))
return r;
}
@ -302,7 +318,7 @@ static int line_splitter(struct file *file, const char *buffer,
while((b != e) && *b != '\n')
b++;
if ((r = pfd->fn(lb, b, pfd->minor)))
if ((r = pfd->fn(lb, b, pfd->minor, &pfd->map)))
return r;
}

View File

@ -41,7 +41,7 @@ static inline ulong div_up(ulong n, ulong size)
}
/* ceiling(log_size(n)) */
static uint int_log(ulong base, ulong n)
static uint int_log(ulong n, ulong base)
{
int result = 0;
@ -57,14 +57,14 @@ static uint int_log(ulong base, ulong n)
* return the highest key that you could lookup
* from the n'th node on level l of the btree.
*/
static offset_t high(struct mapped_device *md, int l, int n)
static offset_t high(struct dm_table *t, int l, int n)
{
while (1) {
if (n >= md->counts[l])
if (n >= t->counts[l])
return (offset_t) -1;
if (l == md->depth - 1)
return md->index[l][((n + 1) * KEYS_PER_NODE) - 1];
if (l == t->depth - 1)
return t->index[l][((n + 1) * KEYS_PER_NODE) - 1];
l++;
n = (n + 1) * (KEYS_PER_NODE + 1) - 1;
@ -77,15 +77,15 @@ static offset_t high(struct mapped_device *md, int l, int n)
* fills in a level of the btree based on the
* highs of the level below it.
*/
static int setup_btree_index(int l, struct mapped_device *md)
static int setup_btree_index(int l, struct dm_table *t)
{
int n, c, cn;
for (n = 0, cn = 0; n < md->counts[l]; n++) {
offset_t *k = md->index[l] + (n * KEYS_PER_NODE);
for (n = 0, cn = 0; n < t->counts[l]; n++) {
offset_t *k = t->index[l] + (n * KEYS_PER_NODE);
for (c = 0; c < KEYS_PER_NODE; c++)
k[c] = high(md, l + 1, cn++);
k[c] = high(t, l + 1, cn++);
cn++; /* one extra for the child that's
greater than all keys */
}
@ -93,31 +93,15 @@ static int setup_btree_index(int l, struct mapped_device *md)
return 0;
}
void dm_table_free(struct mapped_device *md)
{
int i;
for (i = 0; i < md->depth; i++) {
vfree(md->index[i]);
md->index[i] = 0;
}
vfree(md->targets);
md->highs = 0;
md->targets = 0;
md->num_targets = 0;
md->num_allocated = 0;
}
/*
* md->highs, and md->targets are managed as
* dynamic arrays during a table load.
* highs, and targets are managed as dynamic
* arrays during a table load.
*/
static int alloc_targets(struct mapped_device *md, int num)
static int alloc_targets(struct dm_table *t, int num)
{
offset_t *n_highs;
struct target *n_targets;
int n = t->num_targets;
if (!(n_highs = vmalloc(sizeof(*n_highs) * num)))
return -ENOMEM;
@ -127,93 +111,143 @@ static int alloc_targets(struct mapped_device *md, int num)
return -ENOMEM;
}
if (md->num_targets) {
memcpy(n_highs, md->highs,
sizeof(*n_highs) * md->num_targets);
memcpy(n_targets, md->targets,
sizeof(*n_targets) * md->num_targets);
if (n) {
memcpy(n_highs, t->highs, sizeof(*n_highs) * n);
memcpy(n_targets, t->targets, sizeof(*n_targets) * n);
}
vfree(md->highs);
vfree(md->targets);
vfree(t->highs);
vfree(t->targets);
md->num_allocated = num;
md->highs = n_highs;
md->targets = n_targets;
t->num_allocated = num;
t->highs = n_highs;
t->targets = n_targets;
return 0;
}
int dm_table_start(struct mapped_device *md)
struct dm_table *dm_table_create(void)
{
int r;
set_bit(DM_LOADING, &md->state);
struct dm_table *t = kmalloc(sizeof(struct dm_table), GFP_NOIO);
dm_table_free(md);
if (!t)
return 0;
/* allocate a single nodes worth to start with */
if ((r = alloc_targets(md, KEYS_PER_NODE)))
memset(t, 0, sizeof(*t));
/* allocate a single nodes worth of targets to
begin with */
if (t && alloc_targets(t, KEYS_PER_NODE)) {
kfree(t);
t = 0;
}
return t;
}
void dm_table_destroy(struct dm_table *t)
{
struct dev_list *d, *n;
int i;
if (!t)
return;
/* free the indexes */
for (i = 0; i < t->depth; i++) {
vfree(t->index[i]);
t->index[i] = 0;
}
/* t->highs was already freed as t->index[t->depth - 1] */
vfree(t->targets);
kfree(t);
/* free the device list */
for (d = t->devices; d; d = n) {
n = d->next;
kfree(d);
}
}
/*
* checks to see if we need to extend highs or targets
*/
static inline int check_space(struct dm_table *t)
{
if (t->num_targets >= t->num_allocated)
return alloc_targets(t, t->num_allocated * 2);
return 0;
}
/*
* adds a target to the map
*/
int dm_table_add_entry(struct dm_table *t, offset_t high,
dm_map_fn target, void *private)
{
int r, n;
if ((r = check_space(t)))
return r;
n = t->num_targets++;
t->highs[n] = high;
t->targets[n].map = target;
t->targets[n].private = private;
return 0;
}
static inline int check_space(struct mapped_device *md)
int dm_table_add_device(struct dm_table *t, kdev_t dev)
{
if (md->num_targets >= md->num_allocated)
return alloc_targets(md, md->num_allocated * 2);
struct dev_list *d = kmalloc(sizeof(*d), GFP_KERNEL);
if (!d)
return -ENOMEM;
d->dev = dev;
d->next = t->devices;
t->devices = d;
return 0;
}
int dm_table_add_entry(struct mapped_device *md, offset_t high,
dm_map_fn target, void *context)
{
int r;
if ((r = check_space(md)))
return r;
md->highs[md->num_targets] = high;
md->targets[md->num_targets].map = target;
md->targets[md->num_targets].private = context;
md->num_targets++;
return 0;
}
int dm_table_complete(struct mapped_device *md)
/*
* builds the btree to index the map
*/
int dm_table_complete(struct dm_table *t)
{
int i, leaf_nodes;
clear_bit(DM_LOADING, &md->state);
/* how many indexes will the btree have ? */
leaf_nodes = div_up(md->num_targets, KEYS_PER_NODE);
leaf_nodes = div_up(t->num_targets, KEYS_PER_NODE);
i = 1 + int_log(leaf_nodes, KEYS_PER_NODE + 1);
md->depth = i;
md->counts[md->depth - 1] = div_up(md->num_targets, KEYS_PER_NODE);
/* work out how many nodes are in each layer */
t->depth = i;
t->counts[t->depth - 1] = div_up(t->num_targets, KEYS_PER_NODE);
while (--i)
md->counts[i - 1] = div_up(md->counts[i], KEYS_PER_NODE + 1);
t->counts[i - 1] = div_up(t->counts[i], KEYS_PER_NODE + 1);
for (i = 0; i < (md->depth - 1); i++) {
size_t s = NODE_SIZE * md->counts[i];
md->index[i] = vmalloc(s);
memset(md->index[i], -1, s);
/* allocate memory for the internal nodes */
for (i = 0; i < (t->depth - 1); i++) {
size_t s = NODE_SIZE * t->counts[i];
t->index[i] = vmalloc(s);
memset(t->index[i], -1, s);
}
/* bottom layer is easy */
md->index[md->depth - 1] = md->highs;
/* leaf layer has already been set up */
t->index[t->depth - 1] = t->highs;
/* fill in higher levels */
for (i = md->depth - 1; i; i--)
setup_btree_index(i - 1, md);
for (i = t->depth - 1; i; i--)
setup_btree_index(i - 1, t);
set_bit(DM_LOADED, &md->state);
return 0;
}
EXPORT_SYMBOL(dm_table_add_device);

View File

@ -47,6 +47,9 @@ struct target_type *dm_get_target(const char *name)
return t;
}
/*
* register a new target_type.
*/
int register_map_target(const char *name, dm_ctr_fn ctr,
dm_dtr_fn dtr, dm_map_fn map)
{
@ -82,7 +85,7 @@ int register_map_target(const char *name, dm_ctr_fn ctr,
* io-err: always fails an io, useful for bringing
* up LV's that have holes in them.
*/
static int io_err_ctr(offset_t b, offset_t e, struct mapped_device *md,
static int io_err_ctr(offset_t b, offset_t e, struct dm_table *t,
const char *cb, const char *ce, void **result)
{
/* this takes no arguments */
@ -109,11 +112,13 @@ struct linear_c {
int offset; /* FIXME: we need a signed offset type */
};
static int linear_ctr(offset_t low, offset_t high, struct mapped_device *md,
/*
* construct a linear mapping.
* <major> <minor> <offset>
*/
static int linear_ctr(offset_t low, offset_t high, struct dm_table *t,
const char *cb, const char *ce, void **result)
{
/* <major> <minor> <offset> */
struct linear_c *lc;
unsigned int major, minor, start;
int r;
@ -135,7 +140,7 @@ static int linear_ctr(offset_t low, offset_t high, struct mapped_device *md,
lc->dev = MKDEV((int) major, (int) minor);
lc->offset = (int) start - (int) low;
if ((r = dm_add_device(md, lc->dev))) {
if ((r = dm_table_add_device(t, lc->dev))) {
kfree(lc);
return r;
}

View File

@ -63,23 +63,12 @@ static int _block_size[MAX_DEVICES];
static int _blksize_size[MAX_DEVICES];
static int _hardsect_size[MAX_DEVICES];
static int blk_open(struct inode *inode, struct file *file);
static int blk_close(struct inode *inode, struct file *file);
static int blk_ioctl(struct inode *inode, struct file *file,
uint command, ulong a);
struct block_device_operations dm_blk_dops = {
open: blk_open,
release: blk_close,
ioctl: blk_ioctl
};
static int request(request_queue_t *q, int rw, struct buffer_head *bh);
/*
* setup and teardown the driver
*/
static int init_dm(void)
static int dm_init(void)
{
int ret;
@ -112,7 +101,7 @@ static int init_dm(void)
return 0;
}
static void exit_dm(void)
static void dm_exit(void)
{
if(kmem_cache_shrink(_io_hook_cache))
WARN("it looks like there are still some io_hooks allocated");
@ -252,6 +241,11 @@ inline static void free_deferred(struct deferred_io *di)
kfree(di);
}
/*
* bh->b_end_io routine that decrements the
* pending count and then calls the original
* bh->b_end_io fn.
*/
static void dec_pending(struct buffer_head *bh, int uptodate)
{
struct io_hook *ih = bh->b_private;
@ -267,6 +261,9 @@ static void dec_pending(struct buffer_head *bh, int uptodate)
bh->b_end_io(bh, uptodate);
}
/*
* add the bh to the list of deferred io.
*/
static int queue_io(struct mapped_device *md, struct buffer_head *bh, int rw)
{
struct deferred_io *di = alloc_deferred();
@ -289,15 +286,17 @@ static int queue_io(struct mapped_device *md, struct buffer_head *bh, int rw)
return 1;
}
/*
* do the bh mapping for a given leaf
*/
inline static int __map_buffer(struct mapped_device *md,
struct buffer_head *bh, int node)
struct buffer_head *bh, int leaf)
{
dm_map_fn fn;
void *context;
struct io_hook *ih = 0;
int r;
struct target *ti = md->targets + node;
struct target *ti = md->map->targets + leaf;
fn = ti->map;
context = ti->private;
@ -334,15 +333,17 @@ inline static int __map_buffer(struct mapped_device *md,
return 1;
}
inline static int __find_node(struct mapped_device *md, struct buffer_head *bh)
/*
* search the btree for the correct target.
*/
inline static int __find_node(struct dm_table *t, struct buffer_head *bh)
{
int i = 0, l, r = 0;
offset_t *node;
/* search the btree for the correct target */
for (l = 0; l < md->depth; l++) {
for (l = 0; l < t->depth; l++) {
r = ((KEYS_PER_NODE + 1) * r) + i;
node = md->index[l] + (r * KEYS_PER_NODE);
node = t->index[l] + (r * KEYS_PER_NODE);
for (i = 0; i < KEYS_PER_NODE; i++)
if (node[i] >= bh->b_rsector)
@ -363,7 +364,7 @@ static int request(request_queue_t *q, int rw, struct buffer_head *bh)
rl;
md = _devs[minor];
if (!md || !test_bit(DM_LOADED, &md->state))
if (!md || !md->map)
goto bad;
/* if we're suspended we have to queue this io for later */
@ -380,7 +381,7 @@ static int request(request_queue_t *q, int rw, struct buffer_head *bh)
rl; /* FIXME: there's still a race here */
}
if (!__map_buffer(md, bh, __find_node(md, bh)))
if (!__map_buffer(md, bh, __find_node(md->map, bh)))
goto bad;
ru;
@ -394,6 +395,10 @@ static int request(request_queue_t *q, int rw, struct buffer_head *bh)
return 0;
}
/*
* see if the device with a specific minor # is
* free.
*/
static inline int __specific_dev(int minor)
{
if (minor > MAX_DEVICES) {
@ -407,6 +412,9 @@ static inline int __specific_dev(int minor)
return -1;
}
/*
* find the first free device.
*/
static inline int __any_old_dev(void)
{
int i;
@ -418,6 +426,9 @@ static inline int __any_old_dev(void)
return -1;
}
/*
* allocate and initialise a blank device.
*/
static struct mapped_device *alloc_dev(int minor)
{
struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL);
@ -445,16 +456,10 @@ static struct mapped_device *alloc_dev(int minor)
return md;
}
static inline struct mapped_device *__find_by_name(const char *name)
{
int i;
for (i = 0; i < MAX_DEVICES; i++)
if (_devs[i] && !strcmp(_devs[i]->name, name))
return _devs[i];
return 0;
}
/*
* open a device so we can use it as a map
* destination.
*/
static int open_dev(struct dev_list *d)
{
int err;
@ -470,6 +475,9 @@ static int open_dev(struct dev_list *d)
return 0;
}
/*
* close a device that we've been using.
*/
static void close_dev(struct dev_list *d)
{
blkdev_put(d->bd, BDEV_FILE);
@ -477,18 +485,14 @@ static void close_dev(struct dev_list *d)
d->bd = 0;
}
static int __find_hardsect_size(struct mapped_device *md)
static inline struct mapped_device *__find_by_name(const char *name)
{
int r = INT_MAX, s;
struct dev_list *dl;
int i;
for (i = 0; i < MAX_DEVICES; i++)
if (_devs[i] && !strcmp(_devs[i]->name, name))
return _devs[i];
for (dl = md->devices; dl; dl = dl->next) {
s = get_hardsect_size(dl->dev);
if (s < r)
r = s;
}
return r;
return 0;
}
struct mapped_device *dm_find_by_name(const char *name)
@ -513,6 +517,9 @@ struct mapped_device *dm_find_by_minor(int minor)
return md;
}
/*
* constructor for a new device
*/
int dm_create(const char *name, int minor)
{
int r;
@ -544,10 +551,14 @@ int dm_create(const char *name, int minor)
return 0;
}
/*
* destructor for the device. md->map is
* deliberately not destroyed, dm-fs should manage
* table objects.
*/
int dm_remove(const char *name)
{
struct mapped_device *md;
struct dev_list *d, *n;
int minor, r;
wl;
@ -566,12 +577,6 @@ int dm_remove(const char *name)
return r;
}
dm_table_free(md);
for (d = md->devices; d; d = n) {
n = d->next;
kfree(d);
}
minor = MINOR(md->dev);
kfree(md);
_devs[minor] = 0;
@ -580,20 +585,57 @@ int dm_remove(const char *name)
return 0;
}
int dm_add_device(struct mapped_device *md, kdev_t dev)
/*
* the hardsect size for a mapped device is the
* smallest hard sect size from the devices it
* maps onto.
*/
static int __find_hardsect_size(struct dev_list *dl)
{
struct dev_list *d = kmalloc(sizeof(*d), GFP_KERNEL);
int result = INT_MAX, size;
if (!d)
return -EINVAL;
while(dl) {
size = get_hardsect_size(dl->dev);
if (size < result)
result = size;
dl = dl->next;
}
d->dev = dev;
d->next = md->devices;
md->devices = d;
return result;
}
/*
* bind a table to the device, the device must not
* be active, though it could have another table
* aready bound.
*/
int dm_bind(struct mapped_device *md, struct dm_table *t)
{
int minor = MINOR(md->dev);
wl;
if (is_active(md)) {
wu;
return -EPERM;
}
md->map = t;
_block_size[minor] = (t->highs[t->num_targets - 1] + 1) >> 1;
/* FIXME: block size depends on the mapping table */
_blksize_size[minor] = BLOCK_SIZE;
_hardsect_size[minor] = __find_hardsect_size(t->devices);
register_disk(NULL, md->dev, 1, &dm_blk_dops, _block_size[minor]);
wu;
return 0;
}
/*
* requeue the deferred buffer_heads by calling
* generic_make_request.
*/
static void __flush_deferred_io(struct mapped_device *md)
{
struct deferred_io *c, *n;
@ -605,9 +647,14 @@ static void __flush_deferred_io(struct mapped_device *md)
}
}
/*
* make the device available for use, if was
* previously suspended rather than newly created
* then all queued io is flushed
*/
int dm_activate(struct mapped_device *md)
{
int ret, minor;
int ret;
struct dev_list *d, *od;
wl;
@ -617,27 +664,17 @@ int dm_activate(struct mapped_device *md)
return 0;
}
if (!md->num_targets) {
if (!md->map) {
wu;
return -ENXIO;
}
/* open all the devices */
for (d = md->devices; d; d = d->next)
for (d = md->map->devices; d; d = d->next)
if ((ret = open_dev(d)))
goto bad;
minor = MINOR(md->dev);
_block_size[minor] = (md->highs[md->num_targets - 1] + 1) >> 1;
_blksize_size[minor] = BLOCK_SIZE; /* FIXME: this depends on
the mapping table */
_hardsect_size[minor] = __find_hardsect_size(md);
register_disk(NULL, md->dev, 1, &dm_blk_dops, _block_size[minor]);
set_bit(DM_ACTIVE, &md->state);
__flush_deferred_io(md);
wu;
@ -645,17 +682,27 @@ int dm_activate(struct mapped_device *md)
bad:
od = d;
for (d = md->devices; d != od; d = d->next)
for (d = md->map->devices; d != od; d = d->next)
close_dev(d);
ru;
return ret;
}
/*
* we need to be able to change a mapping table
* under a mounted filesystem. for example we
* might want to move some data in the background.
* Before the table can be swapped with
* dm_bind_table, dm_suspend must be called to
* flush any in flight buffer_heads and ensure
* that any further io gets deferred.
*/
void dm_suspend(struct mapped_device *md)
{
DECLARE_WAITQUEUE(wait, current);
struct dev_list *d;
if (!is_active(md))
return;
@ -676,7 +723,7 @@ void dm_suspend(struct mapped_device *md)
remove_wait_queue(&md->wait, &wait);
/* close all the devices */
for (d = md->devices; d; d = d->next)
for (d = md->map->devices; d; d = d->next)
close_dev(d);
clear_bit(DM_ACTIVE, &md->state);
@ -684,11 +731,17 @@ void dm_suspend(struct mapped_device *md)
}
struct block_device_operations dm_blk_dops = {
open: blk_open,
release: blk_close,
ioctl: blk_ioctl
};
/*
* module hooks
*/
module_init(init_dm);
module_exit(exit_dm);
module_init(dm_init);
module_exit(dm_exit);
/*
* Local variables:

View File

@ -137,9 +137,8 @@
#define DM_NAME_LEN 64
enum {
DM_LOADED = 0,
DM_LOADING,
DM_ACTIVE,
DM_BOUND = 0, /* device has been bound to a table */
DM_ACTIVE, /* device is running */
};
/*
@ -182,6 +181,24 @@ struct target {
void *private;
};
/*
* the btree
*/
struct dm_table {
/* btree table */
int depth;
int counts[MAX_DEPTH]; /* in nodes */
offset_t *index[MAX_DEPTH];
int num_targets;
int num_allocated;
offset_t *highs;
struct target *targets;
/* a list of devices used by this table */
struct dev_list *devices;
};
/*
* the actual device struct
*/
@ -198,46 +215,40 @@ struct mapped_device {
/* a list of io's that arrived while we were suspended */
struct deferred_io *deferred;
/* btree table */
int depth;
int counts[MAX_DEPTH]; /* in nodes */
offset_t *index[MAX_DEPTH];
int num_targets;
int num_allocated;
offset_t *highs;
struct target *targets;
struct dm_table *map;
/* used by dm-fs.c */
devfs_handle_t devfs_entry;
struct proc_dir_entry *pde;
/* a list of devices used by this md */
struct dev_list *devices;
};
extern struct block_device_operations dm_blk_dops;
/* dm-target.c */
int dm_target_init(void);
struct target_type *dm_get_target(const char *name);
/* dm.c */
struct mapped_device *dm_find_by_name(const char *name);
struct mapped_device *dm_find_by_minor(int minor);
int dm_create(const char *name, int minor);
int dm_remove(const char *name);
int dm_bind(struct mapped_device *md, struct dm_table *t);
int dm_activate(struct mapped_device *md);
void dm_suspend(struct mapped_device *md);
/* dm-table.c */
int dm_table_start(struct mapped_device *md);
int dm_table_add_entry(struct mapped_device *md, offset_t high,
dm_map_fn target, void *context);
int dm_table_complete(struct mapped_device *md);
void dm_table_free(struct mapped_device *md);
struct dm_table *dm_table_create(void);
void dm_table_destroy(struct dm_table *t);
int dm_table_add_entry(struct dm_table *t, offset_t high,
dm_map_fn target, void *private);
int dm_table_complete(struct dm_table *t);
/* dm-fs.c */
int dm_fs_init(void);