summaryrefslogtreecommitdiff
path: root/sys/dev
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
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')
-rw-r--r--sys/dev/dm/dm.h7
-rw-r--r--sys/dev/dm/dm_ioctl.c6
-rw-r--r--sys/dev/dm/dm_target.c95
-rw-r--r--sys/dev/dm/dm_target_error.c5
-rw-r--r--sys/dev/dm/dm_target_linear.c5
-rw-r--r--sys/dev/dm/dm_target_snapshot.c8
-rw-r--r--sys/dev/dm/dm_target_zero.c5
7 files changed, 106 insertions, 25 deletions
diff --git a/sys/dev/dm/dm.h b/sys/dev/dm/dm.h
index 7ca325c8aa3..a7409bcc16f 100644
--- a/sys/dev/dm/dm.h
+++ b/sys/dev/dm/dm.h
@@ -1,4 +1,4 @@
-/* $NetBSD: dm.h,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm.h,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -213,6 +213,7 @@ typedef struct dm_target {
int (*upcall)(dm_table_entry_t *, struct buf *);
uint32_t version[3];
+ int ref_cnt;
TAILQ_ENTRY(dm_target) dm_target_next;
} dm_target_t;
@@ -255,8 +256,10 @@ int dm_table_status_ioctl(prop_dictionary_t);
int dm_target_destroy(void);
int dm_target_insert(dm_target_t *);
prop_array_t dm_target_prop_list(void);
-dm_target_t* dm_target_lookup_name(const char *);
+dm_target_t* dm_target_lookup(const char *);
int dm_target_rem(char *);
+void dm_target_unbusy(dm_target_t *);
+void dm_target_busy(dm_target_t *);
/* XXX temporally add */
int dm_target_init(void);
diff --git a/sys/dev/dm/dm_ioctl.c b/sys/dev/dm/dm_ioctl.c
index e6c28f423df..43d81907ff3 100644
--- a/sys/dev/dm/dm_ioctl.c
+++ b/sys/dev/dm/dm_ioctl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_ioctl.c,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm_ioctl.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -727,10 +727,10 @@ dm_table_load_ioctl(prop_dictionary_t dm_dict)
* If we want to deny table with 2 or more different
* target we should do it here
*/
- if ((target = dm_target_lookup_name(type)) == NULL)
+ if ((target = dm_target_lookup(type)) == NULL)
return ENOENT;
- if ((table_en=kmem_alloc(sizeof(dm_table_entry_t),
+ if ((table_en = kmem_alloc(sizeof(dm_table_entry_t),
KM_NOSLEEP)) == NULL)
return ENOMEM;
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");
diff --git a/sys/dev/dm/dm_target_error.c b/sys/dev/dm/dm_target_error.c
index 09efdf703ea..9bd8bea19eb 100644
--- a/sys/dev/dm/dm_target_error.c
+++ b/sys/dev/dm/dm_target_error.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_error.c,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm_target_error.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -81,6 +81,9 @@ dm_target_error_destroy(dm_table_entry_t *table_en)
{
table_en->target_config = NULL;
+ /* Unbusy target so we can unload it */
+ dm_target_unbusy(table_en->target);
+
return 0;
}
diff --git a/sys/dev/dm/dm_target_linear.c b/sys/dev/dm/dm_target_linear.c
index c65e21fc3a3..e80badfb3ed 100644
--- a/sys/dev/dm/dm_target_linear.c
+++ b/sys/dev/dm/dm_target_linear.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_linear.c,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm_target_linear.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -176,6 +176,9 @@ dm_target_linear_destroy(dm_table_entry_t *table_en)
/* Decrement pdev ref counter if 0 remove it */
dm_pdev_decr(tlc->pdev);
+ /* Unbusy target so we can unload it */
+ dm_target_unbusy(table_en->target);
+
kmem_free(table_en->target_config, sizeof(dm_target_linear_config_t));
table_en->target_config = NULL;
diff --git a/sys/dev/dm/dm_target_snapshot.c b/sys/dev/dm/dm_target_snapshot.c
index 3482fa04491..725d525ca63 100644
--- a/sys/dev/dm/dm_target_snapshot.c
+++ b/sys/dev/dm/dm_target_snapshot.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_snapshot.c,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm_target_snapshot.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -220,6 +220,9 @@ dm_target_snapshot_destroy(dm_table_entry_t *table_en)
if (tsc->tsc_persistent_dev)
dm_pdev_decr(tsc->tsc_cow_dev);
+
+ /* Unbusy target so we can unload it */
+ dm_target_unbusy(table_en->target);
kmem_free(table_en->target_config, sizeof(dm_target_snapshot_config_t));
@@ -385,6 +388,9 @@ dm_target_snapshot_orig_destroy(dm_table_entry_t *table_en)
/* Decrement pdev ref counter if 0 remove it */
dm_pdev_decr(tsoc->tsoc_real_dev);
+
+ /* Unbusy target so we can unload it */
+ dm_target_unbusy(table_en->target);
kmem_free(table_en->target_config, sizeof(dm_target_snapshot_origin_config_t));
diff --git a/sys/dev/dm/dm_target_zero.c b/sys/dev/dm/dm_target_zero.c
index b2defff836c..c323620732c 100644
--- a/sys/dev/dm/dm_target_zero.c
+++ b/sys/dev/dm/dm_target_zero.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_zero.c,v 1.2 2008/12/19 15:24:03 haad Exp $ */
+/* $NetBSD: dm_target_zero.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -88,6 +88,9 @@ int
dm_target_zero_destroy(dm_table_entry_t *table_en)
{
table_en->target_config = NULL;
+
+ /* Unbusy target so we can unload it */
+ dm_target_unbusy(table_en->target);
return 0;
}