mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
o tidy ups
This commit is contained in:
parent
78512ae004
commit
4183d3fe6c
@ -66,7 +66,7 @@ struct pf_data {
|
||||
int minor;
|
||||
};
|
||||
|
||||
int dm_init_fs(void)
|
||||
int dm_fs_init(void)
|
||||
{
|
||||
struct pf_data *pfd = kmalloc(sizeof(*pfd), GFP_KERNEL);
|
||||
|
||||
@ -90,11 +90,11 @@ int dm_init_fs(void)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dm_fin_fs();
|
||||
dm_fs_exit();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void dm_fin_fs(void)
|
||||
void dm_fs_exit(void)
|
||||
{
|
||||
if (_control) {
|
||||
remove_proc_entry(_control_name, _proc_dir);
|
||||
@ -229,7 +229,7 @@ static int process_table(const char *b, const char *e, int minor)
|
||||
} else {
|
||||
/* add the new entry */
|
||||
char target[64];
|
||||
struct target *t;
|
||||
struct target_type *t;
|
||||
offset_t start, size, high;
|
||||
size_t len;
|
||||
|
||||
|
@ -27,19 +27,36 @@
|
||||
|
||||
#include "dm.h"
|
||||
|
||||
static int alloc_targets(struct mapped_device *md, int num);
|
||||
|
||||
/* ceiling(n / size) * size */
|
||||
static inline ulong round_up(ulong n, ulong size)
|
||||
{
|
||||
ulong r = n % size;
|
||||
return n + (r ? (size - r) : 0);
|
||||
}
|
||||
|
||||
/* ceiling(n / size) */
|
||||
static inline ulong div_up(ulong n, ulong size)
|
||||
{
|
||||
return round_up(n, size) / size;
|
||||
}
|
||||
|
||||
/* ceiling(log_size(n)) */
|
||||
static uint int_log(ulong base, ulong n)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
while (n != 1) {
|
||||
n = div_up(n, base);
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
while (1) {
|
||||
@ -52,8 +69,14 @@ static offset_t high(struct mapped_device *md, int l, int n)
|
||||
l++;
|
||||
n = (n + 1) * (KEYS_PER_NODE + 1) - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
int n, c, cn;
|
||||
@ -63,13 +86,14 @@ static int setup_btree_index(int l, struct mapped_device *md)
|
||||
|
||||
for (c = 0; c < KEYS_PER_NODE; c++)
|
||||
k[c] = high(md, l + 1, cn++);
|
||||
cn++;
|
||||
cn++; /* one extra for the child that's
|
||||
greater than all keys */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dm_free_table(struct mapped_device *md)
|
||||
void dm_table_free(struct mapped_device *md)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < md->depth; i++) {
|
||||
@ -86,70 +110,14 @@ void dm_free_table(struct mapped_device *md)
|
||||
md->num_allocated = 0;
|
||||
}
|
||||
|
||||
int dm_table_start(struct mapped_device *md)
|
||||
{
|
||||
int r;
|
||||
set_bit(DM_LOADING, &md->state);
|
||||
|
||||
dm_free_table(md);
|
||||
if ((r = alloc_targets(md, 64)))
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_table_add_entry(struct mapped_device *md, offset_t high,
|
||||
dm_map_fn target, void *context)
|
||||
{
|
||||
if (md->num_targets >= md->num_targets &&
|
||||
alloc_targets(md, md->num_allocated * 2))
|
||||
return -ENOMEM;
|
||||
|
||||
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)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
clear_bit(DM_LOADING, &md->state);
|
||||
|
||||
/* how many indexes will the btree have ? */
|
||||
for (n = div_up(md->num_targets, KEYS_PER_NODE), i = 1; n != 1; i++)
|
||||
n = div_up(n, KEYS_PER_NODE + 1);
|
||||
|
||||
md->depth = i;
|
||||
md->counts[md->depth - 1] = div_up(md->num_targets, KEYS_PER_NODE);
|
||||
|
||||
while (--i)
|
||||
md->counts[i - 1] = div_up(md->counts[i], KEYS_PER_NODE + 1);
|
||||
|
||||
for (i = 0; i < md->depth; i++) {
|
||||
size_t s = NODE_SIZE * md->counts[i];
|
||||
md->index[i] = vmalloc(s);
|
||||
memset(md->index[i], -1, s);
|
||||
}
|
||||
|
||||
/* bottom layer is easy */
|
||||
md->index[md->depth - 1] = md->highs;
|
||||
|
||||
/* fill in higher levels */
|
||||
for (i = md->depth - 1; i; i--)
|
||||
setup_btree_index(i - 1, md);
|
||||
|
||||
set_bit(DM_LOADED, &md->state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* md->highs, and md->targets are managed as
|
||||
* dynamic arrays during a table load.
|
||||
*/
|
||||
static int alloc_targets(struct mapped_device *md, int num)
|
||||
{
|
||||
offset_t *n_highs;
|
||||
struct target_instance *n_targets;
|
||||
struct target *n_targets;
|
||||
|
||||
if (!(n_highs = vmalloc(sizeof(*n_highs) * num)))
|
||||
return -ENOMEM;
|
||||
@ -176,3 +144,76 @@ static int alloc_targets(struct mapped_device *md, int num)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_table_start(struct mapped_device *md)
|
||||
{
|
||||
int r;
|
||||
set_bit(DM_LOADING, &md->state);
|
||||
|
||||
dm_table_free(md);
|
||||
|
||||
/* allocate a single nodes worth to start with */
|
||||
if ((r = alloc_targets(md, KEYS_PER_NODE)))
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_space(struct mapped_device *md)
|
||||
{
|
||||
if (md->num_targets >= md->num_allocated)
|
||||
return alloc_targets(md, md->num_allocated * 2);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
while (--i)
|
||||
md->counts[i - 1] = div_up(md->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);
|
||||
}
|
||||
|
||||
/* bottom layer is easy */
|
||||
md->index[md->depth - 1] = md->highs;
|
||||
|
||||
/* fill in higher levels */
|
||||
for (i = md->depth - 1; i; i--)
|
||||
setup_btree_index(i - 1, md);
|
||||
|
||||
set_bit(DM_LOADED, &md->state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,20 +25,20 @@
|
||||
|
||||
#include "dm.h"
|
||||
|
||||
static struct target *_targets;
|
||||
static struct target_type *_targets;
|
||||
static spinlock_t _lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
struct target *__get_target(const char *name)
|
||||
struct target_type *__get_target(const char *name)
|
||||
{
|
||||
struct target *t;
|
||||
struct target_type *t;
|
||||
for (t = _targets; t && strcmp(t->name, name); t = t->next)
|
||||
;
|
||||
return t;
|
||||
}
|
||||
|
||||
struct target *dm_get_target(const char *name)
|
||||
struct target_type *dm_get_target(const char *name)
|
||||
{
|
||||
struct target *t;
|
||||
struct target_type *t;
|
||||
|
||||
spin_lock(&_lock);
|
||||
t = __get_target(name);
|
||||
@ -50,7 +50,8 @@ struct target *dm_get_target(const char *name)
|
||||
int register_map_target(const char *name, dm_ctr_fn ctr,
|
||||
dm_dtr_fn dtr, dm_map_fn map)
|
||||
{
|
||||
struct target *t = kmalloc(sizeof(*t) + strlen(name) + 1, GFP_KERNEL);
|
||||
struct target_type *t =
|
||||
kmalloc(sizeof(*t) + strlen(name) + 1, GFP_KERNEL);
|
||||
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
@ -78,12 +79,8 @@ int register_map_target(const char *name, dm_ctr_fn ctr,
|
||||
|
||||
|
||||
/*
|
||||
* now for a couple of simple targets:
|
||||
*
|
||||
* 'io-err' target always fails an io, useful for bringing up LV's
|
||||
* that have holes in them.
|
||||
*
|
||||
* 'linear' target maps a linear range of a device
|
||||
* 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,
|
||||
const char *cb, const char *ce, void **result)
|
||||
@ -104,7 +101,9 @@ static int io_err_map(struct buffer_head *bh, void *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* linear: maps a linear range of a device.
|
||||
*/
|
||||
struct linear_c {
|
||||
kdev_t dev;
|
||||
int offset; /* FIXME: we need a signed offset type */
|
||||
@ -113,9 +112,8 @@ struct linear_c {
|
||||
static int linear_ctr(offset_t low, offset_t high, struct mapped_device *md,
|
||||
const char *cb, const char *ce, void **result)
|
||||
{
|
||||
/* context string should be of the form:
|
||||
* <major> <minor> <offset>
|
||||
*/
|
||||
/* <major> <minor> <offset> */
|
||||
|
||||
struct linear_c *lc;
|
||||
unsigned int major, minor, start;
|
||||
int r;
|
||||
@ -160,7 +158,10 @@ static int linear_map(struct buffer_head *bh, void *context)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_std_targets(void)
|
||||
/*
|
||||
* registers io-err and linear targets
|
||||
*/
|
||||
int dm_target_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -79,7 +79,7 @@ static int request(request_queue_t *q, int rw, struct buffer_head *bh);
|
||||
/*
|
||||
* setup and teardown the driver
|
||||
*/
|
||||
static int init(void)
|
||||
static int init_dm(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -91,12 +91,9 @@ static int init(void)
|
||||
0, 0, NULL, NULL)))
|
||||
return -ENOMEM;
|
||||
|
||||
if ((ret = dm_init_fs()))
|
||||
if ((ret = dm_fs_init()) || (ret = dm_target_init()))
|
||||
return ret;
|
||||
|
||||
if (dm_std_targets())
|
||||
return -EIO; /* FIXME: better error value */
|
||||
|
||||
/* set up the arrays */
|
||||
read_ahead[MAJOR_NR] = DEFAULT_READ_AHEAD;
|
||||
blk_size[MAJOR_NR] = _block_size;
|
||||
@ -115,12 +112,12 @@ static int init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fin(void)
|
||||
static void exit_dm(void)
|
||||
{
|
||||
if(kmem_cache_shrink(_io_hook_cache))
|
||||
WARN("it looks like there are still some io_hooks allocated");
|
||||
|
||||
dm_fin_fs();
|
||||
dm_fs_exit();
|
||||
|
||||
if (devfs_unregister_blkdev(MAJOR_NR, _name) < 0)
|
||||
printk(KERN_ERR "%s -- unregister_blkdev failed\n", _name);
|
||||
@ -240,9 +237,11 @@ inline static void free_io_hook(struct io_hook *ih)
|
||||
kmem_cache_free(_io_hook_cache, ih);
|
||||
}
|
||||
|
||||
/* FIXME: need to decide if deferred_io's need their own slab, I say
|
||||
no for now since they are only used when the device is
|
||||
suspended. */
|
||||
/*
|
||||
* FIXME: need to decide if deferred_io's need
|
||||
* their own slab, I say no for now since they are
|
||||
* only used when the device is suspended.
|
||||
*/
|
||||
inline static struct deferred_io *alloc_deferred(void)
|
||||
{
|
||||
return kmalloc(sizeof(struct deferred_io), GFP_NOIO);
|
||||
@ -298,7 +297,7 @@ inline static int __map_buffer(struct mapped_device *md,
|
||||
void *context;
|
||||
struct io_hook *ih = 0;
|
||||
int r;
|
||||
struct target_instance *ti = md->targets + node;
|
||||
struct target *ti = md->targets + node;
|
||||
|
||||
fn = ti->map;
|
||||
context = ti->private;
|
||||
@ -446,7 +445,7 @@ static struct mapped_device *alloc_dev(int minor)
|
||||
return md;
|
||||
}
|
||||
|
||||
static inline struct mapped_device *__find_name(const char *name)
|
||||
static inline struct mapped_device *__find_by_name(const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_DEVICES; i++)
|
||||
@ -497,7 +496,7 @@ struct mapped_device *dm_find_by_name(const char *name)
|
||||
struct mapped_device *md;
|
||||
|
||||
rl;
|
||||
md = __find_name(name);
|
||||
md = __find_by_name(name);
|
||||
ru;
|
||||
|
||||
return md;
|
||||
@ -526,7 +525,7 @@ int dm_create(const char *name, int minor)
|
||||
return -ENOMEM;
|
||||
|
||||
wl;
|
||||
if (__find_name(name)) {
|
||||
if (__find_by_name(name)) {
|
||||
WARN("device with that name already exists");
|
||||
kfree(md);
|
||||
wu;
|
||||
@ -552,7 +551,7 @@ int dm_remove(const char *name)
|
||||
int minor, r;
|
||||
|
||||
wl;
|
||||
if (!(md = __find_name(name))) {
|
||||
if (!(md = __find_by_name(name))) {
|
||||
wu;
|
||||
return -ENXIO;
|
||||
}
|
||||
@ -567,7 +566,7 @@ int dm_remove(const char *name)
|
||||
return r;
|
||||
}
|
||||
|
||||
dm_free_table(md);
|
||||
dm_table_free(md);
|
||||
for (d = md->devices; d; d = n) {
|
||||
n = d->next;
|
||||
kfree(d);
|
||||
@ -688,8 +687,8 @@ void dm_suspend(struct mapped_device *md)
|
||||
/*
|
||||
* module hooks
|
||||
*/
|
||||
module_init(init);
|
||||
module_exit(fin);
|
||||
module_init(init_dm);
|
||||
module_exit(exit_dm);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
@ -53,9 +53,9 @@
|
||||
* 1000 7,700,000
|
||||
* 10,000,000 3,800,000
|
||||
*
|
||||
* Of course these results should be taken with a pinch of salt; the lookups
|
||||
* were sequential and there were no other applications (other than X + emacs)
|
||||
* running to give any pressure on the level 1 cache.
|
||||
* Of course these results should be taken with a pinch of salt; the
|
||||
* lookups were sequential and there were no other applications (other
|
||||
* than X + emacs) running to give any pressure on the level 1 cache.
|
||||
*
|
||||
* Typical LVM users would find they have very few targets for each
|
||||
* LV (probably less than 10).
|
||||
@ -142,26 +142,49 @@ enum {
|
||||
DM_ACTIVE,
|
||||
};
|
||||
|
||||
/* devices that a metadevice should uses and hence open/close */
|
||||
/*
|
||||
* devices that a metadevice uses and hence should
|
||||
* open/close
|
||||
*/
|
||||
struct dev_list {
|
||||
kdev_t dev;
|
||||
struct block_device *bd;
|
||||
struct dev_list *next;
|
||||
};
|
||||
|
||||
/* io that had to be deferred while we were suspended */
|
||||
/*
|
||||
* io that had to be deferred while we were
|
||||
* suspended
|
||||
*/
|
||||
struct deferred_io {
|
||||
int rw;
|
||||
struct buffer_head *bh;
|
||||
struct deferred_io *next;
|
||||
};
|
||||
|
||||
/* btree leaf, these do the actual mapping */
|
||||
struct target_instance {
|
||||
/*
|
||||
* information about a target type
|
||||
*/
|
||||
struct target_type {
|
||||
char *name;
|
||||
dm_ctr_fn ctr;
|
||||
dm_dtr_fn dtr;
|
||||
dm_map_fn map;
|
||||
|
||||
struct target_type *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* btree leaf, these do the actual mapping
|
||||
*/
|
||||
struct target {
|
||||
dm_map_fn map;
|
||||
void *private;
|
||||
};
|
||||
|
||||
/*
|
||||
* the actual device struct
|
||||
*/
|
||||
struct mapped_device {
|
||||
kdev_t dev;
|
||||
char name[DM_NAME_LEN];
|
||||
@ -183,7 +206,7 @@ struct mapped_device {
|
||||
int num_targets;
|
||||
int num_allocated;
|
||||
offset_t *highs;
|
||||
struct target_instance *targets;
|
||||
struct target *targets;
|
||||
|
||||
/* used by dm-fs.c */
|
||||
devfs_handle_t devfs_entry;
|
||||
@ -193,21 +216,11 @@ struct mapped_device {
|
||||
struct dev_list *devices;
|
||||
};
|
||||
|
||||
/* information about a target type */
|
||||
struct target {
|
||||
char *name;
|
||||
dm_ctr_fn ctr;
|
||||
dm_dtr_fn dtr;
|
||||
dm_map_fn map;
|
||||
|
||||
struct target *next;
|
||||
};
|
||||
|
||||
extern struct block_device_operations dm_blk_dops;
|
||||
|
||||
/* dm-target.c */
|
||||
struct target *dm_get_target(const char *name);
|
||||
int dm_std_targets(void);
|
||||
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);
|
||||
@ -224,12 +237,11 @@ 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_free_table(struct mapped_device *md);
|
||||
|
||||
void dm_table_free(struct mapped_device *md);
|
||||
|
||||
/* dm-fs.c */
|
||||
int dm_init_fs(void);
|
||||
void dm_fin_fs(void);
|
||||
int dm_fs_init(void);
|
||||
void dm_fs_exit(void);
|
||||
|
||||
int dm_fs_add(struct mapped_device *md);
|
||||
int dm_fs_remove(struct mapped_device *md);
|
||||
|
Loading…
Reference in New Issue
Block a user