mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
o quick tidy up
This commit is contained in:
parent
269930c0da
commit
2eca35b6d6
@ -1,22 +1,9 @@
|
||||
/*
|
||||
* dm-target.c
|
||||
*
|
||||
* Copyright (C) 2001 Sistina Software
|
||||
* Copyright (C) 2001 Sistina Software (UK) Limited
|
||||
*
|
||||
* This software is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU CC; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* This file is released under the GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -26,79 +13,88 @@
|
||||
#include "dm.h"
|
||||
#include <linux/kmod.h>
|
||||
|
||||
static LIST_HEAD(dm_targets);
|
||||
static rwlock_t dm_targets_lock = RW_LOCK_UNLOCKED;
|
||||
static LIST_HEAD(_targets);
|
||||
static rwlock_t _lock = RW_LOCK_UNLOCKED;
|
||||
|
||||
#define DM_MOD_NAME_SIZE 32
|
||||
|
||||
struct target_type *dm_get_target_type(const char *name)
|
||||
static inline struct target_type *__get_target_type(const char *name)
|
||||
{
|
||||
struct list_head *tmp, *head;
|
||||
struct target_type *t;
|
||||
int try = 0;
|
||||
|
||||
for(tmp = _targets.next; tmp != &_targets; tmp = tmp->next) {
|
||||
|
||||
t = list_entry(tmp, struct target_type, list);
|
||||
if (!strcmp(name, t->name)) {
|
||||
if (!t->use && t->module)
|
||||
__MOD_INC_USE_COUNT(t->module);
|
||||
t->use++;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct target_type *get_target_type(const char *name)
|
||||
{
|
||||
read_lock(&_lock);
|
||||
t = __get_target_type(name);
|
||||
read_unlock(&_lock);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
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 NULL;
|
||||
|
||||
try_again:
|
||||
read_lock(&dm_targets_lock);
|
||||
tmp = head = &dm_targets;
|
||||
for(;;) {
|
||||
tmp = tmp->next;
|
||||
if (tmp == head)
|
||||
break;
|
||||
t = list_entry(tmp, struct target_type, list);
|
||||
if (strcmp(name, t->name) == 0) {
|
||||
if (t->use == 0 && t->module)
|
||||
__MOD_INC_USE_COUNT(t->module);
|
||||
t->use++;
|
||||
read_unlock(&dm_targets_lock);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
read_unlock(&dm_targets_lock);
|
||||
/* strcat() is only safe due to length check above */
|
||||
strcat(module_name, name);
|
||||
request_module(module_name);
|
||||
}
|
||||
|
||||
if (try++ == 0) {
|
||||
char module_name[DM_MOD_NAME_SIZE] = "dm-";
|
||||
/* strcat() is only safe due to length check above */
|
||||
strcat(module_name, name);
|
||||
request_module(module_name);
|
||||
goto try_again;
|
||||
struct target_type *dm_get_target_type(const char *name)
|
||||
{
|
||||
t = get_target_type(name);
|
||||
|
||||
if (!t) {
|
||||
load_module(name);
|
||||
t = get_target_type(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return t;
|
||||
}
|
||||
|
||||
void dm_put_target_type(struct target_type *t)
|
||||
{
|
||||
read_lock(&dm_targets_lock);
|
||||
read_lock(&_lock);
|
||||
if (--t->use == 0 && t->module)
|
||||
__MOD_DEC_USE_COUNT(t->module);
|
||||
|
||||
if (t->use < 0)
|
||||
BUG();
|
||||
read_unlock(&dm_targets_lock);
|
||||
read_unlock(&_lock);
|
||||
}
|
||||
|
||||
int dm_register_target(struct target_type *t)
|
||||
{
|
||||
struct list_head *tmp, *head;
|
||||
struct target_type *t2;
|
||||
int rv = 0;
|
||||
write_lock(&dm_targets_lock);
|
||||
tmp = head = &dm_targets;
|
||||
for(;;) {
|
||||
if (tmp == head)
|
||||
break;
|
||||
t2 = list_entry(tmp, struct target_type, list);
|
||||
if (strcmp(t->name, t2->name) != 0)
|
||||
continue;
|
||||
|
||||
write_lock(&_lock);
|
||||
if (__get_target_type(t->name)) {
|
||||
rv = -EEXIST;
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
if (rv == 0)
|
||||
list_add(&t->list, &dm_targets);
|
||||
write_unlock(&dm_targets_lock);
|
||||
list_add(&t->list, &_targets);
|
||||
|
||||
out:
|
||||
write_unlock(&_lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -106,12 +102,12 @@ int dm_unregister_target(struct target_type *t)
|
||||
{
|
||||
int rv = -ETXTBSY;
|
||||
|
||||
write_lock(&dm_targets_lock);
|
||||
write_lock(&_lock);
|
||||
if (t->use == 0) {
|
||||
list_del(&t->list);
|
||||
rv = 0;
|
||||
}
|
||||
write_unlock(&dm_targets_lock);
|
||||
write_unlock(&_lock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user