1 /* 2 * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Alex Hornung <ahornung@gmail.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 #ifndef _SYS_DEVFS_H_ 35 #define _SYS_DEVFS_H_ 36 37 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) 38 39 #ifndef _SYS_QUEUE_H_ 40 #include <sys/queue.h> 41 #endif 42 #ifndef _SYS_LOCK_H_ 43 #include <sys/lock.h> 44 #endif 45 #ifndef _SYS_CONF_H_ 46 #include <sys/conf.h> 47 #endif 48 #ifndef _SYS_MSGPORT_H_ 49 #include <sys/msgport.h> 50 #endif 51 #ifndef _SYS_DIRENT_H_ 52 #include <sys/dirent.h> 53 #endif 54 #ifndef _SYS_DEVICE_H_ 55 #include <sys/device.h> 56 #endif 57 #ifndef _SYS_UCRED_H_ 58 #include <sys/ucred.h> 59 #endif 60 61 62 typedef enum { 63 Proot, /* the filesystem root */ 64 Plink, 65 Preg, 66 Pdir, 67 Pdev 68 } devfs_nodetype; 69 70 struct devfs_dirent { 71 ino_t d_ino; /* file number of entry */ 72 uint16_t d_namlen; /* strlen(d_name) */ 73 uint8_t d_type; /* file type */ 74 char *d_name; 75 }; 76 77 struct devfs_fid { 78 uint16_t fid_len; /* Length of structure. */ 79 uint16_t fid_pad; /* Force 32-bit alignment. */ 80 uint32_t fid_gen; 81 ino_t fid_ino; /* File number (ino). */ 82 }; 83 84 struct devfs_node { 85 cdev_t d_dev; /* device assoicated with this node */ 86 87 struct mount *mp; /* mount point of this node */ 88 struct devfs_dirent d_dir; /* dirent data (name, inode, ...) */ 89 struct vnode *v_node; /* assoicated vnode */ 90 struct devfs_node *parent; /* parent of this node */ 91 devfs_nodetype node_type; /* devfs node type */ 92 93 u_int64_t refs; /* number of open references */ 94 size_t nchildren; /* number of children of a parent */ 95 u_int64_t cookie_jar; /* cookie pool for children */ 96 u_int64_t cookie; /* directory entry cookie for readdir */ 97 98 struct devfs_node *link_target; /* target of this autolink-type node */ 99 size_t nlinks; /* hard links */ 100 101 char *symlink_name; /* symlink name for readlink */ 102 size_t symlink_namelen; /* symlink name length for readlink */ 103 104 u_short mode; /* files access mode and type */ 105 uid_t uid; /* owner user id */ 106 gid_t gid; /* owner group id */ 107 u_long flags; 108 109 struct timespec atime; /* time of last access */ 110 struct timespec mtime; /* time of last modification */ 111 struct timespec ctime; /* time file changed */ 112 113 TAILQ_ENTRY(devfs_node) link; 114 TAILQ_HEAD(, devfs_node) list; /* linked list of children */ 115 }; 116 117 struct devfs_orphan { 118 struct devfs_node *node; 119 TAILQ_ENTRY(devfs_orphan) link; 120 }; 121 122 struct devfs_mnt_data { 123 TAILQ_HEAD(, devfs_orphan) orphan_list; 124 TAILQ_ENTRY(devfs_mnt_data) link; 125 126 struct devfs_node *root_node; 127 struct mount *mp; 128 uint32_t mnt_type; 129 long leak_count; 130 long file_count; 131 int jailed; 132 size_t mntonnamelen; 133 }; 134 135 struct devfs_clone_handler { 136 char *name; 137 u_char namlen; 138 d_clone_t *nhandler; 139 TAILQ_ENTRY(devfs_clone_handler) link; 140 }; 141 142 143 struct devfs_alias { 144 char *name; 145 size_t namlen; 146 cdev_t dev_target; 147 TAILQ_ENTRY(devfs_alias) link; 148 }; 149 150 struct devfs_dev_ops { 151 struct dev_ops *ops; 152 int ref_count; 153 int id; 154 TAILQ_ENTRY(devfs_dev_ops) link; 155 }; 156 157 typedef struct devfs_msg { 158 struct lwkt_msg hdr; 159 160 union { 161 struct { 162 cdev_t dev; 163 uid_t uid; 164 gid_t gid; 165 int perms; 166 } __m_dev; 167 struct { 168 struct devfs_mnt_data *mnt; 169 } __m_mnt; 170 struct { 171 const char *name; 172 d_clone_t *nhandler; 173 } __m_chandler; 174 struct { 175 void *load; 176 void *load2; 177 } __m_gen; 178 struct { 179 void *resp; 180 } __m_resp; 181 struct { 182 udev_t udev; 183 } __m_udev; 184 struct { 185 cdev_t cdev; 186 } __m_cdev; 187 struct { 188 char *name; 189 } __m_name; 190 struct { 191 char *basename; 192 u_char unit; 193 struct vnode *vp; 194 } __m_clone; 195 struct { 196 struct devfs_node *node; 197 } __m_node; 198 struct { 199 char *name; 200 char *target; 201 struct mount *mp; 202 } __m_link; 203 struct { 204 struct dev_ops *ops; 205 int minor; 206 } __m_ops; 207 struct { 208 cdev_t dev; 209 uint32_t flag; 210 } __m_flags; 211 struct { 212 ino_t ino; 213 struct vnode *vp; 214 struct mount *mp; 215 } __m_ino; 216 } __m_u; 217 } *devfs_msg_t; 218 219 #define mdv_chandler __m_u.__m_chandler 220 #define mdv_mnt __m_u.__m_mnt.mnt 221 #define mdv_load __m_u.__m_gen.load 222 #define mdv_load2 __m_u.__m_gen.load2 223 #define mdv_response __m_u.__m_resp.resp 224 #define mdv_dev __m_u.__m_dev 225 #define mdv_link __m_u.__m_link 226 #define mdv_udev __m_u.__m_udev.udev 227 #define mdv_cdev __m_u.__m_cdev.cdev 228 #define mdv_name __m_u.__m_name.name 229 #define mdv_clone __m_u.__m_clone 230 #define mdv_node __m_u.__m_node.node 231 #define mdv_ops __m_u.__m_ops 232 #define mdv_flags __m_u.__m_flags 233 #define mdv_ino __m_u.__m_ino 234 235 236 typedef struct devfs_core_args { 237 thread_t td; 238 } *devfs_core_args_t; 239 240 TAILQ_HEAD(devfs_node_head, devfs_node); 241 TAILQ_HEAD(devfs_dev_head, cdev); 242 TAILQ_HEAD(devfs_mnt_head, devfs_mnt_data); 243 TAILQ_HEAD(devfs_chandler_head, devfs_clone_handler); 244 TAILQ_HEAD(devfs_alias_head, devfs_alias); 245 TAILQ_HEAD(devfs_dev_ops_head, devfs_dev_ops); 246 247 typedef void (devfs_scan_t)(cdev_t, void *); 248 typedef void* (devfs_iterate_callback_t)(struct devfs_node *, void *); 249 250 #define DEVFS_NODE(x) ((struct devfs_node *)((x)->v_data)) 251 #define DEVFS_MNTDATA(x) ((struct devfs_mnt_data *)((x)->mnt_data)) 252 #define DEVFS_ORPHANLIST(x) (&(DEVFS_MNTDATA(x)->orphan_list)) 253 #define DEVFS_DENODE_HEAD(x) (&((x)->list)) 254 #define DEVFS_ISDIGIT(x) ((x >= '0') && (x <= '9')) 255 256 /* 257 * -rwxr-xr-x 258 */ 259 #define DEVFS_DEFAULT_MODE ((VREAD|VWRITE|VEXEC) | ((VREAD|VEXEC)>>3) | \ 260 ((VREAD|VEXEC)>>6)); 261 262 #define DEVFS_DEFAULT_UID 0 /* root */ 263 #define DEVFS_DEFAULT_GID 0 /* wheel */ 264 265 /* 266 * debug levels 267 */ 268 #define DEVFS_DEBUG_SHOW 0x00 269 #define DEVFS_DEBUG_WARNING 0x01 270 #define DEVFS_DEBUG_INFO 0x02 271 #define DEVFS_DEBUG_DEBUG 0x03 272 273 /* 274 * Message ids 275 */ 276 #define DEVFS_TERMINATE_CORE 0x01 277 #define DEVFS_DEVICE_CREATE 0x02 278 #define DEVFS_DEVICE_DESTROY 0x03 279 #define DEVFS_MOUNT_ADD 0x04 280 #define DEVFS_MOUNT_DEL 0x05 281 #define DEVFS_CREATE_ALL_DEV 0x06 282 #define DEVFS_DESTROY_RELATED 0x07 283 #define DEVFS_DESTROY_DEV_BY_OPS 0x08 284 #define DEVFS_CHANDLER_ADD 0x09 285 #define DEVFS_CHANDLER_DEL 0x0A 286 #define DEVFS_FIND_DEVICE_BY_UDEV 0x0B 287 #define DEVFS_FIND_DEVICE_BY_NAME 0x0C 288 #define DEVFS_MAKE_ALIAS 0x0D 289 #define DEVFS_DESTROY_ALIAS 0x0E 290 #define DEVFS_APPLY_RULES 0x0F 291 #define DEVFS_RESET_RULES 0x10 292 #define DEVFS_SCAN_CALLBACK 0x11 293 #define DEVFS_CLR_RELATED_FLAG 0x12 294 #define DEVFS_DESTROY_RELATED_WO_FLAG 0x13 295 #define DEVFS_INODE_TO_VNODE 0x14 296 #define DEVFS_SYNC 0x99 297 298 /* 299 * Node flags 300 * 301 * HIDDEN Makes node inaccessible, apart from already allocated vnodes 302 * INVISIBLE Makes node invisible in a readdir() 303 */ 304 #define DEVFS_NODE_LINKED 0x001 /* Linked into topology */ 305 #define DEVFS_USER_CREATED 0x002 /* Node was user-created */ 306 #define DEVFS_ORPHANED 0x004 /* on orphan list */ 307 #define DEVFS_CLONED 0x008 /* Created by cloning code */ 308 #define DEVFS_HIDDEN 0x010 /* Makes node inaccessible */ 309 #define DEVFS_INVISIBLE 0x020 /* Makes node invisible */ 310 #define DEVFS_PTY 0x040 /* PTY device */ 311 #define DEVFS_DESTROYED 0x080 /* Sanity check */ 312 #define DEVFS_RULE_CREATED 0x100 /* Node was rule-created */ 313 #define DEVFS_RULE_HIDDEN 0x200 /* Node was hidden by a rule */ 314 315 /* 316 * Clone helper stuff 317 */ 318 #define DEVFS_BITMAP_INITIAL_SIZE 1 319 #define DEVFS_CLONE_BITMAP(name) devfs_ ## name ## _clone_bitmap 320 #define DEVFS_DECLARE_CLONE_BITMAP(name) \ 321 struct devfs_bitmap DEVFS_CLONE_BITMAP(name) 322 323 struct devfs_bitmap { 324 int chunks; 325 unsigned long *bitmap; 326 }; 327 328 struct devfs_unit_hash { 329 struct devfs_unit_hash *next; 330 int unit_no; 331 cdev_t dev; 332 }; 333 334 void devfs_clone_bitmap_init(struct devfs_bitmap *); 335 void devfs_clone_bitmap_uninit(struct devfs_bitmap *); 336 void devfs_clone_bitmap_resize(struct devfs_bitmap *, int); 337 int devfs_clone_bitmap_fff(struct devfs_bitmap *); 338 void devfs_clone_bitmap_set(struct devfs_bitmap *, int); 339 int devfs_clone_bitmap_get(struct devfs_bitmap *, int); 340 int devfs_clone_bitmap_chk(struct devfs_bitmap *, int); 341 void devfs_clone_bitmap_put(struct devfs_bitmap *, int); 342 343 /* 344 * Prototypes 345 */ 346 int devfs_debug(int level, char *fmt, ...) __printflike(2, 3); 347 int devfs_allocv(struct vnode **, struct devfs_node *); 348 struct devfs_node *devfs_allocp(devfs_nodetype, char *, struct devfs_node *, 349 struct mount *, cdev_t); 350 int devfs_allocvp(struct mount *, struct vnode **, devfs_nodetype, char *, 351 struct devfs_node *, cdev_t); 352 353 int devfs_freep(struct devfs_node *); 354 355 int devfs_unlinkp(struct devfs_node *); 356 357 void devfs_tracer_add_orphan(struct devfs_node *); 358 void devfs_tracer_del_orphan(struct devfs_node *); 359 size_t devfs_tracer_orphan_count(struct mount *, int); 360 361 int devfs_set_perms(struct devfs_node *, uid_t, gid_t, u_short, u_long); 362 int devfs_gc(struct devfs_node *); 363 364 int devfs_create_dev(cdev_t, uid_t, gid_t, int); 365 int devfs_destroy_dev(cdev_t); 366 367 devfs_msg_t devfs_msg_send_sync(uint32_t, devfs_msg_t); 368 void devfs_msg_send(uint32_t, devfs_msg_t); 369 void devfs_msg_send_dev(uint32_t, cdev_t dev, uid_t, gid_t, int); 370 void devfs_msg_send_mount(uint32_t, struct devfs_mnt_data *); 371 void devfs_msg_send_ops(uint32_t, struct dev_ops *, int); 372 void devfs_msg_send_chandler(uint32_t, char *, d_clone_t); 373 void devfs_msg_send_generic(uint32_t, void *); 374 void devfs_msg_send_name(uint32_t, char *); 375 void devfs_msg_send_link(uint32_t, char *, char *, struct mount *); 376 377 devfs_msg_t devfs_msg_get(void); 378 int devfs_msg_put(devfs_msg_t); 379 380 int devfs_mount_add(struct devfs_mnt_data *); 381 int devfs_mount_del(struct devfs_mnt_data *); 382 383 int devfs_create_all_dev(struct devfs_node *); 384 385 struct devfs_node *devfs_resolve_or_create_path( 386 struct devfs_node *, char *, int); 387 int devfs_resolve_name_path(char *, char *, char **, char **); 388 struct devfs_node *devfs_create_device_node(struct devfs_node *, cdev_t, 389 char *, char *, ...) __printf0like(4, 5); 390 391 int devfs_destroy_device_node(struct devfs_node *, cdev_t); 392 int devfs_destroy_node(struct devfs_node *, char *); 393 int devfs_destroy_related(cdev_t); 394 int devfs_destroy_dev_by_ops(struct dev_ops *, int); 395 struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *); 396 397 cdev_t devfs_new_cdev(struct dev_ops *, int, struct dev_ops *); 398 void devfs_assume_knotes(cdev_t dev, struct kqinfo *kqi); 399 400 cdev_t devfs_find_device_by_name(const char *, ...) __printflike(1, 2); 401 cdev_t devfs_find_device_by_udev(udev_t); 402 403 struct vnode *devfs_inode_to_vnode(struct mount *, ino_t); 404 405 int devfs_clone_handler_add(const char *, d_clone_t *); 406 int devfs_clone_handler_del(const char *); 407 cdev_t devfs_clone(cdev_t, const char *, size_t, int, struct ucred *); 408 409 int devfs_link_dev(cdev_t); 410 411 int devfs_make_alias(const char *, cdev_t); 412 int devfs_destroy_alias(const char *, cdev_t); 413 414 int devfs_alias_create(char *, struct devfs_node *, int); 415 416 int devfs_apply_rules(char *); 417 int devfs_reset_rules(char *); 418 419 int devfs_scan_callback(devfs_scan_t *, void *); 420 421 int devfs_clr_related_flag(cdev_t, uint32_t); 422 int devfs_destroy_related_without_flag(cdev_t, uint32_t); 423 int devfs_node_is_accessible(struct devfs_node *); 424 425 int devfs_reference_ops(struct dev_ops *); 426 void devfs_release_ops(struct dev_ops *); 427 428 void devfs_config(void); 429 430 void *devfs_iterate_topology(struct devfs_node *node, 431 devfs_iterate_callback_t *callback, void *arg1); 432 433 void *devfs_find_device_node_callback(struct devfs_node *, cdev_t); 434 435 436 int devfs_WildCmp(const char *w, const char *s); 437 int devfs_WildCaseCmp(const char *w, const char *s); 438 439 #endif /* KERNEL */ 440 441 #define DEVFS_MNT_RULESET 0x01 442 #define DEVFS_MNT_JAIL 0x02 443 444 struct devfs_mount_info { 445 int flags; 446 }; 447 448 #endif /* _SYS_DEVFS_H_ */ 449