summaryrefslogtreecommitdiff
path: root/sys/dev/dm/dm_target.c
diff options
context:
space:
mode:
authorhaad <haad@NetBSD.org>2008-12-19 16:30:41 +0000
committerhaad <haad@NetBSD.org>2008-12-19 16:30:41 +0000
commit78284dcaf12637bfbb20587a1462594b9f2b730a (patch)
tree2100fb14f4ebfd8ed671b082aa5a7ef354ba6957 /sys/dev/dm/dm_target.c
parent210ce8a4644c8bbb37146181ab162e59738a52ec (diff)
Add infrastructure needed to load device-mapper targets as modules.
Targets wasn't converted yet and at least snapshot target will be converted in a near future.
Diffstat (limited to 'sys/dev/dm/dm_target.c')
-rw-r--r--sys/dev/dm/dm_target.c95
1 files changed, 79 insertions, 16 deletions
diff --git a/sys/dev/dm/dm_target.c b/sys/dev/dm/dm_target.c
index d1ab3f9e259..01911e258cd 100644
--- a/sys/dev/dm/dm_target.c
+++ b/sys/dev/dm/dm_target.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target.c,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm_target.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -38,31 +38,70 @@
#include "dm.h"
static dm_target_t* dm_target_alloc(const char *);
+static dm_target_t* dm_target_lookup_name(const char *);
TAILQ_HEAD(dm_target_head, dm_target);
static struct dm_target_head dm_target_list =
TAILQ_HEAD_INITIALIZER(dm_target_list);
+kmutex_t dm_target_mutex;
+
+/*
+ * Called indirectly from dm_table_load_ioct to mark target as used.
+ */
+void
+dm_target_busy(dm_target_t *target)
+{
+ target->ref_cnt++;
+}
+
+void
+dm_target_unbusy(dm_target_t *target)
+{
+ target->ref_cnt--;
+}
+
+dm_target_t *
+dm_target_lookup(const char *dm_target_name)
+{
+ dm_target_t *dmt;
+
+ dmt = NULL;
+
+ mutex_enter(&dm_target_mutex);
+
+ if (dm_target_name != NULL)
+ dmt = dm_target_lookup_name(dm_target_name);
+
+ if (dmt != NULL)
+ dm_target_busy(dmt);
+
+ mutex_exit(&dm_target_mutex);
+
+ return dmt;
+}
+
/*
* Search for name in TAIL and return apropriate pointer.
*/
-dm_target_t*
+static dm_target_t*
dm_target_lookup_name(const char *dm_target_name)
{
dm_target_t *dm_target;
int dlen; int slen;
- slen = strlen(dm_target_name)+1;
+ slen = strlen(dm_target_name) + 1;
- TAILQ_FOREACH (dm_target, &dm_target_list, dm_target_next) {
- dlen = strlen(dm_target->name)+1;
+ TAILQ_FOREACH(dm_target, &dm_target_list, dm_target_next) {
+ dlen = strlen(dm_target->name) + 1;
if (dlen != slen)
continue;
- if (strncmp(dm_target_name, dm_target->name, slen) == 0)
- return dm_target;
+ if (strncmp(dm_target_name, dm_target->name, slen) == 0){
+ return dm_target;
+ }
}
return NULL;
@@ -77,13 +116,18 @@ int
dm_target_insert(dm_target_t *dm_target)
{
dm_target_t *dmt;
+
+ mutex_enter(&dm_target_mutex);
dmt = dm_target_lookup_name(dm_target->name);
-
- if (dmt != NULL)
+ if (dmt != NULL) {
+ mutex_exit(&dm_target_mutex);
return EEXIST;
-
+ }
+
TAILQ_INSERT_TAIL(&dm_target_list, dm_target, dm_target_next);
+
+ mutex_exit(&dm_target_mutex);
return 0;
}
@@ -95,18 +139,29 @@ dm_target_insert(dm_target_t *dm_target)
int
dm_target_rem(char *dm_target_name)
{
- dm_target_t *dm_target;
+ dm_target_t *dmt;
KASSERT(dm_target_name != NULL);
-
- dm_target = dm_target_lookup_name(dm_target_name);
- if (dm_target == NULL)
+
+ mutex_enter(&dm_target_mutex);
+
+ dmt = dm_target_lookup_name(dm_target_name);
+ if (dmt == NULL) {
+ mutex_exit(&dm_target_mutex);
return ENOENT;
+ }
+
+ if (dmt->ref_cnt > 0) {
+ mutex_exit(&dm_target_mutex);
+ return EBUSY;
+ }
TAILQ_REMOVE(&dm_target_list,
- dm_target, dm_target_next);
+ dmt, dm_target_next);
+
+ mutex_exit(&dm_target_mutex);
- (void)kmem_free(dm_target, sizeof(dm_target_t));
+ (void)kmem_free(dmt, sizeof(dm_target_t));
return 0;
}
@@ -122,6 +177,7 @@ dm_target_destroy(void)
{
dm_target_t *dm_target;
+ mutex_enter(&dm_target_mutex);
while (TAILQ_FIRST(&dm_target_list) != NULL){
dm_target = TAILQ_FIRST(&dm_target_list);
@@ -131,6 +187,7 @@ dm_target_destroy(void)
(void)kmem_free(dm_target, sizeof(dm_target_t));
}
+ mutex_exit(&dm_target_mutex);
return 0;
}
@@ -157,6 +214,8 @@ dm_target_prop_list(void)
size_t i;
target_array = prop_array_create();
+
+ mutex_enter(&dm_target_mutex);
TAILQ_FOREACH (dm_target, &dm_target_list, dm_target_next){
@@ -175,6 +234,8 @@ dm_target_prop_list(void)
prop_object_release(target_dict);
}
+ mutex_exit(&dm_target_mutex);
+
return target_array;
}
@@ -186,6 +247,8 @@ dm_target_init(void)
int r;
r = 0;
+
+ mutex_init(&dm_target_mutex, MUTEX_DEFAULT, IPL_NONE);
dmt = dm_target_alloc("linear");
dmt1 = dm_target_alloc("zero");