#ifndef _DM_DEV_H_
#define _DM_DEV_H_
#ifdef _KERNEL
#include <sys/errno.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/types.h>
#include <cpu/inttypes.h>
#include <sys/condvar.h>
#include <sys/lock.h>
#include <sys/queue.h>
#include <sys/vnode.h>
#include <sys/buf.h>
#include <sys/device.h>
#include <sys/devicestat.h>
#include <sys/diskslice.h>
#include <sys/disklabel.h>
#include <sys/vfscache.h>
#include <libprop/proplib.h>
#define DM_VERSION_MAJOR 4
#define DM_VERSION_MINOR 16
#define DM_VERSION_PATCHLEVEL 0
#define DM_MAX_TYPE_NAME 16
#define DM_MAX_DEV_NAME 32
#define DM_MAX_PARAMS_SIZE 1024
#define DM_NAME_LEN 128
#define DM_UUID_LEN 129
#define DM_TABLE_ACTIVE 0
#define DM_TABLE_INACTIVE 1
typedef struct dm_mapping {
union {
struct dm_pdev *pdev;
} data;
TAILQ_ENTRY(dm_mapping) next;
} dm_mapping_t;
typedef struct dm_table_entry {
struct dm_dev *dev;
uint64_t start;
uint64_t length;
struct dm_target *target;
void *target_config;
TAILQ_ENTRY(dm_table_entry) next;
TAILQ_HEAD(, dm_mapping) pdev_maps;
} dm_table_entry_t;
TAILQ_HEAD(dm_table, dm_table_entry);
typedef struct dm_table dm_table_t;
typedef struct dm_table_head {
int cur_active_table;
struct dm_table tables[2];
struct lock table_mtx;
int io_cnt;
} dm_table_head_t;
typedef struct dm_pdev {
char name[DM_MAX_DEV_NAME];
char udev_name[DM_MAX_DEV_NAME];
dev_t udev;
struct partinfo pdev_pinfo;
struct vnode *pdev_vnode;
int ref_cnt;
TAILQ_ENTRY(dm_pdev) next_pdev;
} dm_pdev_t;
typedef struct dm_dev {
char name[DM_NAME_LEN];
char uuid[DM_UUID_LEN];
cdev_t devt;
uint64_t minor;
uint32_t flags;
struct lock dev_mtx;
struct cv dev_cv;
uint32_t ref_cnt;
uint32_t is_open;
dm_table_head_t table_head;
struct disk *diskp;
struct devstat stats;
TAILQ_ENTRY(dm_dev) next_devlist;
} dm_dev_t;
typedef struct dm_target {
char name[DM_MAX_TYPE_NAME];
int (*init)(dm_table_entry_t *, int, char **);
int (*destroy)(dm_table_entry_t *);
int (*strategy)(dm_table_entry_t *, struct buf *);
char *(*table)(void *);
char *(*info)(void *);
int (*dump)(dm_table_entry_t *, void *data, size_t length, off_t offset);
int (*message)(dm_table_entry_t *, char *);
uint32_t version[3];
int ref_cnt;
int max_argc;
TAILQ_ENTRY(dm_target) dm_target_next;
} dm_target_t;
void dmsetdiskinfo(struct disk *, dm_table_head_t *);
uint64_t atoi64(const char *);
char *dm_alloc_string(int len);
void dm_builtin_init(void *);
void dm_builtin_uninit(void *);
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_DM);
#endif
extern int dm_debug_level;
int dm_list_versions_ioctl(prop_dictionary_t);
int dm_dev_create_ioctl(prop_dictionary_t);
int dm_dev_list_ioctl(prop_dictionary_t);
int dm_dev_rename_ioctl(prop_dictionary_t);
int dm_dev_remove_ioctl(prop_dictionary_t);
int dm_dev_remove_all_ioctl(prop_dictionary_t);
int dm_dev_status_ioctl(prop_dictionary_t);
int dm_dev_suspend_ioctl(prop_dictionary_t);
int dm_dev_resume_ioctl(prop_dictionary_t);
int dm_table_clear_ioctl(prop_dictionary_t);
int dm_table_deps_ioctl(prop_dictionary_t);
int dm_table_load_ioctl(prop_dictionary_t);
int dm_table_status_ioctl(prop_dictionary_t);
int dm_message_ioctl(prop_dictionary_t);
int dm_check_version(prop_dictionary_t);
void dm_target_busy(dm_target_t *);
void dm_target_unbusy(dm_target_t *);
dm_target_t* dm_target_autoload(const char *);
dm_target_t* dm_target_lookup(const char *);
int dm_target_insert(dm_target_t *);
int dm_target_remove(char *);
dm_target_t* dm_target_alloc(const char *);
int dm_target_free(dm_target_t *);
prop_array_t dm_target_prop_list(void);
int dm_target_init(void);
int dm_target_uninit(void);
dm_table_t *dm_table_get_entry(dm_table_head_t *, uint8_t);
void dm_table_release(dm_table_head_t *, uint8_t s);
void dm_table_switch_tables(dm_table_head_t *);
int dm_table_destroy(dm_table_head_t *, uint8_t);
uint64_t dm_table_size(dm_table_head_t *);
uint64_t dm_inactive_table_size(dm_table_head_t *);
int dm_table_get_target_count(dm_table_head_t *, uint8_t);
void dm_table_head_init(dm_table_head_t *);
void dm_table_head_destroy(dm_table_head_t *);
void dm_table_init_target(dm_table_entry_t *table_en, void *cfg);
int dm_table_add_deps(dm_table_entry_t *table_en, dm_pdev_t *pdev);
void dm_table_free_deps(dm_table_entry_t *table_en);
dm_dev_t* dm_dev_lookup(const char *, const char *, int);
int dm_dev_insert(dm_dev_t *);
#if 0
dm_dev_t* dm_dev_lookup_evict(const char *, const char *, int);
#endif
int dm_dev_create(dm_dev_t **, const char *, const char *, int);
int dm_dev_remove(dm_dev_t *);
int dm_dev_remove_all(int);
void dm_dev_busy(dm_dev_t *);
void dm_dev_unbusy(dm_dev_t *);
prop_array_t dm_dev_prop_list(void);
int dm_dev_init(void);
int dm_dev_uninit(void);
off_t dm_pdev_correct_dump_offset(dm_pdev_t *, off_t);
dm_pdev_t* dm_pdev_insert(const char *);
int dm_pdev_decr(dm_pdev_t *);
uint64_t dm_pdev_get_udev(dm_pdev_t *);
int dm_pdev_get_vattr(dm_pdev_t *, struct vattr *);
int dm_pdev_init(void);
int dm_pdev_uninit(void);
#define dmdebug(format, ...) \
do { if (dm_debug_level) kprintf("%s: "format, __func__, ## __VA_ARGS__); } while(0)
#define DM_TARGET_MODULE(name, evh) \
static moduledata_t name##_mod = { \
#name, \
evh, \
NULL \
}; \
DECLARE_MODULE(name, name##_mod, SI_SUB_DM_TARGETS, \
SI_ORDER_ANY); \
MODULE_DEPEND(name, dm, 1, 1, 1)
#define DM_TARGET_BUILTIN(name, evh) \
SYSINIT(name##module, SI_SUB_DM_TARGETS, SI_ORDER_ANY, \
dm_builtin_init, evh); \
SYSUNINIT(name##module, SI_SUB_DM_TARGETS, SI_ORDER_ANY, \
dm_builtin_uninit, evh)
#endif
#endif