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 } __m_gen; 177 struct { 178 void *resp; 179 } __m_resp; 180 struct { 181 udev_t udev; 182 } __m_udev; 183 struct { 184 cdev_t cdev; 185 } __m_cdev; 186 struct { 187 char *name; 188 } __m_name; 189 struct { 190 char *basename; 191 u_char unit; 192 struct vnode *vp; 193 } __m_clone; 194 struct { 195 struct devfs_node *node; 196 } __m_node; 197 struct { 198 char *name; 199 char *target; 200 struct mount *mp; 201 } __m_link; 202 struct { 203 struct dev_ops *ops; 204 int minor; 205 } __m_ops; 206 struct { 207 char *name; 208 uint32_t flag; 209 } __m_flags; 210 struct { 211 ino_t ino; 212 struct vnode *vp; 213 struct mount *mp; 214 } __m_ino; 215 } __m_u; 216 } *devfs_msg_t; 217 218 #define mdv_chandler __m_u.__m_chandler 219 #define mdv_mnt __m_u.__m_mnt.mnt 220 #define mdv_load __m_u.__m_gen.load 221 #define mdv_response __m_u.__m_resp.resp 222 #define mdv_dev __m_u.__m_dev 223 #define mdv_link __m_u.__m_link 224 #define mdv_udev __m_u.__m_udev.udev 225 #define mdv_cdev __m_u.__m_cdev.cdev 226 #define mdv_name __m_u.__m_name.name 227 #define mdv_clone __m_u.__m_clone 228 #define mdv_node __m_u.__m_node.node 229 #define mdv_ops __m_u.__m_ops 230 #define mdv_flags __m_u.__m_flags 231 #define mdv_ino __m_u.__m_ino 232 233 234 typedef struct devfs_core_args { 235 thread_t td; 236 } *devfs_core_args_t; 237 238 TAILQ_HEAD(devfs_node_head, devfs_node); 239 TAILQ_HEAD(devfs_dev_head, cdev); 240 TAILQ_HEAD(devfs_mnt_head, devfs_mnt_data); 241 TAILQ_HEAD(devfs_chandler_head, devfs_clone_handler); 242 TAILQ_HEAD(devfs_alias_head, devfs_alias); 243 TAILQ_HEAD(devfs_dev_ops_head, devfs_dev_ops); 244 245 typedef void (devfs_scan_t)(cdev_t); 246 typedef void* (devfs_iterate_callback_t)(struct devfs_node *, void *); 247 248 #define DEVFS_NODE(x) ((struct devfs_node *)((x)->v_data)) 249 #define DEVFS_MNTDATA(x) ((struct devfs_mnt_data *)((x)->mnt_data)) 250 #define DEVFS_ORPHANLIST(x) (&(DEVFS_MNTDATA(x)->orphan_list)) 251 #define DEVFS_DENODE_HEAD(x) (&((x)->list)) 252 #define DEVFS_ISDIGIT(x) ((x >= '0') && (x <= '9')) 253 254 /* 255 * -rwxr-xr-x 256 */ 257 #define DEVFS_DEFAULT_MODE ((VREAD|VWRITE|VEXEC) | ((VREAD|VEXEC)>>3) | \ 258 ((VREAD|VEXEC)>>6)); 259 260 #define DEVFS_DEFAULT_UID 0 /* root */ 261 #define DEVFS_DEFAULT_GID 0 /* wheel */ 262 263 /* 264 * debug levels 265 */ 266 #define DEVFS_DEBUG_SHOW 0x00 267 #define DEVFS_DEBUG_WARNING 0x01 268 #define DEVFS_DEBUG_INFO 0x02 269 #define DEVFS_DEBUG_DEBUG 0x03 270 271 /* 272 * Message ids 273 */ 274 #define DEVFS_TERMINATE_CORE 0x01 275 #define DEVFS_DEVICE_CREATE 0x02 276 #define DEVFS_DEVICE_DESTROY 0x03 277 #define DEVFS_MOUNT_ADD 0x04 278 #define DEVFS_MOUNT_DEL 0x05 279 #define DEVFS_CREATE_ALL_DEV 0x06 280 #define DEVFS_DESTROY_SUBNAMES 0x07 281 #define DEVFS_DESTROY_DEV_BY_OPS 0x08 282 #define DEVFS_CHANDLER_ADD 0x09 283 #define DEVFS_CHANDLER_DEL 0x0A 284 #define DEVFS_FIND_DEVICE_BY_UDEV 0x0B 285 #define DEVFS_FIND_DEVICE_BY_NAME 0x0C 286 #define DEVFS_MAKE_ALIAS 0x0D 287 #define DEVFS_APPLY_RULES 0x0F 288 #define DEVFS_RESET_RULES 0x10 289 #define DEVFS_SCAN_CALLBACK 0x11 290 #define DEVFS_CLR_SUBNAMES_FLAG 0x12 291 #define DEVFS_DESTROY_SUBNAMES_WO_FLAG 0x13 292 #define DEVFS_INODE_TO_VNODE 0x14 293 #define DEVFS_SYNC 0x99 294 295 /* 296 * Node flags 297 * 298 * HIDDEN Makes node inaccessible, apart from already allocated vnodes 299 * INVISIBLE Makes node invisible in a readdir() 300 */ 301 #define DEVFS_NODE_LINKED 0x001 /* Linked into topology */ 302 #define DEVFS_USER_CREATED 0x002 /* Node was user-created */ 303 #define DEVFS_ORPHANED 0x004 /* on orphan list */ 304 #define DEVFS_CLONED 0x008 /* Created by cloning code */ 305 #define DEVFS_HIDDEN 0x010 /* Makes node inaccessible */ 306 #define DEVFS_INVISIBLE 0x020 /* Makes node invisible */ 307 #define DEVFS_PTY 0x040 /* PTY device */ 308 #define DEVFS_DESTROYED 0x080 /* Sanity check */ 309 #define DEVFS_RULE_CREATED 0x100 /* Node was rule-created */ 310 #define DEVFS_RULE_HIDDEN 0x200 /* Node was hidden by a rule */ 311 312 /* 313 * Clone helper stuff 314 */ 315 #define DEVFS_BITMAP_INITIAL_SIZE 1 316 #define DEVFS_CLONE_BITMAP(name) devfs_ ## name ## _clone_bitmap 317 #define DEVFS_DECLARE_CLONE_BITMAP(name) \ 318 struct devfs_bitmap DEVFS_CLONE_BITMAP(name) 319 #define devfs_clone_bitmap_put devfs_clone_bitmap_rst 320 321 struct devfs_bitmap { 322 int chunks; 323 unsigned long *bitmap; 324 }; 325 326 struct devfs_unit_hash { 327 struct devfs_unit_hash *next; 328 int unit_no; 329 cdev_t dev; 330 }; 331 332 void devfs_clone_bitmap_init(struct devfs_bitmap *); 333 void devfs_clone_bitmap_uninit(struct devfs_bitmap *); 334 void devfs_clone_bitmap_resize(struct devfs_bitmap *, int); 335 int devfs_clone_bitmap_fff(struct devfs_bitmap *); 336 void devfs_clone_bitmap_set(struct devfs_bitmap *, int); 337 void devfs_clone_bitmap_rst(struct devfs_bitmap *, int); 338 int devfs_clone_bitmap_get(struct devfs_bitmap *, int); 339 int devfs_clone_bitmap_chk(struct devfs_bitmap *, int); 340 341 /* 342 * Prototypes 343 */ 344 int devfs_debug(int level, char *fmt, ...); 345 int devfs_allocv(struct vnode **, struct devfs_node *); 346 struct devfs_node *devfs_allocp(devfs_nodetype, char *, struct devfs_node *, 347 struct mount *, cdev_t); 348 int devfs_allocvp(struct mount *, struct vnode **, devfs_nodetype, char *, 349 struct devfs_node *, cdev_t); 350 351 int devfs_freep(struct devfs_node *); 352 353 int devfs_unlinkp(struct devfs_node *); 354 355 void devfs_tracer_add_orphan(struct devfs_node *); 356 void devfs_tracer_del_orphan(struct devfs_node *); 357 size_t devfs_tracer_orphan_count(struct mount *, int); 358 359 int devfs_set_perms(struct devfs_node *, uid_t, gid_t, u_short, u_long); 360 int devfs_gc(struct devfs_node *); 361 362 int devfs_create_dev(cdev_t, uid_t, gid_t, int); 363 int devfs_destroy_dev(cdev_t); 364 365 devfs_msg_t devfs_msg_send_sync(uint32_t, devfs_msg_t); 366 void devfs_msg_send(uint32_t, devfs_msg_t); 367 void devfs_msg_send_dev(uint32_t, cdev_t dev, uid_t, gid_t, int); 368 void devfs_msg_send_mount(uint32_t, struct devfs_mnt_data *); 369 void devfs_msg_send_ops(uint32_t, struct dev_ops *, int); 370 void devfs_msg_send_chandler(uint32_t, char *, d_clone_t); 371 void devfs_msg_send_generic(uint32_t, void *); 372 void devfs_msg_send_name(uint32_t, char *); 373 void devfs_msg_send_link(uint32_t, char *, char *, struct mount *); 374 375 devfs_msg_t devfs_msg_get(void); 376 int devfs_msg_put(devfs_msg_t); 377 378 int devfs_mount_add(struct devfs_mnt_data *); 379 int devfs_mount_del(struct devfs_mnt_data *); 380 381 int devfs_create_all_dev(struct devfs_node *); 382 383 struct devfs_node *devfs_resolve_or_create_path( 384 struct devfs_node *, char *, int); 385 int devfs_resolve_name_path(char *, char *, char **, char **); 386 struct devfs_node *devfs_create_device_node(struct devfs_node *, cdev_t, 387 char *, char *, ...); 388 389 int devfs_destroy_device_node(struct devfs_node *, cdev_t); 390 int devfs_destroy_subnames(char *); 391 int devfs_destroy_dev_by_ops(struct dev_ops *, int); 392 struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *); 393 394 cdev_t devfs_new_cdev(struct dev_ops *, int, struct dev_ops *); 395 396 cdev_t devfs_find_device_by_name(const char *, ...); 397 cdev_t devfs_find_device_by_udev(udev_t); 398 399 struct vnode *devfs_inode_to_vnode(struct mount *, ino_t); 400 401 int devfs_clone_handler_add(const char *, d_clone_t *); 402 int devfs_clone_handler_del(const char *); 403 cdev_t devfs_clone(cdev_t, const char *, size_t, int, struct ucred *); 404 405 int devfs_link_dev(cdev_t); 406 407 int devfs_make_alias(const char *, cdev_t); 408 409 int devfs_alias_create(char *, struct devfs_node *, int); 410 411 int devfs_apply_rules(char *); 412 int devfs_reset_rules(char *); 413 414 int devfs_scan_callback(devfs_scan_t *); 415 416 int devfs_clr_subnames_flag(char *, uint32_t); 417 int devfs_destroy_subnames_without_flag(char *, uint32_t); 418 int devfs_node_is_accessible(struct devfs_node *); 419 420 int devfs_reference_ops(struct dev_ops *); 421 void devfs_release_ops(struct dev_ops *); 422 423 void devfs_config(void); 424 425 void *devfs_iterate_topology(struct devfs_node *node, 426 devfs_iterate_callback_t *callback, void *arg1); 427 428 void *devfs_find_device_node_callback(struct devfs_node *, cdev_t); 429 430 #endif /* KERNEL */ 431 432 #define DEVFS_MNT_RULESET 0x01 433 #define DEVFS_MNT_JAIL 0x02 434 435 struct devfs_mount_info { 436 int flags; 437 }; 438 439 #endif /* _SYS_DEVFS_H_ */ 440