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 65 extern const struct dkdriver dmdkdriver; 66 extern uint32_t dm_dev_counter; 67 68 typedef 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 */ 79 typedef 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 91 SLIST_HEAD(dm_table, dm_table_entry); 92 93 typedef struct dm_table dm_table_t; 94 95 typedef 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 */ 113 typedef 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 */ 129 TAILQ_HEAD(dm_dev_head, dm_dev); 130 //extern struct dm_dev_head dm_devs; 131 132 typedef 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. */ 159 typedef 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 */ 171 TAILQ_HEAD(target_linear_devs, target_linear_config); 172 173 typedef struct target_linear_devs dm_target_linear_devs_t; 174 175 /* constant dm_target structures for error, zero, linear, stripes etc. */ 176 typedef 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 */ 208 void dmgetproperties(struct disk *, dm_table_head_t *); 209 210 /* Generic function used to convert char to string */ 211 uint64_t atoi64(const char *); 212 213 /* dm_ioctl.c */ 214 int dm_dev_create_ioctl(prop_dictionary_t); 215 int dm_dev_list_ioctl(prop_dictionary_t); 216 int dm_dev_remove_ioctl(prop_dictionary_t); 217 int dm_dev_rename_ioctl(prop_dictionary_t); 218 int dm_dev_resume_ioctl(prop_dictionary_t); 219 int dm_dev_status_ioctl(prop_dictionary_t); 220 int dm_dev_suspend_ioctl(prop_dictionary_t); 221 222 int dm_check_version(prop_dictionary_t); 223 int dm_list_versions_ioctl(prop_dictionary_t); 224 225 int dm_table_clear_ioctl(prop_dictionary_t); 226 int dm_table_deps_ioctl(prop_dictionary_t); 227 int dm_table_load_ioctl(prop_dictionary_t); 228 int dm_table_status_ioctl(prop_dictionary_t); 229 230 /* dm_target.c */ 231 dm_target_t* dm_target_alloc(const char *); 232 dm_target_t* dm_target_autoload(const char *); 233 int dm_target_destroy(void); 234 int dm_target_insert(dm_target_t *); 235 prop_array_t dm_target_prop_list(void); 236 dm_target_t* dm_target_lookup(const char *); 237 int dm_target_rem(const char *); 238 void dm_target_unbusy(dm_target_t *); 239 void dm_target_busy(dm_target_t *); 240 int dm_target_init(void); 241 242 #define DM_MAX_PARAMS_SIZE 1024 243 244 /* dm_target_linear.c */ 245 int dm_target_linear_init(dm_table_entry_t *, int, char **); 246 char *dm_target_linear_table(void *); 247 int dm_target_linear_strategy(dm_table_entry_t *, struct buf *); 248 int dm_target_linear_sync(dm_table_entry_t *); 249 int dm_target_linear_destroy(dm_table_entry_t *); 250 //int dm_target_linear_upcall(dm_table_entry_t *, struct buf *); 251 int dm_target_linear_secsize(dm_table_entry_t *, unsigned int *); 252 253 /* dm_target_stripe.c */ 254 int dm_target_stripe_init(dm_table_entry_t *, int, char **); 255 char *dm_target_stripe_info(void *); 256 char *dm_target_stripe_table(void *); 257 int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *); 258 int dm_target_stripe_sync(dm_table_entry_t *); 259 int dm_target_stripe_destroy(dm_table_entry_t *); 260 //int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *); 261 int dm_target_stripe_secsize(dm_table_entry_t *, unsigned int *); 262 263 /* dm_target_error.c */ 264 int dm_target_error_init(dm_table_entry_t*, int, char **); 265 int dm_target_error_strategy(dm_table_entry_t *, struct buf *); 266 int 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 */ 270 int dm_target_zero_init(dm_table_entry_t *, int, char **); 271 int dm_target_zero_strategy(dm_table_entry_t *, struct buf *); 272 int 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 */ 277 void dm_target_delay_pool_create(void); 278 void dm_target_delay_pool_destroy(void); 279 int dm_target_delay_init(dm_table_entry_t *, int, char **); 280 char *dm_target_delay_info(void *); 281 char *dm_target_delay_table(void *); 282 int dm_target_delay_strategy(dm_table_entry_t *, struct buf *); 283 int dm_target_delay_sync(dm_table_entry_t *); 284 int dm_target_delay_destroy(dm_table_entry_t *); 285 //int dm_target_delay_upcall(dm_table_entry_t *, struct buf *); 286 int dm_target_delay_secsize(dm_table_entry_t *, unsigned int *); 287 288 /* dm_target_flakey.c */ 289 int dm_target_flakey_init(dm_table_entry_t *, int, char **); 290 char *dm_target_flakey_table(void *); 291 int dm_target_flakey_strategy(dm_table_entry_t *, struct buf *); 292 int dm_target_flakey_sync(dm_table_entry_t *); 293 int dm_target_flakey_destroy(dm_table_entry_t *); 294 //int dm_target_flakey_upcall(dm_table_entry_t *, struct buf *); 295 int 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 302 int dm_table_destroy(dm_table_head_t *, uint8_t); 303 uint64_t dm_table_size(dm_table_head_t *); 304 uint64_t dm_inactive_table_size(dm_table_head_t *); 305 void dm_table_disksize(dm_table_head_t *, uint64_t *, unsigned int *); 306 dm_table_t *dm_table_get_entry(dm_table_head_t *, uint8_t); 307 int dm_table_get_target_count(dm_table_head_t *, uint8_t); 308 void dm_table_release(dm_table_head_t *, uint8_t s); 309 void dm_table_switch_tables(dm_table_head_t *); 310 void dm_table_head_init(dm_table_head_t *); 311 void dm_table_head_destroy(dm_table_head_t *); 312 int dm_table_add_deps(dm_table_entry_t *, dm_pdev_t *); 313 314 /* dm_dev.c */ 315 dm_dev_t* dm_dev_alloc(void); 316 void dm_dev_busy(dm_dev_t *); 317 int dm_dev_destroy(void); 318 dm_dev_t* dm_dev_detach(device_t); 319 int dm_dev_free(dm_dev_t *); 320 int dm_dev_init(void); 321 int dm_dev_insert(dm_dev_t *); 322 dm_dev_t* dm_dev_lookup(const char *, const char *, int); 323 prop_array_t dm_dev_prop_list(void); 324 dm_dev_t* dm_dev_rem(const char *, const char *, int); 325 /*int dm_dev_test_minor(int);*/ 326 void dm_dev_unbusy(dm_dev_t *); 327 328 /* dm_pdev.c */ 329 int dm_pdev_decr(dm_pdev_t *); 330 int dm_pdev_destroy(void); 331 int dm_pdev_init(void); 332 dm_pdev_t* dm_pdev_insert(const char *); 333 334 #endif /*_KERNEL*/ 335 336 #endif /*_DM_H_*/ 337