1/* $NetBSD: dm.h,v 1.56 2021/08/21 22:23:33 andvar Exp $ */ 2 3/* 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Adam Hamsik. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#ifndef _DM_H_ 33#define _DM_H_ 34 35#ifdef _KERNEL 36 37#include <sys/errno.h> 38#include <sys/atomic.h> 39#include <sys/fcntl.h> 40#include <sys/condvar.h> 41#include <sys/kauth.h> 42#include <sys/mutex.h> 43#include <sys/rwlock.h> 44#include <sys/queue.h> 45#include <sys/vnode.h> 46#include <sys/device.h> 47#include <sys/disk.h> 48#include <sys/disklabel.h> 49 50#include <miscfs/specfs/specdev.h> /* for v_rdev */ 51 52#include <prop/proplib.h> 53 54#define DM_MAX_TYPE_NAME 16 55#define DM_NAME_LEN 128 56#define DM_UUID_LEN 129 57 58#define DM_VERSION_MAJOR 4 59#define DM_VERSION_MINOR 16 60 61#define DM_VERSION_PATCHLEVEL 0 62 63/*** Internal device-mapper structures ***/ 64 65extern const struct dkdriver dmdkdriver; 66extern uint32_t dm_dev_counter; 67 68typedef struct dm_mapping { 69 union { 70 struct dm_pdev *pdev; 71 } data; 72 TAILQ_ENTRY(dm_mapping) next; 73} dm_mapping_t; 74 75/* 76 * A device mapper table is a list of physical ranges plus the mapping target 77 * applied to them. 78 */ 79typedef struct dm_table_entry { 80 struct dm_dev *dm_dev; /* backlink */ 81 uint64_t start; 82 uint64_t length; 83 84 struct dm_target *target; /* Link to table target. */ 85 void *target_config; /* Target specific data. */ 86 SLIST_ENTRY(dm_table_entry) next; 87 88 TAILQ_HEAD(, dm_mapping) pdev_maps; 89} dm_table_entry_t; 90 91SLIST_HEAD(dm_table, dm_table_entry); 92 93typedef struct dm_table dm_table_t; 94 95typedef struct dm_table_head { 96 /* Current active table is selected with this. */ 97 int cur_active_table; 98 dm_table_t tables[2]; 99 100 kmutex_t table_mtx; 101 kcondvar_t table_cv; /* I/O waiting cv */ 102 103 uint32_t io_cnt; 104} dm_table_head_t; 105 106#define MAX_DEV_NAME 32 107 108/* 109 * This structure is used to store opened vnodes for disk with name. 110 * I need this because devices can be opened only once, but I can 111 * have more than one device on one partition. 112 */ 113typedef struct dm_pdev { 114 char name[MAX_DEV_NAME]; 115 char udev_name[MAX_DEV_NAME]; 116 117 struct vnode *pdev_vnode; 118 uint64_t pdev_numsec; 119 unsigned int pdev_secsize; 120 int ref_cnt; /* reference counter for users of this pdev */ 121 122 SLIST_ENTRY(dm_pdev) next_pdev; 123} dm_pdev_t; 124 125/* 126 * This structure is called for every device-mapper device. 127 * It points to SLIST of device tables and mirrored, snapshoted etc. devices. 128 */ 129TAILQ_HEAD(dm_dev_head, dm_dev); 130//extern struct dm_dev_head dm_devs; 131 132typedef struct dm_dev { 133 char name[DM_NAME_LEN]; 134 char uuid[DM_UUID_LEN]; 135 136 device_t devt; /* pointer to autoconf device_t structure */ 137 uint64_t minor; /* Device minor number */ 138 uint32_t flags; /* store communication protocol flags */ 139 140 kmutex_t dev_mtx; /* mutex for general device lock */ 141 kcondvar_t dev_cv; /* cv for between ioctl synchronisation */ 142 143 uint32_t event_nr; 144 uint32_t ref_cnt; 145 146 dm_table_head_t table_head; 147 148 //struct dm_dev_head upcalls; 149 150 struct disk *diskp; 151 kmutex_t diskp_mtx; 152 153 //TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */ 154 155 TAILQ_ENTRY(dm_dev) next_devlist; /* Major device list. */ 156} dm_dev_t; 157 158/* For linear target. */ 159typedef struct target_linear_config { 160 dm_pdev_t *pdev; 161 uint64_t offset; 162 TAILQ_ENTRY(target_linear_config) entries; 163} dm_target_linear_config_t; 164 165/* 166 * Striping devices are stored in a linked list, this might be inefficient 167 * for more than 8 striping devices and can be changed to something more 168 * scalable. 169 * TODO: look for other options than linked list. 170 */ 171TAILQ_HEAD(target_linear_devs, target_linear_config); 172 173typedef struct target_linear_devs dm_target_linear_devs_t; 174 175/* constant dm_target structures for error, zero, linear, stripes etc. */ 176typedef struct dm_target { 177 char name[DM_MAX_TYPE_NAME]; 178 /* Initialize target_config area */ 179 int (*init)(dm_table_entry_t *, int, char **); 180 181 /* Destroy target_config area */ 182 int (*destroy)(dm_table_entry_t *); 183 184 int (*strategy)(dm_table_entry_t *, struct buf *); 185 //int (*upcall)(dm_table_entry_t *, struct buf *); 186 187 /* 188 * Optional routines. 189 */ 190 /* 191 * Info/table routine are called to get params string, which is target 192 * specific. When dm_table_status_ioctl is called with flag 193 * DM_STATUS_TABLE_FLAG I have to sent params string back. 194 */ 195 char *(*info)(void *); 196 char *(*table)(void *); 197 int (*sync)(dm_table_entry_t *); 198 int (*secsize)(dm_table_entry_t *, unsigned int *); 199 200 uint32_t version[3]; 201 uint32_t ref_cnt; 202 int max_argc; 203 204 TAILQ_ENTRY(dm_target) dm_target_next; 205} dm_target_t; 206 207/* device-mapper */ 208void dmgetproperties(struct disk *, dm_table_head_t *); 209 210/* Generic function used to convert char to string */ 211uint64_t atoi64(const char *); 212 213/* dm_ioctl.c */ 214int dm_dev_create_ioctl(prop_dictionary_t); 215int dm_dev_list_ioctl(prop_dictionary_t); 216int dm_dev_remove_ioctl(prop_dictionary_t); 217int dm_dev_rename_ioctl(prop_dictionary_t); 218int dm_dev_resume_ioctl(prop_dictionary_t); 219int dm_dev_status_ioctl(prop_dictionary_t); 220int dm_dev_suspend_ioctl(prop_dictionary_t); 221 222int dm_check_version(prop_dictionary_t); 223int dm_list_versions_ioctl(prop_dictionary_t); 224 225int dm_table_clear_ioctl(prop_dictionary_t); 226int dm_table_deps_ioctl(prop_dictionary_t); 227int dm_table_load_ioctl(prop_dictionary_t); 228int dm_table_status_ioctl(prop_dictionary_t); 229 230/* dm_target.c */ 231dm_target_t* dm_target_alloc(const char *); 232dm_target_t* dm_target_autoload(const char *); 233int dm_target_destroy(void); 234int dm_target_insert(dm_target_t *); 235prop_array_t dm_target_prop_list(void); 236dm_target_t* dm_target_lookup(const char *); 237int dm_target_rem(const char *); 238void dm_target_unbusy(dm_target_t *); 239void dm_target_busy(dm_target_t *); 240int dm_target_init(void); 241 242#define DM_MAX_PARAMS_SIZE 1024 243 244/* dm_target_linear.c */ 245int dm_target_linear_init(dm_table_entry_t *, int, char **); 246char *dm_target_linear_table(void *); 247int dm_target_linear_strategy(dm_table_entry_t *, struct buf *); 248int dm_target_linear_sync(dm_table_entry_t *); 249int dm_target_linear_destroy(dm_table_entry_t *); 250//int dm_target_linear_upcall(dm_table_entry_t *, struct buf *); 251int dm_target_linear_secsize(dm_table_entry_t *, unsigned int *); 252 253/* dm_target_stripe.c */ 254int dm_target_stripe_init(dm_table_entry_t *, int, char **); 255char *dm_target_stripe_info(void *); 256char *dm_target_stripe_table(void *); 257int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *); 258int dm_target_stripe_sync(dm_table_entry_t *); 259int dm_target_stripe_destroy(dm_table_entry_t *); 260//int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *); 261int dm_target_stripe_secsize(dm_table_entry_t *, unsigned int *); 262 263/* dm_target_error.c */ 264int dm_target_error_init(dm_table_entry_t*, int, char **); 265int dm_target_error_strategy(dm_table_entry_t *, struct buf *); 266int dm_target_error_destroy(dm_table_entry_t *); 267//int dm_target_error_upcall(dm_table_entry_t *, struct buf *); 268 269/* dm_target_zero.c */ 270int dm_target_zero_init(dm_table_entry_t *, int, char **); 271int dm_target_zero_strategy(dm_table_entry_t *, struct buf *); 272int dm_target_zero_destroy(dm_table_entry_t *); 273//int dm_target_zero_upcall(dm_table_entry_t *, struct buf *); 274 275#if 0 276/* dm_target_delay.c */ 277void dm_target_delay_pool_create(void); 278void dm_target_delay_pool_destroy(void); 279int dm_target_delay_init(dm_table_entry_t *, int, char **); 280char *dm_target_delay_info(void *); 281char *dm_target_delay_table(void *); 282int dm_target_delay_strategy(dm_table_entry_t *, struct buf *); 283int dm_target_delay_sync(dm_table_entry_t *); 284int dm_target_delay_destroy(dm_table_entry_t *); 285//int dm_target_delay_upcall(dm_table_entry_t *, struct buf *); 286int dm_target_delay_secsize(dm_table_entry_t *, unsigned int *); 287 288/* dm_target_flakey.c */ 289int dm_target_flakey_init(dm_table_entry_t *, int, char **); 290char *dm_target_flakey_table(void *); 291int dm_target_flakey_strategy(dm_table_entry_t *, struct buf *); 292int dm_target_flakey_sync(dm_table_entry_t *); 293int dm_target_flakey_destroy(dm_table_entry_t *); 294//int dm_target_flakey_upcall(dm_table_entry_t *, struct buf *); 295int dm_target_flakey_secsize(dm_table_entry_t *, unsigned int *); 296#endif 297 298/* dm_table.c */ 299#define DM_TABLE_ACTIVE 0 300#define DM_TABLE_INACTIVE 1 301 302int dm_table_destroy(dm_table_head_t *, uint8_t); 303uint64_t dm_table_size(dm_table_head_t *); 304uint64_t dm_inactive_table_size(dm_table_head_t *); 305void dm_table_disksize(dm_table_head_t *, uint64_t *, unsigned int *); 306dm_table_t *dm_table_get_entry(dm_table_head_t *, uint8_t); 307int dm_table_get_target_count(dm_table_head_t *, uint8_t); 308void dm_table_release(dm_table_head_t *, uint8_t s); 309void dm_table_switch_tables(dm_table_head_t *); 310void dm_table_head_init(dm_table_head_t *); 311void dm_table_head_destroy(dm_table_head_t *); 312int dm_table_add_deps(dm_table_entry_t *, dm_pdev_t *); 313 314/* dm_dev.c */ 315dm_dev_t* dm_dev_alloc(void); 316void dm_dev_busy(dm_dev_t *); 317int dm_dev_destroy(void); 318dm_dev_t* dm_dev_detach(device_t); 319int dm_dev_free(dm_dev_t *); 320int dm_dev_init(void); 321int dm_dev_insert(dm_dev_t *); 322dm_dev_t* dm_dev_lookup(const char *, const char *, int); 323prop_array_t dm_dev_prop_list(void); 324dm_dev_t* dm_dev_rem(const char *, const char *, int); 325/*int dm_dev_test_minor(int);*/ 326void dm_dev_unbusy(dm_dev_t *); 327 328/* dm_pdev.c */ 329int dm_pdev_decr(dm_pdev_t *); 330int dm_pdev_destroy(void); 331int dm_pdev_init(void); 332dm_pdev_t* dm_pdev_insert(const char *); 333 334#endif /*_KERNEL*/ 335 336#endif /*_DM_H_*/ 337