1 /* $NetBSD: dm.h,v 1.17 2009/12/29 23:37:48 haad 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_DEV_H_ 33 #define _DM_DEV_H_ 34 35 36 #ifdef _KERNEL 37 38 #include <sys/errno.h> 39 #include <sys/systm.h> 40 #include <sys/kernel.h> 41 42 #include <cpu/inttypes.h> 43 #include <cpu/atomic.h> 44 #include <sys/condvar.h> 45 #include <sys/lock.h> 46 #include <sys/queue.h> 47 48 #include <sys/device.h> 49 #include <sys/devicestat.h> 50 #include <sys/diskslice.h> 51 #include <sys/disklabel.h> 52 53 #include <libprop/proplib.h> 54 55 #define DM_MAX_TYPE_NAME 16 56 #define DM_NAME_LEN 128 57 #define DM_UUID_LEN 129 58 59 #define DM_VERSION_MAJOR 4 60 #define DM_VERSION_MINOR 16 61 62 #define DM_VERSION_PATCHLEVEL 0 63 64 /*** Internal device-mapper structures ***/ 65 66 /* 67 * A table entry describes a physical range of the logical volume. 68 */ 69 #define MAX_TARGET_STRING_LEN 32 70 71 /* 72 * A device mapper table is a list of physical ranges plus the mapping target 73 * applied to them. 74 */ 75 struct buf; 76 struct bio; 77 78 typedef struct dm_table_entry { 79 struct dm_dev *dm_dev; /* backlink */ 80 uint64_t start; 81 uint64_t length; 82 83 struct dm_target *target; /* Link to table target. */ 84 void *target_config; /* Target specific data. */ 85 SLIST_ENTRY(dm_table_entry) next; 86 } dm_table_entry_t; 87 88 SLIST_HEAD(dm_table, dm_table_entry); 89 90 typedef struct dm_table dm_table_t; 91 92 typedef struct dm_table_head { 93 /* Current active table is selected with this. */ 94 int cur_active_table; 95 struct dm_table tables[2]; 96 97 struct lock table_mtx; 98 struct cv table_cv; /*IO waiting cv */ 99 100 uint32_t io_cnt; 101 } dm_table_head_t; 102 103 #define MAX_DEV_NAME 32 104 105 /* 106 * This structure is used to store opened vnodes for disk with name. 107 * I need this because devices can be opened only once, but I can 108 * have more then one device on one partition. 109 */ 110 111 typedef struct dm_pdev { 112 char name[MAX_DEV_NAME]; 113 struct partinfo pdev_pinfo; /* partinfo of the underlying device */ 114 115 struct vnode *pdev_vnode; 116 int ref_cnt; /* reference counter for users ofthis pdev */ 117 118 SLIST_ENTRY(dm_pdev) next_pdev; 119 } dm_pdev_t; 120 121 /* 122 * This structure is called for every device-mapper device. 123 * It points to SLIST of device tables and mirrored, snapshoted etc. devices. 124 */ 125 TAILQ_HEAD(dm_dev_head, dm_dev); 126 127 typedef struct dm_dev { 128 char name[DM_NAME_LEN]; 129 char uuid[DM_UUID_LEN]; 130 131 cdev_t devt; /* pointer to autoconf device_t structure */ 132 uint64_t minor; 133 uint32_t flags; /* store communication protocol flags */ 134 135 struct lock dev_mtx; /* mutex for generall device lock */ 136 struct cv dev_cv; /* cv for between ioctl synchronisation */ 137 138 uint32_t event_nr; 139 uint32_t ref_cnt; 140 141 uint32_t dev_type; 142 143 dm_table_head_t table_head; 144 145 struct dm_dev_head upcalls; 146 147 struct disk *diskp; 148 struct lock diskp_mtx; 149 150 struct devstat stats; 151 152 TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */ 153 154 TAILQ_ENTRY(dm_dev) next_devlist; /* Major device list. */ 155 } dm_dev_t; 156 157 /* Device types used for upcalls */ 158 #define DM_ZERO_DEV (1 << 0) 159 #define DM_ERROR_DEV (1 << 1) 160 #define DM_LINEAR_DEV (1 << 2) 161 #define DM_MIRROR_DEV (1 << 3) 162 #define DM_STRIPE_DEV (1 << 4) 163 #define DM_SNAPSHOT_DEV (1 << 5) 164 #define DM_SNAPSHOT_ORIG_DEV (1 << 6) 165 #define DM_SPARE_DEV (1 << 7) 166 /* Set this device type only during dev remove ioctl. */ 167 #define DM_DELETING_DEV (1 << 8) 168 #define DM_CRYPTO_DEV (1 << 9) 169 170 /* for zero, error : dm_target->target_config == NULL */ 171 172 /* 173 * Target config is initiated with target_init function. 174 */ 175 176 /* for linear : */ 177 typedef struct target_linear_config { 178 dm_pdev_t *pdev; 179 uint64_t offset; 180 } dm_target_linear_config_t; 181 182 /* for stripe : */ 183 184 #define MAX_STRIPES 32 185 186 typedef struct target_stripe_config { 187 struct target_linear_config stripe_devs[MAX_STRIPES]; 188 int stripe_num; 189 uint64_t stripe_chunksize; 190 } dm_target_stripe_config_t; 191 192 /* for mirror : */ 193 typedef struct target_mirror_config { 194 #define MAX_MIRROR_COPIES 4 195 dm_pdev_t *orig; 196 dm_pdev_t *copies[MAX_MIRROR_COPIES]; 197 198 /* copied blocks bitmaps administration etc*/ 199 dm_pdev_t *log_pdev; /* for administration */ 200 uint64_t log_regionsize; /* blocksize of mirror */ 201 202 /* list of parts that still need copied etc.; run length encoded? */ 203 } dm_target_mirror_config_t; 204 205 206 /* for snapshot : */ 207 typedef struct target_snapshot_config { 208 dm_pdev_t *tsc_snap_dev; 209 /* cow dev is set only for persistent snapshot devices */ 210 dm_pdev_t *tsc_cow_dev; 211 212 uint64_t tsc_chunk_size; 213 uint32_t tsc_persistent_dev; 214 } dm_target_snapshot_config_t; 215 216 /* for snapshot-origin devices */ 217 typedef struct target_snapshot_origin_config { 218 dm_pdev_t *tsoc_real_dev; 219 /* list of snapshots ? */ 220 } dm_target_snapshot_origin_config_t; 221 222 /* constant dm_target structures for error, zero, linear, stripes etc. */ 223 typedef struct dm_target { 224 char name[DM_MAX_TYPE_NAME]; 225 /* Initialize target_config area */ 226 int (*init)(dm_dev_t *, void **, char *); 227 228 /* Destroy target_config area */ 229 int (*destroy)(dm_table_entry_t *); 230 231 int (*deps) (dm_table_entry_t *, prop_array_t); 232 /* 233 * Status routine is called to get params string, which is target 234 * specific. When dm_table_status_ioctl is called with flag 235 * DM_STATUS_TABLE_FLAG I have to sent params string back. 236 */ 237 char * (*status)(void *); 238 int (*strategy)(dm_table_entry_t *, struct buf *); 239 int (*upcall)(dm_table_entry_t *, struct buf *); 240 int (*dump)(dm_table_entry_t *, void *data, size_t length, off_t offset); 241 242 uint32_t version[3]; 243 int ref_cnt; 244 245 TAILQ_ENTRY(dm_target) dm_target_next; 246 } dm_target_t; 247 248 /* Interface structures */ 249 250 /* 251 * This structure is used to translate command sent to kernel driver in 252 * <key>command</key> 253 * <value></value> 254 * to function which I can call. 255 */ 256 struct cmd_function { 257 const char *cmd; 258 int (*fn)(prop_dictionary_t); 259 }; 260 261 /* device-mapper */ 262 void dmsetdiskinfo(struct disk *, dm_table_head_t *); 263 prop_dictionary_t dmgetdiskinfo(struct disk *); 264 void dmgetproperties(struct disk *, dm_table_head_t *); 265 int dm_detach(dm_dev_t *); 266 267 /* dm_ioctl.c */ 268 int dm_dev_create_ioctl(prop_dictionary_t); 269 int dm_dev_list_ioctl(prop_dictionary_t); 270 int dm_dev_remove_ioctl(prop_dictionary_t); 271 int dm_dev_rename_ioctl(prop_dictionary_t); 272 int dm_dev_resume_ioctl(prop_dictionary_t); 273 int dm_dev_status_ioctl(prop_dictionary_t); 274 int dm_dev_suspend_ioctl(prop_dictionary_t); 275 276 int dm_check_version(prop_dictionary_t); 277 int dm_get_version_ioctl(prop_dictionary_t); 278 int dm_list_versions_ioctl(prop_dictionary_t); 279 280 int dm_table_clear_ioctl(prop_dictionary_t); 281 int dm_table_deps_ioctl(prop_dictionary_t); 282 int dm_table_load_ioctl(prop_dictionary_t); 283 int dm_table_status_ioctl(prop_dictionary_t); 284 285 /* dm_target.c */ 286 dm_target_t* dm_target_alloc(const char *); 287 dm_target_t* dm_target_autoload(const char *); 288 int dm_target_destroy(void); 289 int dm_target_insert(dm_target_t *); 290 prop_array_t dm_target_prop_list(void); 291 dm_target_t* dm_target_lookup(const char *); 292 int dm_target_rem(char *); 293 void dm_target_unbusy(dm_target_t *); 294 void dm_target_busy(dm_target_t *); 295 296 /* XXX temporally add */ 297 int dm_target_init(void); 298 299 #define DM_MAX_PARAMS_SIZE 1024 300 301 /* dm_target_zero.c */ 302 int dm_target_zero_init(dm_dev_t *, void**, char *); 303 char * dm_target_zero_status(void *); 304 int dm_target_zero_strategy(dm_table_entry_t *, struct buf *); 305 int dm_target_zero_destroy(dm_table_entry_t *); 306 int dm_target_zero_deps(dm_table_entry_t *, prop_array_t); 307 int dm_target_zero_upcall(dm_table_entry_t *, struct buf *); 308 309 /* dm_target_error.c */ 310 int dm_target_error_init(dm_dev_t *, void**, char *); 311 char * dm_target_error_status(void *); 312 int dm_target_error_strategy(dm_table_entry_t *, struct buf *); 313 int dm_target_error_deps(dm_table_entry_t *, prop_array_t); 314 int dm_target_error_destroy(dm_table_entry_t *); 315 int dm_target_error_upcall(dm_table_entry_t *, struct buf *); 316 317 /* dm_target_linear.c */ 318 int dm_target_linear_init(dm_dev_t *, void**, char *); 319 char * dm_target_linear_status(void *); 320 int dm_target_linear_strategy(dm_table_entry_t *, struct buf *); 321 int dm_target_linear_deps(dm_table_entry_t *, prop_array_t); 322 int dm_target_linear_destroy(dm_table_entry_t *); 323 int dm_target_linear_upcall(dm_table_entry_t *, struct buf *); 324 int dm_target_linear_dump(dm_table_entry_t *, void *, size_t, off_t); 325 326 /* dm_target_crypt.c */ 327 int dm_target_crypt_init(dm_dev_t *, void**, char *); 328 char * dm_target_crypt_status(void *); 329 int dm_target_crypt_strategy(dm_table_entry_t *, struct buf *); 330 int dm_target_crypt_deps(dm_table_entry_t *, prop_array_t); 331 int dm_target_crypt_destroy(dm_table_entry_t *); 332 int dm_target_crypt_upcall(dm_table_entry_t *, struct buf *); 333 int dm_target_crypt_dump(dm_table_entry_t *, void *, size_t, off_t); 334 335 /* Generic function used to convert char to string */ 336 uint64_t atoi64(const char *); 337 338 /* dm_target_mirror.c */ 339 int dm_target_mirror_init(dm_dev_t *, void**, char *); 340 char * dm_target_mirror_status(void *); 341 int dm_target_mirror_strategy(dm_table_entry_t *, struct buf *); 342 int dm_target_mirror_deps(dm_table_entry_t *, prop_array_t); 343 int dm_target_mirror_destroy(dm_table_entry_t *); 344 int dm_target_mirror_upcall(dm_table_entry_t *, struct buf *); 345 346 /* dm_target_stripe.c */ 347 int dm_target_stripe_init(dm_dev_t *, void**, char *); 348 char * dm_target_stripe_status(void *); 349 int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *); 350 int dm_target_stripe_deps(dm_table_entry_t *, prop_array_t); 351 int dm_target_stripe_destroy(dm_table_entry_t *); 352 int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *); 353 int dm_target_stripe_dump(dm_table_entry_t *, void *, size_t, off_t); 354 355 /* dm_target_snapshot.c */ 356 int dm_target_snapshot_init(dm_dev_t *, void**, char *); 357 char * dm_target_snapshot_status(void *); 358 int dm_target_snapshot_strategy(dm_table_entry_t *, struct buf *); 359 int dm_target_snapshot_deps(dm_table_entry_t *, prop_array_t); 360 int dm_target_snapshot_destroy(dm_table_entry_t *); 361 int dm_target_snapshot_upcall(dm_table_entry_t *, struct buf *); 362 363 /* dm snapshot origin driver */ 364 int dm_target_snapshot_orig_init(dm_dev_t *, void**, char *); 365 char * dm_target_snapshot_orig_status(void *); 366 int dm_target_snapshot_orig_strategy(dm_table_entry_t *, struct buf *); 367 int dm_target_snapshot_orig_deps(dm_table_entry_t *, prop_array_t); 368 int dm_target_snapshot_orig_destroy(dm_table_entry_t *); 369 int dm_target_snapshot_orig_upcall(dm_table_entry_t *, struct buf *); 370 371 /* dm_table.c */ 372 #define DM_TABLE_ACTIVE 0 373 #define DM_TABLE_INACTIVE 1 374 375 int dm_table_destroy(dm_table_head_t *, uint8_t); 376 uint64_t dm_table_size(dm_table_head_t *); 377 dm_table_t * dm_table_get_entry(dm_table_head_t *, uint8_t); 378 int dm_table_get_target_count(dm_table_head_t *, uint8_t); 379 void dm_table_release(dm_table_head_t *, uint8_t s); 380 void dm_table_switch_tables(dm_table_head_t *); 381 void dm_table_head_init(dm_table_head_t *); 382 void dm_table_head_destroy(dm_table_head_t *); 383 384 /* dm_dev.c */ 385 dm_dev_t* dm_dev_alloc(void); 386 void dm_dev_busy(dm_dev_t *); 387 int dm_dev_destroy(void); 388 void disable_dev(dm_dev_t *); 389 int dm_dev_free(dm_dev_t *); 390 int dm_dev_init(void); 391 int dm_dev_insert(dm_dev_t *); 392 dm_dev_t* dm_dev_lookup(const char *, const char *, int); 393 prop_array_t dm_dev_prop_list(void); 394 dm_dev_t* dm_dev_rem(const char *, const char *, int); 395 /*int dm_dev_test_minor(int);*/ 396 void dm_dev_unbusy(dm_dev_t *); 397 398 /* dm_pdev.c */ 399 int dm_pdev_decr(dm_pdev_t *); 400 int dm_pdev_destroy(void); 401 int dm_pdev_init(void); 402 dm_pdev_t* dm_pdev_insert(const char *); 403 off_t dm_pdev_correct_dump_offset(dm_pdev_t *, off_t); 404 405 extern int dm_debug_level; 406 MALLOC_DECLARE(M_DM); 407 408 #define aprint_debug(format, ...) \ 409 do { if (dm_debug_level) kprintf(format, ## __VA_ARGS__); } while(0) 410 #define aprint_normal kprintf 411 412 #endif /*_KERNEL*/ 413 414 #endif /*_DM_DEV_H_*/ 415