From e8f62085be586fac2f5931ff83da0c36b85e98b1 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 31 Aug 2001 12:49:31 +0000 Subject: [PATCH] o tidy ups --- driver/device-mapper/dm-fs.c | 8 +- driver/device-mapper/dm-table.c | 171 +++++++++++++++++++------------ driver/device-mapper/dm-target.c | 35 ++++--- driver/device-mapper/dm.c | 35 +++---- driver/device-mapper/dm.h | 60 ++++++----- 5 files changed, 181 insertions(+), 128 deletions(-) diff --git a/driver/device-mapper/dm-fs.c b/driver/device-mapper/dm-fs.c index 541923587..9c981a391 100644 --- a/driver/device-mapper/dm-fs.c +++ b/driver/device-mapper/dm-fs.c @@ -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; diff --git a/driver/device-mapper/dm-table.c b/driver/device-mapper/dm-table.c index e96b7dd36..adb9a67d0 100644 --- a/driver/device-mapper/dm-table.c +++ b/driver/device-mapper/dm-table.c @@ -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; +} + + diff --git a/driver/device-mapper/dm-target.c b/driver/device-mapper/dm-target.c index 851e31234..f286eadae 100644 --- a/driver/device-mapper/dm-target.c +++ b/driver/device-mapper/dm-target.c @@ -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: - * - */ + /* */ + 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; diff --git a/driver/device-mapper/dm.c b/driver/device-mapper/dm.c index 6c9ab6a65..da87593f8 100644 --- a/driver/device-mapper/dm.c +++ b/driver/device-mapper/dm.c @@ -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: diff --git a/driver/device-mapper/dm.h b/driver/device-mapper/dm.h index 5be6d4e5c..e040c7348 100644 --- a/driver/device-mapper/dm.h +++ b/driver/device-mapper/dm.h @@ -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);