X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmd%2Fdm.c;h=7f1af5231ef76b17329c98ae66d24a2d64dc53a8;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=4d3c1d32adf5fae71dc86bc3b5f61d58b289d256;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 4d3c1d32a..7f1af5231 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ @@ -59,6 +60,8 @@ struct mapped_device { request_queue_t *queue; struct gendisk *disk; + void *interface_ptr; + /* * A list of ios that arrived while we were suspended. */ @@ -138,23 +141,20 @@ static void local_exit(void) DMINFO("cleaned up"); } -/* - * We have a lot of init/exit functions, so it seems easier to - * store them in an array. The disposable macro 'xx' - * expands a prefix into a pair of function names. - */ -static struct { - int (*init) (void); - void (*exit) (void); - -} _inits[] = { -#define xx(n) {n ## _init, n ## _exit}, - xx(local) - xx(dm_target) - xx(dm_linear) - xx(dm_stripe) - xx(dm_interface) -#undef xx +int (*_inits[])(void) __initdata = { + local_init, + dm_target_init, + dm_linear_init, + dm_stripe_init, + dm_interface_init, +}; + +void (*_exits[])(void) = { + local_exit, + dm_target_exit, + dm_linear_exit, + dm_stripe_exit, + dm_interface_exit, }; static int __init dm_init(void) @@ -164,7 +164,7 @@ static int __init dm_init(void) int r, i; for (i = 0; i < count; i++) { - r = _inits[i].init(); + r = _inits[i](); if (r) goto bad; } @@ -173,17 +173,17 @@ static int __init dm_init(void) bad: while (i--) - _inits[i].exit(); + _exits[i](); return r; } static void __exit dm_exit(void) { - int i = ARRAY_SIZE(_inits); + int i = ARRAY_SIZE(_exits); while (i--) - _inits[i].exit(); + _exits[i](); } /* @@ -331,8 +331,8 @@ static sector_t max_io_len(struct mapped_device *md, */ if (ti->split_io) { sector_t boundary; - boundary = dm_round_up(offset + 1, ti->split_io) - offset; - + boundary = ((offset + ti->split_io) & ~(ti->split_io - 1)) + - offset; if (len > boundary) len = boundary; } @@ -643,7 +643,7 @@ static void free_minor(unsigned int minor) /* * See if the device with a specific minor # is free. */ -static int specific_minor(unsigned int minor) +static int specific_minor(struct mapped_device *md, unsigned int minor) { int r, m; @@ -663,7 +663,7 @@ static int specific_minor(unsigned int minor) goto out; } - r = idr_get_new_above(&_minor_idr, specific_minor, minor, &m); + r = idr_get_new_above(&_minor_idr, md, minor, &m); if (r) { goto out; } @@ -679,7 +679,7 @@ out: return r; } -static int next_free_minor(unsigned int *minor) +static int next_free_minor(struct mapped_device *md, unsigned int *minor) { int r; unsigned int m; @@ -692,7 +692,7 @@ static int next_free_minor(unsigned int *minor) goto out; } - r = idr_get_new(&_minor_idr, next_free_minor, &m); + r = idr_get_new(&_minor_idr, md, &m); if (r) { goto out; } @@ -726,7 +726,7 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) } /* get a minor number for the dev */ - r = persistent ? specific_minor(minor) : next_free_minor(&minor); + r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor); if (r < 0) goto bad1; @@ -805,7 +805,7 @@ static void event_callback(void *context) { struct mapped_device *md = (struct mapped_device *) context; - atomic_inc(&md->event_nr);; + atomic_inc(&md->event_nr); wake_up(&md->eventq); } @@ -883,6 +883,32 @@ int dm_create_with_minor(unsigned int minor, struct mapped_device **result) return create_aux(minor, 1, result); } +void *dm_get_mdptr(dev_t dev) +{ + struct mapped_device *md; + void *mdptr = NULL; + unsigned minor = MINOR(dev); + + if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) + return NULL; + + down(&_minor_lock); + + md = idr_find(&_minor_idr, minor); + + if (md && (dm_disk(md)->first_minor == minor)) + mdptr = md->interface_ptr; + + up(&_minor_lock); + + return mdptr; +} + +void dm_set_mdptr(struct mapped_device *md, void *ptr) +{ + md->interface_ptr = ptr; +} + void dm_get(struct mapped_device *md) { atomic_inc(&md->holders); @@ -893,8 +919,10 @@ void dm_put(struct mapped_device *md) struct dm_table *map = dm_get_table(md); if (atomic_dec_and_test(&md->holders)) { - if (!test_bit(DMF_SUSPENDED, &md->flags) && map) - dm_table_suspend_targets(map); + if (!test_bit(DMF_SUSPENDED, &md->flags) && map) { + dm_table_presuspend_targets(map); + dm_table_postsuspend_targets(map); + } __unbind(md); free_dev(md); } @@ -1006,7 +1034,11 @@ int dm_suspend(struct mapped_device *md) return -EINVAL; } + map = dm_get_table(md); + if (map) + dm_table_presuspend_targets(map); __lock_fs(md); + up_read(&md->lock); /* @@ -1029,7 +1061,6 @@ int dm_suspend(struct mapped_device *md) up_write(&md->lock); /* unplug */ - map = dm_get_table(md); if (map) { dm_table_unplug_all(map); dm_table_put(map); @@ -1064,7 +1095,7 @@ int dm_suspend(struct mapped_device *md) map = dm_get_table(md); if (map) - dm_table_suspend_targets(map); + dm_table_postsuspend_targets(map); dm_table_put(map); up_write(&md->lock); @@ -1142,5 +1173,5 @@ module_exit(dm_exit); module_param(major, uint, 0); MODULE_PARM_DESC(major, "The major number of the device mapper"); MODULE_DESCRIPTION(DM_NAME " driver"); -MODULE_AUTHOR("Joe Thornber "); +MODULE_AUTHOR("Joe Thornber "); MODULE_LICENSE("GPL");