1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

o added reference counting to the destination devices, make sure that the

destructor for any targets you write call dm_table_remove_device.
This commit is contained in:
Joe Thornber 2001-08-31 16:36:56 +00:00
parent 0f29dc2f2d
commit a46d94071b
6 changed files with 92 additions and 32 deletions

View File

@ -39,12 +39,13 @@ 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 dm_table *t,
typedef int (*dm_ctr_fn)(struct dm_table *t,
offset_t b, offset_t e,
const char *cb, const char *ce, void **result);
typedef void (*dm_dtr_fn)(void *c);
typedef void (*dm_dtr_fn)(struct dm_table *t, void *c);
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,
int dm_register_target(const char *name, dm_ctr_fn ctr, dm_dtr_fn dtr,
dm_map_fn map);
@ -53,6 +54,7 @@ int register_map_target(const char *name, dm_ctr_fn ctr, dm_dtr_fn dtr,
* (ie. opened/closed).
*/
int dm_table_add_device(struct dm_table *t, kdev_t dev);
void dm_table_remove_device(struct dm_table *t, kdev_t dev);
#endif
#endif

View File

@ -277,12 +277,14 @@ static int process_table(const char *b, const char *e, int minor,
}
high = start + (size - 1);
if ((r = t->ctr(start, high, table, we, e, &context)))
if ((r = t->ctr(table, start, high, we, e, &context)))
return r;
if ((r = dm_table_add_entry(table, high, t->map, context)))
if ((r = dm_table_add_entry(table, high, t->map, context))) {
t->dtr(table, context);
return r;
}
}
return 0;
}

View File

@ -147,7 +147,6 @@ struct dm_table *dm_table_create(void)
void dm_table_destroy(struct dm_table *t)
{
struct dev_list *d, *n;
int i;
if (!t)
@ -164,10 +163,17 @@ void dm_table_destroy(struct dm_table *t)
kfree(t);
/* free the device list */
if (t->devices) {
struct dev_list *d, *n;
WARN("there are still devices present, someone isn't "
"calling dm_table_remove_device");
for (d = t->devices; d; d = n) {
n = d->next;
kfree(d);
}
}
}
/*
@ -200,20 +206,62 @@ int dm_table_add_entry(struct dm_table *t, offset_t high,
return 0;
}
/*
* see if we've already got a device in the list.
*/
static struct dev_list *find_device(struct dev_list *d, kdev_t dev)
{
while(d) {
if (d->dev == dev)
break;
d = d->next;
}
return d;
}
/*
* add a device to the list, or just increment the
* usage count if it's already present.
*/
int dm_table_add_device(struct dm_table *t, kdev_t dev)
{
struct dev_list *d = kmalloc(sizeof(*d), GFP_KERNEL);
struct dev_list *d;
d = find_device(t->devices, dev);
if (!d) {
d = kmalloc(sizeof(*d), GFP_KERNEL);
if (!d)
return -ENOMEM;
d->dev = dev;
atomic_set(&d->count, 0);
d->next = t->devices;
t->devices = d;
}
atomic_inc(&d->count);
return 0;
}
/*
* decrement a devices use count and remove it if
* neccessary.
*/
void dm_table_remove_device(struct dm_table *t, kdev_t dev)
{
struct dev_list *d = find_device(t->devices, dev);
if (!d) {
WARN("asked to remove a device that isn't present");
return;
}
if (atomic_dec_and_test(&d->count))
kfree(d);
}
/*
* builds the btree to index the map
*/

View File

@ -50,7 +50,7 @@ struct target_type *dm_get_target(const char *name)
/*
* register a new target_type.
*/
int register_map_target(const char *name, dm_ctr_fn ctr,
int dm_register_target(const char *name, dm_ctr_fn ctr,
dm_dtr_fn dtr, dm_map_fn map)
{
struct target_type *t =
@ -85,7 +85,8 @@ 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 dm_table *t,
static int io_err_ctr(struct dm_table *t,
offset_t b, offset_t e,
const char *cb, const char *ce, void **result)
{
/* this takes no arguments */
@ -93,7 +94,7 @@ static int io_err_ctr(offset_t b, offset_t e, struct dm_table *t,
return 0;
}
static void io_err_dtr(void *c)
static void io_err_dtr(struct dm_table *t, void *c)
{
/* empty */
}
@ -116,7 +117,8 @@ struct linear_c {
* construct a linear mapping.
* <major> <minor> <offset>
*/
static int linear_ctr(offset_t low, offset_t high, struct dm_table *t,
static int linear_ctr(struct dm_table *t,
offset_t low, offset_t high,
const char *cb, const char *ce, void **result)
{
struct linear_c *lc;
@ -149,8 +151,10 @@ static int linear_ctr(offset_t low, offset_t high, struct dm_table *t,
return 0;
}
static void linear_dtr(void *c)
static void linear_dtr(struct dm_table *t, void *c)
{
struct linear_c *lc = (struct linear_c *) c;
dm_table_remove_device(t, lc->dev);
kfree(c);
}
@ -171,7 +175,7 @@ int dm_target_init(void)
int ret;
#define xx(n, fn) \
if ((ret = register_map_target(n, \
if ((ret = dm_register_target(n, \
fn ## _ctr, fn ## _dtr, fn ## _map) < 0)) return ret
xx("io-err", io_err);
@ -180,3 +184,5 @@ int dm_target_init(void)
return 0;
}
EXPORT_SYMBOL(dm_register_target);

View File

@ -216,12 +216,12 @@ static int blk_ioctl(struct inode *inode, struct file *file,
return 0;
}
inline static struct io_hook *alloc_io_hook(void)
static inline struct io_hook *alloc_io_hook(void)
{
return kmem_cache_alloc(_io_hook_cache, GFP_NOIO);
}
inline static void free_io_hook(struct io_hook *ih)
static inline void free_io_hook(struct io_hook *ih)
{
kmem_cache_free(_io_hook_cache, ih);
}
@ -231,12 +231,12 @@ inline static void free_io_hook(struct io_hook *ih)
* 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)
static inline struct deferred_io *alloc_deferred(void)
{
return kmalloc(sizeof(struct deferred_io), GFP_NOIO);
}
inline static void free_deferred(struct deferred_io *di)
static inline void free_deferred(struct deferred_io *di)
{
kfree(di);
}
@ -289,7 +289,7 @@ static int queue_io(struct mapped_device *md, struct buffer_head *bh, int rw)
/*
* do the bh mapping for a given leaf
*/
inline static int __map_buffer(struct mapped_device *md,
static inline int __map_buffer(struct mapped_device *md,
struct buffer_head *bh, int leaf)
{
dm_map_fn fn;
@ -336,7 +336,7 @@ inline static int __map_buffer(struct mapped_device *md,
/*
* search the btree for the correct target.
*/
inline static int __find_node(struct dm_table *t, struct buffer_head *bh)
static inline int __find_node(struct dm_table *t, struct buffer_head *bh)
{
int i = 0, l, r = 0;
offset_t *node;

View File

@ -147,6 +147,8 @@ enum {
*/
struct dev_list {
kdev_t dev;
atomic_t count;
struct block_device *bd;
struct dev_list *next;
};
@ -260,12 +262,12 @@ int dm_fs_remove(struct mapped_device *md);
#define WARN(f, x...) printk(KERN_WARNING "device-mapper: " f "\n" , ## x)
inline static int is_active(struct mapped_device *md)
static inline int is_active(struct mapped_device *md)
{
return test_bit(DM_ACTIVE, &md->state);
}
inline static const char *eat_space(const char *b, const char *e)
static inline const char *eat_space(const char *b, const char *e)
{
while(b != e && isspace((int) *b))
b++;
@ -273,7 +275,7 @@ inline static const char *eat_space(const char *b, const char *e)
return b;
}
inline static int get_number(const char **b, const char *e, unsigned int *n)
static inline int get_number(const char **b, const char *e, unsigned int *n)
{
char *ptr;
*b = eat_space(*b, e);