diff options
| author | haad <haad@NetBSD.org> | 2008-12-19 16:30:41 +0000 |
|---|---|---|
| committer | haad <haad@NetBSD.org> | 2008-12-19 16:30:41 +0000 |
| commit | 78284dcaf12637bfbb20587a1462594b9f2b730a (patch) | |
| tree | 2100fb14f4ebfd8ed671b082aa5a7ef354ba6957 /sys/dev | |
| parent | 210ce8a4644c8bbb37146181ab162e59738a52ec (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.h | 7 | ||||
| -rw-r--r-- | sys/dev/dm/dm_ioctl.c | 6 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target.c | 95 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_error.c | 5 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_linear.c | 5 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_snapshot.c | 8 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_zero.c | 5 |
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; } |
