1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00
lvm2/driver/device-mapper/dm-target.c
Steven Whitehouse 14ce9d49f1 Ok. this is the big one.... the change to the new fs interface.
Things to note:

 o Changes to the dm-*.c files have been kept as small as possible during
   the development of the new fs interface and there are a few places where
   the new code does odd things to give the original code what it wants. These
   places will gradually go away during the next few days once we are sure the
   new code is sound.
 o I've spent most of my testing time looking at the parser since thats where
   a lot of the changes are, I've not checked the actual I/O very much, but
   then that code hasn't changed at all.
 o The print operation in the target type operations is there to help in
   debugging and will go away eventually
 o There are some other printk's which will also go away once we are sure that
   things are working correctly.
 o I've tagged the old code with PRE_DMFS if you want to use that until this is
   stable.
 o There are no kernel patches for this yet (will fix after lunch... :-)
      o Makefile needs some changes
      o need to EXPORT_SYMBOL(deny_write_access); in ksyms.c

How to use the new interface ?

 mount -t dmfs dmfs /mnt/dm
 cd /mnt/dm
 mkdir fish fish/tank
 cd fish/tank
 cat ~/my.table > table
 cd ..
 ln -s tank ACTIVE

Creates a logical volume called fish and activates a table called tank, if
there is a problem doing the link, look in /mnt/dm/fish/tank/errors to see
what is wrong.

If you see any odd things happening, let me know right away as I'm sure there'll
be one or two things that slipped through my testing.
2001-10-17 11:34:50 +00:00

181 lines
3.0 KiB
C

/*
* dm-target.c
*
* Copyright (C) 2001 Sistina Software (UK) Limited
*
* This file is released under the GPL.
*/
/*
* 16/08/2001 - First Version [Joe Thornber]
*/
#include "dm.h"
#include <linux/kmod.h>
struct tt_internal {
struct target_type tt;
struct list_head list;
long use;
};
static LIST_HEAD(_targets);
static rwlock_t _lock = RW_LOCK_UNLOCKED;
#define DM_MOD_NAME_SIZE 32
static inline struct tt_internal *__find_target_type(const char *name)
{
struct list_head *tmp;
struct tt_internal *ti;
for(tmp = _targets.next; tmp != &_targets; tmp = tmp->next) {
ti = list_entry(tmp, struct tt_internal, list);
if (!strcmp(name, ti->tt.name))
return ti;
}
return 0;
}
static struct tt_internal *get_target_type(const char *name)
{
struct tt_internal *ti;
read_lock(&_lock);
ti = __find_target_type(name);
if (ti) {
if (ti->use == 0 && ti->tt.module)
__MOD_INC_USE_COUNT(ti->tt.module);
ti->use++;
}
read_unlock(&_lock);
return ti;
}
static void load_module(const char *name)
{
char module_name[DM_MOD_NAME_SIZE] = "dm-";
/* Length check for strcat() below */
if (strlen(name) > (DM_MOD_NAME_SIZE - 4))
return;
strcat(module_name, name);
request_module(module_name);
}
struct target_type *dm_get_target_type(const char *name)
{
struct tt_internal *ti = get_target_type(name);
if (!ti) {
load_module(name);
ti = get_target_type(name);
}
return ti ? &ti->tt : 0;
}
void dm_put_target_type(struct target_type *t)
{
struct tt_internal *ti = (struct tt_internal *) t;
read_lock(&_lock);
if (--ti->use == 0 && ti->tt.module)
__MOD_DEC_USE_COUNT(ti->tt.module);
if (ti->use < 0)
BUG();
read_unlock(&_lock);
}
static struct tt_internal *alloc_target(struct target_type *t)
{
struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL);
if (ti) {
memset(ti, 0, sizeof(*ti));
ti->tt = *t;
}
return ti;
}
int dm_register_target(struct target_type *t)
{
int rv = 0;
struct tt_internal *ti = alloc_target(t);
if (!ti)
return -ENOMEM;
write_lock(&_lock);
if (__find_target_type(t->name))
rv = -EEXIST;
else
list_add(&ti->list, &_targets);
write_unlock(&_lock);
return rv;
}
int dm_unregister_target(struct target_type *t)
{
struct tt_internal *ti = (struct tt_internal *) t;
int rv = -ETXTBSY;
write_lock(&_lock);
if (ti->use == 0) {
list_del(&ti->list);
kfree(ti);
rv = 0;
}
write_unlock(&_lock);
return rv;
}
/*
* io-err: always fails an io, useful for bringing
* up LV's that have holes in them.
*/
static int io_err_ctr(struct dm_table *t, offset_t b, offset_t l,
char *args, void **context)
{
*context = 0;
return 0;
}
static void io_err_dtr(struct dm_table *t, void *c)
{
/* empty */
}
static int io_err_map(struct buffer_head *bh, int rw, void *context)
{
buffer_IO_error(bh);
return 0;
}
static struct target_type error_target = {
name: "error",
ctr: io_err_ctr,
dtr: io_err_dtr,
map: io_err_map
};
int dm_target_init(void)
{
return dm_register_target(&error_target);
}
EXPORT_SYMBOL(dm_register_target);
EXPORT_SYMBOL(dm_unregister_target);