#ifndef _SYS_DEVFS_H_
#define _SYS_DEVFS_H_
#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
#ifndef _SYS_TYPES_H_
#include <sys/types.h>
#endif
#ifndef _SYS_QUEUE_H_
#include <sys/queue.h>
#endif
#ifdef _KERNEL
#ifndef _SYS_LOCK_H_
#include <sys/lock.h>
#endif
#ifndef _SYS_CONF_H_
#include <sys/conf.h>
#endif
#ifndef _SYS_MSGPORT_H_
#include <sys/msgport.h>
#endif
#endif
#ifndef _SYS_DIRENT_H_
#include <sys/dirent.h>
#endif
#ifndef _SYS_DEVICE_H_
#include <sys/device.h>
#endif
#ifdef _KERNEL
#ifndef _SYS_UCRED_H_
#include <sys/ucred.h>
#endif
#endif
typedef enum {
Nroot,
Nlink,
Nreg,
Ndir,
Ndev
} devfs_nodetype;
struct devfs_dirent {
ino_t d_ino;
uint16_t d_namlen;
uint8_t d_type;
char *d_name;
};
struct devfs_fid {
uint16_t fid_len;
uint16_t fid_pad;
uint32_t fid_gen;
ino_t fid_ino;
};
struct devfs_node {
cdev_t d_dev;
struct mount *mp;
struct devfs_dirent d_dir;
struct vnode *v_node;
struct devfs_node *parent;
devfs_nodetype node_type;
u_int64_t refs;
size_t nchildren;
u_int64_t cookie_jar;
u_int64_t cookie;
struct devfs_node *link_target;
size_t nlinks;
char *symlink_name;
size_t symlink_namelen;
u_short mode;
uid_t uid;
gid_t gid;
u_long flags;
struct timespec atime;
struct timespec mtime;
struct timespec ctime;
TAILQ_ENTRY(devfs_node) link;
TAILQ_HEAD(, devfs_node) list;
};
#ifdef _KERNEL
struct devfs_orphan {
struct devfs_node *node;
TAILQ_ENTRY(devfs_orphan) link;
};
struct devfs_mnt_data {
TAILQ_HEAD(, devfs_orphan) orphan_list;
TAILQ_ENTRY(devfs_mnt_data) link;
struct devfs_node *root_node;
struct mount *mp;
uint32_t mnt_type;
long leak_count;
long file_count;
int jailed;
size_t mntonnamelen;
};
struct devfs_clone_handler {
char *name;
u_char namlen;
d_clone_t *nhandler;
TAILQ_ENTRY(devfs_clone_handler) link;
};
struct devfs_alias {
char *name;
size_t namlen;
cdev_t dev_target;
TAILQ_ENTRY(devfs_alias) link;
};
struct devfs_dev_ops {
struct dev_ops *ops;
int ref_count;
int id;
TAILQ_ENTRY(devfs_dev_ops) link;
};
typedef struct devfs_msg {
struct lwkt_msg hdr;
union {
struct {
cdev_t dev;
uid_t uid;
gid_t gid;
int perms;
} __m_dev;
struct {
struct devfs_mnt_data *mnt;
} __m_mnt;
struct {
const char *name;
d_clone_t *nhandler;
} __m_chandler;
struct {
void *load;
void *load2;
} __m_gen;
struct {
void *resp;
} __m_resp;
struct {
dev_t udev;
} __m_udev;
struct {
cdev_t cdev;
} __m_cdev;
struct {
char *name;
} __m_name;
struct {
char *basename;
u_char unit;
struct vnode *vp;
} __m_clone;
struct {
struct devfs_node *node;
} __m_node;
struct {
char *name;
char *target;
struct mount *mp;
} __m_link;
struct {
struct dev_ops *ops;
int minor;
} __m_ops;
struct {
cdev_t dev;
uint32_t flag;
} __m_flags;
struct {
ino_t ino;
struct vnode *vp;
struct mount *mp;
} __m_ino;
} __m_u;
} *devfs_msg_t;
#define mdv_chandler __m_u.__m_chandler
#define mdv_mnt __m_u.__m_mnt.mnt
#define mdv_load __m_u.__m_gen.load
#define mdv_load2 __m_u.__m_gen.load2
#define mdv_response __m_u.__m_resp.resp
#define mdv_dev __m_u.__m_dev
#define mdv_link __m_u.__m_link
#define mdv_udev __m_u.__m_udev.udev
#define mdv_cdev __m_u.__m_cdev.cdev
#define mdv_name __m_u.__m_name.name
#define mdv_clone __m_u.__m_clone
#define mdv_node __m_u.__m_node.node
#define mdv_ops __m_u.__m_ops
#define mdv_flags __m_u.__m_flags
#define mdv_ino __m_u.__m_ino
typedef struct devfs_core_args {
thread_t td;
} *devfs_core_args_t;
TAILQ_HEAD(devfs_node_head, devfs_node);
TAILQ_HEAD(devfs_dev_head, cdev);
TAILQ_HEAD(devfs_mnt_head, devfs_mnt_data);
TAILQ_HEAD(devfs_chandler_head, devfs_clone_handler);
TAILQ_HEAD(devfs_alias_head, devfs_alias);
TAILQ_HEAD(devfs_dev_ops_head, devfs_dev_ops);
typedef void (devfs_scan_t)(char *, cdev_t, bool, void *);
typedef void* (devfs_iterate_callback_t)(struct devfs_node *, void *);
#define DEVFS_NODE(x) ((struct devfs_node *)((x)->v_data))
#define DEVFS_MNTDATA(x) ((struct devfs_mnt_data *)((x)->mnt_data))
#define DEVFS_ORPHANLIST(x) (&(DEVFS_MNTDATA(x)->orphan_list))
#define DEVFS_DENODE_HEAD(x) (&((x)->list))
#if 0
#define DEVFS_ISDIGIT(x) ((x >= '0') && (x <= '9'))
#endif
#define DEVFS_DEFAULT_MODE ((VREAD|VWRITE|VEXEC) | ((VREAD|VEXEC)>>3) | \
((VREAD|VEXEC)>>6));
#define DEVFS_DEFAULT_UID 0
#define DEVFS_DEFAULT_GID 0
#define DEVFS_DEBUG_SHOW 0x00
#define DEVFS_DEBUG_WARNING 0x01
#define DEVFS_DEBUG_INFO 0x02
#define DEVFS_DEBUG_DEBUG 0x03
#define DEVFS_TERMINATE_CORE 0x01
#define DEVFS_DEVICE_CREATE 0x02
#define DEVFS_DEVICE_DESTROY 0x03
#define DEVFS_MOUNT_ADD 0x04
#define DEVFS_MOUNT_DEL 0x05
#define DEVFS_CREATE_ALL_DEV 0x06
#define DEVFS_DESTROY_RELATED 0x07
#define DEVFS_DESTROY_DEV_BY_OPS 0x08
#define DEVFS_CHANDLER_ADD 0x09
#define DEVFS_CHANDLER_DEL 0x0A
#define DEVFS_FIND_DEVICE_BY_DEVID 0x0B
#define DEVFS_FIND_DEVICE_BY_NAME 0x0C
#define DEVFS_MAKE_ALIAS 0x0D
#define DEVFS_DESTROY_ALIAS 0x0E
#define DEVFS_APPLY_RULES 0x0F
#define DEVFS_RESET_RULES 0x10
#define DEVFS_SCAN_CALLBACK 0x11
#define DEVFS_CLR_RELATED_FLAG 0x12
#define DEVFS_DESTROY_RELATED_WO_FLAG 0x13
#define DEVFS_INODE_TO_VNODE 0x14
#define DEVFS_SYNC 0x99
#define DEVFS_NODE_LINKED 0x001
#define DEVFS_USER_CREATED 0x002
#define DEVFS_ORPHANED 0x004
#define DEVFS_CLONED 0x008
#define DEVFS_HIDDEN 0x010
#define DEVFS_INVISIBLE 0x020
#define DEVFS_PTY 0x040
#define DEVFS_DESTROYED 0x080
#define DEVFS_RULE_CREATED 0x100
#define DEVFS_RULE_HIDDEN 0x200
#define DEVFS_NLINKSWAIT 0x400
#define DEVFS_BITMAP_INITIAL_SIZE 1
#define DEVFS_CLONE_BITMAP(name) devfs_ ## name ## _clone_bitmap
#define DEVFS_DEFINE_CLONE_BITMAP(name) \
struct devfs_bitmap DEVFS_CLONE_BITMAP(name)
#define DEVFS_DECLARE_CLONE_BITMAP(name) \
extern struct devfs_bitmap DEVFS_CLONE_BITMAP(name)
struct devfs_bitmap {
int chunks;
unsigned long *bitmap;
};
#endif
#if 0
struct devfs_unit_hash {
struct devfs_unit_hash *next;
int unit_no;
cdev_t dev;
};
#endif
#ifdef _KERNEL
void devfs_clone_bitmap_init(struct devfs_bitmap *);
void devfs_clone_bitmap_uninit(struct devfs_bitmap *);
int devfs_clone_bitmap_set(struct devfs_bitmap *, int);
int devfs_clone_bitmap_get(struct devfs_bitmap *, int);
int devfs_clone_bitmap_chk(struct devfs_bitmap *, int);
void devfs_clone_bitmap_put(struct devfs_bitmap *, int);
int devfs_debug(int level, char *fmt, ...) __printflike(2, 3);
int devfs_allocv(struct vnode **, struct devfs_node *);
struct devfs_node *devfs_allocp(devfs_nodetype, char *, struct devfs_node *,
struct mount *, cdev_t);
int devfs_allocvp(struct mount *, struct vnode **, devfs_nodetype, char *,
struct devfs_node *, cdev_t);
void devfs_freep(struct devfs_node *);
void devfs_unlinkp(struct devfs_node *);
void devfs_tracer_add_orphan(struct devfs_node *);
void devfs_tracer_del_orphan(struct devfs_node *);
size_t devfs_tracer_orphan_count(struct mount *, int);
int devfs_set_perms(struct devfs_node *, uid_t, gid_t, u_short, u_long);
int devfs_gc(struct devfs_node *);
int devfs_create_dev(cdev_t, uid_t, gid_t, int);
int devfs_destroy_dev(cdev_t);
int devfs_msg_send_sync(uint32_t, devfs_msg_t);
void devfs_msg_send(uint32_t, devfs_msg_t);
void devfs_msg_send_dev(uint32_t, cdev_t dev, uid_t, gid_t, int);
void devfs_msg_send_mount(uint32_t, struct devfs_mnt_data *);
void devfs_msg_send_ops(uint32_t, struct dev_ops *, int);
void devfs_msg_send_chandler(uint32_t, char *, d_clone_t);
void devfs_msg_send_generic(uint32_t, void *);
void devfs_msg_send_name(uint32_t, char *);
void devfs_msg_send_link(uint32_t, char *, char *, struct mount *);
devfs_msg_t devfs_msg_get(void);
int devfs_msg_put(devfs_msg_t);
int devfs_mount_add(struct devfs_mnt_data *);
int devfs_mount_del(struct devfs_mnt_data *);
int devfs_create_all_dev(struct devfs_node *);
struct devfs_node *devfs_resolve_or_create_path(
struct devfs_node *, char *, int);
int devfs_resolve_name_path(char *, char *, char **, char **);
struct devfs_node *devfs_create_device_node(struct devfs_node *, cdev_t, int *,
char *, char *, ...) __printf0like(5, 6);
int devfs_destroy_device_node(struct devfs_node *, cdev_t);
int devfs_destroy_node(struct devfs_node *, char *);
int devfs_destroy_related(cdev_t);
int devfs_destroy_dev_by_ops(struct dev_ops *, int);
struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *);
cdev_t devfs_new_cdev(struct dev_ops *, int, struct dev_ops *);
void devfs_assume_knotes(cdev_t dev, struct kqinfo *kqi);
cdev_t devfs_find_device_by_name(const char *, ...) __printf0like(1, 2);
cdev_t devfs_find_device_by_devid(dev_t);
struct vnode *devfs_inode_to_vnode(struct mount *, ino_t);
int devfs_clone_handler_add(const char *, d_clone_t *);
int devfs_clone_handler_del(const char *);
cdev_t devfs_clone(cdev_t, const char *, size_t, int, struct ucred *);
int devfs_link_dev(cdev_t);
int devfs_make_alias(const char *, cdev_t);
int devfs_destroy_alias(const char *, cdev_t);
int devfs_alias_create(char *, struct devfs_node *, int);
int devfs_apply_rules(char *);
int devfs_reset_rules(char *);
int devfs_scan_callback(devfs_scan_t *, void *);
int devfs_clr_related_flag(cdev_t, uint32_t);
int devfs_destroy_related_without_flag(cdev_t, uint32_t);
int devfs_node_is_accessible(struct devfs_node *);
void devfs_config(void);
void *devfs_iterate_topology(struct devfs_node *node,
devfs_iterate_callback_t *callback, void *arg1);
void *devfs_find_device_node_callback(struct devfs_node *, cdev_t);
typedef void d_priv_dtor_t(void *data);
int devfs_get_cdevpriv(struct file *fp, void **datap);
int devfs_set_cdevpriv(struct file *fp, void *priv, d_priv_dtor_t *dtr);
void devfs_clear_cdevpriv(struct file *fp);
int devfs_WildCmp(const char *w, const char *s);
int devfs_WildCaseCmp(const char *w, const char *s);
#endif
#endif
#define DEVFS_MNT_RULESET 0x01
#define DEVFS_MNT_JAIL 0x02
struct devfs_mount_info {
int flags;
};
#endif