2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Alex Hornung <ahornung@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/mount.h>
38 #include <sys/vnode.h>
39 #include <sys/types.h>
41 #include <sys/msgport.h>
42 #include <sys/msgport2.h>
43 #include <sys/spinlock2.h>
44 #include <sys/sysctl.h>
45 #include <sys/ucred.h>
46 #include <sys/param.h>
47 #include <sys/sysref2.h>
48 #include <vfs/devfs/devfs.h>
49 #include <vfs/devfs/devfs_rules.h>
51 MALLOC_DEFINE(M_DEVFS
, "devfs", "Device File System (devfs) allocations");
54 * SYSREF Integration - reference counting, allocation,
55 * sysid and syslink integration.
57 static void devfs_cdev_terminate(cdev_t dev
);
58 static struct sysref_class cdev_sysref_class
= {
61 .proto
= SYSREF_PROTO_DEV
,
62 .offset
= offsetof(struct cdev
, si_sysref
),
63 .objsize
= sizeof(struct cdev
),
67 .terminate
= (sysref_terminate_func_t
)devfs_cdev_terminate
71 static struct objcache
*devfs_node_cache
;
72 static struct objcache
*devfs_msg_cache
;
73 static struct objcache
*devfs_dev_cache
;
75 static struct objcache_malloc_args devfs_node_malloc_args
= {
76 sizeof(struct devfs_node
), M_DEVFS
};
77 struct objcache_malloc_args devfs_msg_malloc_args
= {
78 sizeof(struct devfs_msg
), M_DEVFS
};
79 struct objcache_malloc_args devfs_dev_malloc_args
= {
80 sizeof(struct cdev
), M_DEVFS
};
82 static struct devfs_dev_head devfs_dev_list
= TAILQ_HEAD_INITIALIZER(devfs_dev_list
);
83 static struct devfs_mnt_head devfs_mnt_list
= TAILQ_HEAD_INITIALIZER(devfs_mnt_list
);
84 static struct devfs_chandler_head devfs_chandler_list
= TAILQ_HEAD_INITIALIZER(devfs_chandler_list
);
85 static struct devfs_alias_head devfs_alias_list
= TAILQ_HEAD_INITIALIZER(devfs_alias_list
);
87 struct lock devfs_lock
;
88 static struct lwkt_port devfs_dispose_port
;
89 static struct lwkt_port devfs_msg_port
;
90 static struct thread
*td_core
;
92 static ino_t d_ino
= 0;
93 static __uint32_t msg_id
= 0;
94 static struct spinlock ino_lock
;
95 static int devfs_debug_enable
= 0;
97 static ino_t
devfs_fetch_ino(void);
98 static int devfs_gc_dirs(struct devfs_node
*);
99 static int devfs_gc_links(struct devfs_node
*, struct devfs_node
*, size_t);
100 static int devfs_create_all_dev_worker(struct devfs_node
*);
101 static int devfs_create_dev_worker(cdev_t
, uid_t
, gid_t
, int);
102 static int devfs_destroy_dev_worker(cdev_t
);
103 static int devfs_destroy_subnames_worker(char *);
104 static int devfs_destroy_dev_by_ops_worker(struct dev_ops
*, int);
105 static int devfs_propagate_dev(cdev_t
, int);
106 static int devfs_unlink_dev(cdev_t dev
);
108 static int devfs_chandler_add_worker(char *, d_clone_t
*);
109 static int devfs_chandler_del_worker(char *);
111 static void devfs_msg_autofree_reply(lwkt_port_t
, lwkt_msg_t
);
112 static void devfs_msg_core(void *);
114 static int devfs_find_device_by_name_worker(devfs_msg_t
);
115 static int devfs_find_device_by_udev_worker(devfs_msg_t
);
117 static int devfs_apply_reset_rules_caller(char *, int);
118 static int devfs_apply_reset_rules_worker(struct devfs_node
*, int);
120 static int devfs_scan_callback_worker(devfs_scan_t
*);
122 static struct devfs_node
*devfs_resolve_or_create_dir(struct devfs_node
*, char *, size_t, int);
124 static int devfs_make_alias_worker(struct devfs_alias
*);
125 static int devfs_alias_remove(cdev_t
);
126 static int devfs_alias_reap(void);
127 static int devfs_alias_propagate(struct devfs_alias
*);
128 static int devfs_alias_apply(struct devfs_node
*, struct devfs_alias
*);
129 static int devfs_alias_check_create(struct devfs_node
*);
131 static int devfs_clr_subnames_flag_worker(char *, uint32_t);
132 static int devfs_destroy_subnames_without_flag_worker(char *, uint32_t);
135 * devfs_debug() is a SYSCTL and TUNABLE controlled debug output function using kvprintf
138 devfs_debug(int level
, char *fmt
, ...)
143 if (level
<= devfs_debug_enable
)
151 * devfs_allocp() Allocates a new devfs node with the specified
152 * parameters. The node is also automatically linked into the topology
153 * if a parent is specified. It also calls the rule and alias stuff to
154 * be applied on the new node
157 devfs_allocp(devfs_nodetype devfsnodetype
, char *name
,
158 struct devfs_node
*parent
, struct mount
*mp
, cdev_t dev
)
160 struct devfs_node
*node
= NULL
;
161 size_t namlen
= strlen(name
);
162 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocp -1- for %s\n", name
?name
:"NULL");
164 node
= objcache_get(devfs_node_cache
, M_WAITOK
);
166 bzero(node
, sizeof(*node
));
168 atomic_add_int(&(DEVFS_MNTDATA(mp
)->leak_count
), 1);
173 node
->d_dir
.d_ino
= devfs_fetch_ino();
174 node
->cookie_jar
= 2; /* Leave 0 and 1 for '.' and '..', respectively */
176 /* Access Control members */
177 node
->mode
= DEVFS_DEFAULT_MODE
; /* files access mode and type */
178 node
->uid
= DEVFS_DEFAULT_UID
; /* owner user id */
179 node
->gid
= DEVFS_DEFAULT_GID
; /* owner group id */
181 switch (devfsnodetype
) {
183 /* Ensure that we don't recycle the root vnode */
184 node
->flags
|= DEVFS_NODE_LINKED
;
186 TAILQ_INIT(DEVFS_DENODE_HEAD(node
));
187 node
->d_dir
.d_type
= DT_DIR
;
192 node
->d_dir
.d_type
= DT_LNK
;
196 node
->d_dir
.d_type
= DT_REG
;
201 node
->d_dir
.d_type
= DT_CHR
;
203 node
->d_dir
.d_ino
= dev
->si_inode
;
205 node
->mode
= dev
->si_perms
; /* files access mode and type */
206 node
->uid
= dev
->si_uid
; /* owner user id */
207 node
->gid
= dev
->si_gid
; /* owner group id */
209 devfs_alias_check_create(node
);
214 panic("devfs_allocp: unknown node type");
218 node
->node_type
= devfsnodetype
;
220 /* Init the dirent structure of each devfs vnode */
221 KKASSERT(namlen
< 256);
223 node
->d_dir
.d_namlen
= namlen
;
224 node
->d_dir
.d_name
= kmalloc(namlen
+1, M_DEVFS
, M_WAITOK
);
225 memcpy(node
->d_dir
.d_name
, name
, namlen
);
226 node
->d_dir
.d_name
[namlen
] = '\0';
228 /* Initialize the parent node element */
229 node
->parent
= parent
;
232 devfs_rule_check_apply(node
);
235 nanotime(&node
->atime
);
236 node
->mtime
= node
->ctime
= node
->atime
;
239 * Associate with parent as last step, clean out namecache
242 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocp: about to insert node\n");
243 if ((parent
!= NULL
) &&
244 ((parent
->node_type
== Proot
) || (parent
->node_type
== Pdir
))) {
245 devfs_debug(DEVFS_DEBUG_DEBUG
,
246 "devfs_allocp: node inserted %p\n",
249 node
->cookie
= parent
->cookie_jar
++;
250 node
->flags
|= DEVFS_NODE_LINKED
;
251 TAILQ_INSERT_TAIL(DEVFS_DENODE_HEAD(parent
), node
, link
);
253 /* This forces negative namecache lookups to clear */
254 ++mp
->mnt_namecache_gen
;
257 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocp -end:2-\n");
262 * devfs_allocv() allocates a new vnode based on a devfs node.
265 devfs_allocv(struct vnode
**vpp
, struct devfs_node
*node
)
272 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -1-\n");
275 while ((vp
= node
->v_node
) != NULL
) {
276 error
= vget(vp
, LK_EXCLUSIVE
);
277 if (error
!= ENOENT
) {
279 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv, code path 2...\n");
283 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -3-\n");
285 if ((error
= getnewvnode(VT_DEVFS
, node
->mp
, vpp
, 0, 0)) != 0)
290 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -4-\n");
292 if (node
->v_node
!= NULL
) {
300 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -5-\n");
302 switch (node
->node_type
) {
319 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -6-\n");
320 KKASSERT(node
->d_dev
);
323 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -7-\n");
324 vp
->v_uminor
= node
->d_dev
->si_uminor
;
326 vp
->v_rdev
= node
->d_dev
;
327 vp
->v_ops
= &node
->mp
->mnt_vn_spec_ops
;
328 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -8-\n");
330 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv: type is Pdev but d_dev is not set!!!!\n");
332 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -9-\n");
336 panic("devfs_allocv: unknown node type");
340 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -10-\n");
341 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocv -end:11-\n");
346 * devfs_allocvp allocates both a devfs node (with the given settings) and a vnode
347 * based on the newly created devfs node.
350 devfs_allocvp(struct mount
*mp
, struct vnode
**vpp
, devfs_nodetype devfsnodetype
,
351 char *name
, struct devfs_node
*parent
, cdev_t dev
)
353 struct devfs_node
*node
;
355 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocvp -1-\n");
356 node
= devfs_allocp(devfsnodetype
, name
, parent
, mp
, dev
);
357 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocvp -2-\n");
359 devfs_allocv(vpp
, node
);
363 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_allocvp -end:3-\n");
369 * Destroy the devfs_node. The node must be unlinked from the topology.
371 * This function will also destroy any vnode association with the node
374 * The cdev_t itself remains intact.
377 devfs_freep(struct devfs_node
*node
)
382 KKASSERT(((node
->flags
& DEVFS_NODE_LINKED
) == 0) ||
383 (node
->node_type
== Proot
));
384 KKASSERT((node
->flags
& DEVFS_DESTROYED
) == 0);
386 atomic_subtract_int(&(DEVFS_MNTDATA(node
->mp
)->leak_count
), 1);
387 if (node
->symlink_name
) {
388 kfree(node
->symlink_name
, M_DEVFS
);
389 node
->symlink_name
= NULL
;
393 * Remove the node from the orphan list if it is still on it.
395 if (node
->flags
& DEVFS_ORPHANED
)
396 devfs_tracer_del_orphan(node
);
399 * Disassociate the vnode from the node. This also prevents the
400 * vnode's reclaim code from double-freeing the node.
402 if ((vp
= node
->v_node
) != NULL
) {
407 if (node
->d_dir
.d_name
)
408 kfree(node
->d_dir
.d_name
, M_DEVFS
);
409 node
->flags
|= DEVFS_DESTROYED
;
411 objcache_put(devfs_node_cache
, node
);
417 * Unlink the devfs node from the topology and add it to the orphan list.
418 * The node will later be destroyed by freep.
420 * Any vnode association, including the v_rdev and v_data, remains intact
424 devfs_unlinkp(struct devfs_node
*node
)
426 struct devfs_node
*parent
;
429 devfs_tracer_add_orphan(node
);
430 devfs_debug(DEVFS_DEBUG_DEBUG
,
431 "devfs_unlinkp for %s\n", node
->d_dir
.d_name
);
432 parent
= node
->parent
;
435 * If the parent is known we can unlink the node out of the topology
438 TAILQ_REMOVE(DEVFS_DENODE_HEAD(parent
), node
, link
);
440 KKASSERT((parent
->nchildren
>= 0));
441 node
->flags
&= ~DEVFS_NODE_LINKED
;
448 * devfs_reaperp() is a recursive function that iterates through all the
449 * topology, unlinking and freeing all devfs nodes.
452 devfs_reaperp(struct devfs_node
*node
)
454 struct devfs_node
*node1
, *node2
;
456 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
457 devfs_debug(DEVFS_DEBUG_DEBUG
,
458 "This node is Pdir or Proot; has %d children\n",
460 if (node
->nchildren
> 2) {
461 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
),
463 devfs_reaperp(node1
);
474 * devfs_gc() is devfs garbage collector. It takes care of unlinking and
475 * freeing a node, but also removes empty directories and links that link
476 * via devfs auto-link mechanism to the node being deleted.
479 devfs_gc(struct devfs_node
*node
)
481 struct devfs_node
*root_node
= DEVFS_MNTDATA(node
->mp
)->root_node
;
483 devfs_gc_links(root_node
, node
, node
->nlinks
);
485 devfs_gc_dirs(root_node
);
493 * devfs_gc_dirs() is a helper function for devfs_gc, unlinking and freeing
497 devfs_gc_dirs(struct devfs_node
*node
)
499 struct devfs_node
*node1
, *node2
;
501 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
502 devfs_debug(DEVFS_DEBUG_DEBUG
,
503 "This node is Pdir or Proot; has %d children\n",
505 if (node
->nchildren
> 2) {
506 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
),
508 devfs_gc_dirs(node1
);
512 if (node
->nchildren
== 2) {
513 devfs_debug(DEVFS_DEBUG_DEBUG
,
514 "This node is called %s and it is empty\n",
525 * devfs_gc_links() is a helper function for devfs_gc, unlinking and freeing
526 * eauto-linked nodes linking to the node being deleted.
529 devfs_gc_links(struct devfs_node
*node
, struct devfs_node
*target
,
532 struct devfs_node
*node1
, *node2
;
535 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
536 devfs_debug(DEVFS_DEBUG_DEBUG
, "This node is Pdir or Proot; has %d children\n", node
->nchildren
);
537 if (node
->nchildren
> 2) {
538 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
539 nlinks
= devfs_gc_links(node1
, target
, nlinks
);
542 } else if (node
->link_target
== target
) {
549 KKASSERT(nlinks
>= 0);
555 * devfs_create_dev() is the asynchronous entry point for device creation.
556 * It just sends a message with the relevant details to the devfs core.
558 * This function will reference the passed device. The reference is owned
559 * by devfs and represents all of the device's node associations.
562 devfs_create_dev(cdev_t dev
, uid_t uid
, gid_t gid
, int perms
)
565 devfs_debug(DEVFS_DEBUG_DEBUG
,
566 "devfs_create_dev -1-, name: %s (%p)\n",
569 id
= devfs_msg_send_dev(DEVFS_DEVICE_CREATE
, dev
, uid
, gid
, perms
);
570 devfs_debug(DEVFS_DEBUG_DEBUG
,
571 "devfs_create_dev -end:2- (unique id: %x) / (%p)\n",
577 * devfs_destroy_dev() is the asynchronous entry point for device destruction.
578 * It just sends a message with the relevant details to the devfs core.
581 devfs_destroy_dev(cdev_t dev
)
583 devfs_msg_send_dev(DEVFS_DEVICE_DESTROY
, dev
, 0, 0, 0);
588 * devfs_mount_add() is the synchronous entry point for adding a new devfs
589 * mount. It sends a synchronous message with the relevant details to the
593 devfs_mount_add(struct devfs_mnt_data
*mnt
)
597 msg
= devfs_msg_get();
599 msg
= devfs_msg_send_sync(DEVFS_MOUNT_ADD
, msg
);
606 * devfs_mount_del() is the synchronous entry point for removing a devfs mount.
607 * It sends a synchronous message with the relevant details to the devfs core.
610 devfs_mount_del(struct devfs_mnt_data
*mnt
)
614 msg
= devfs_msg_get();
616 msg
= devfs_msg_send_sync(DEVFS_MOUNT_DEL
, msg
);
623 * devfs_destroy_subnames() is the synchronous entry point for device destruction
624 * by subname. It just sends a message with the relevant details to the devfs core.
627 devfs_destroy_subnames(char *name
)
631 msg
= devfs_msg_get();
632 msg
->mdv_load
= name
;
633 msg
= devfs_msg_send_sync(DEVFS_DESTROY_SUBNAMES
, msg
);
639 devfs_clr_subnames_flag(char *name
, uint32_t flag
)
643 msg
= devfs_msg_get();
644 msg
->mdv_flags
.name
= name
;
645 msg
->mdv_flags
.flag
= flag
;
646 msg
= devfs_msg_send_sync(DEVFS_CLR_SUBNAMES_FLAG
, msg
);
653 devfs_destroy_subnames_without_flag(char *name
, uint32_t flag
)
657 msg
= devfs_msg_get();
658 msg
->mdv_flags
.name
= name
;
659 msg
->mdv_flags
.flag
= flag
;
660 msg
= devfs_msg_send_sync(DEVFS_DESTROY_SUBNAMES_WO_FLAG
, msg
);
667 * devfs_create_all_dev is the asynchronous entry point to trigger device
668 * node creation. It just sends a message with the relevant details to
672 devfs_create_all_dev(struct devfs_node
*root
)
674 devfs_msg_send_generic(DEVFS_CREATE_ALL_DEV
, root
);
679 * devfs_destroy_dev_by_ops is the asynchronous entry point to destroy all
680 * devices with a specific set of dev_ops and minor. It just sends a
681 * message with the relevant details to the devfs core.
684 devfs_destroy_dev_by_ops(struct dev_ops
*ops
, int minor
)
686 devfs_msg_send_ops(DEVFS_DESTROY_DEV_BY_OPS
, ops
, minor
);
691 * devfs_clone_handler_add is the synchronous entry point to add a new
692 * clone handler. It just sends a message with the relevant details to
696 devfs_clone_handler_add(char *name
, d_clone_t
*nhandler
)
700 msg
= devfs_msg_get();
701 msg
->mdv_chandler
.name
= name
;
702 msg
->mdv_chandler
.nhandler
= nhandler
;
703 msg
= devfs_msg_send_sync(DEVFS_CHANDLER_ADD
, msg
);
709 * devfs_clone_handler_del is the synchronous entry point to remove a
710 * clone handler. It just sends a message with the relevant details to
714 devfs_clone_handler_del(char *name
)
718 msg
= devfs_msg_get();
719 msg
->mdv_chandler
.name
= name
;
720 msg
->mdv_chandler
.nhandler
= NULL
;
721 msg
= devfs_msg_send_sync(DEVFS_CHANDLER_DEL
, msg
);
727 * devfs_find_device_by_name is the synchronous entry point to find a
728 * device given its name. It sends a synchronous message with the
729 * relevant details to the devfs core and returns the answer.
732 devfs_find_device_by_name(const char *fmt
, ...)
736 char target
[PATH_MAX
+1];
745 i
= kvcprintf(fmt
, NULL
, target
, 10, ap
);
750 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_find_device_by_name: %s -1-\n", target
);
751 msg
= devfs_msg_get();
752 msg
->mdv_name
= target
;
753 msg
= devfs_msg_send_sync(DEVFS_FIND_DEVICE_BY_NAME
, msg
);
754 found
= msg
->mdv_cdev
;
757 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_find_device_by_name found? %s -end:2-\n", (found
)?"YES":"NO");
762 * devfs_find_device_by_udev is the synchronous entry point to find a
763 * device given its udev number. It sends a synchronous message with
764 * the relevant details to the devfs core and returns the answer.
767 devfs_find_device_by_udev(udev_t udev
)
772 msg
= devfs_msg_get();
773 msg
->mdv_udev
= udev
;
774 msg
= devfs_msg_send_sync(DEVFS_FIND_DEVICE_BY_UDEV
, msg
);
775 found
= msg
->mdv_cdev
;
778 devfs_debug(DEVFS_DEBUG_DEBUG
,
779 "devfs_find_device_by_udev found? %s -end:3-\n",
780 ((found
) ? found
->si_name
:"NO"));
785 * devfs_make_alias is the asynchronous entry point to register an alias
786 * for a device. It just sends a message with the relevant details to the
790 devfs_make_alias(char *name
, cdev_t dev_target
)
792 struct devfs_alias
*alias
;
794 alias
= kmalloc(sizeof(struct devfs_alias
), M_DEVFS
, M_WAITOK
);
795 memcpy(alias
->name
, name
, strlen(name
) + 1);
796 alias
->dev_target
= dev_target
;
798 devfs_msg_send_generic(DEVFS_MAKE_ALIAS
, alias
);
803 * devfs_apply_rules is the asynchronous entry point to trigger application
804 * of all rules. It just sends a message with the relevant details to the
808 devfs_apply_rules(char *mntto
)
813 namelen
= strlen(mntto
) + 1;
815 new_name
= kmalloc(namelen
, M_DEVFS
, M_WAITOK
);
817 memcpy(new_name
, mntto
, namelen
);
819 devfs_msg_send_name(DEVFS_APPLY_RULES
, new_name
);
824 * devfs_reset_rules is the asynchronous entry point to trigger reset of all rules.
825 * It just sends a message with the relevant details to the devfs core.
828 devfs_reset_rules(char *mntto
)
833 namelen
= strlen(mntto
) + 1;
835 new_name
= kmalloc(namelen
, M_DEVFS
, M_WAITOK
);
837 memcpy(new_name
, mntto
, namelen
);
839 devfs_msg_send_name(DEVFS_RESET_RULES
, new_name
);
845 * devfs_scan_callback is the asynchronous entry point to call a callback
847 * It just sends a message with the relevant details to the devfs core.
850 devfs_scan_callback(devfs_scan_t
*callback
)
854 /* Make sure that function pointers have the size of a generic pointer (innecessary) */
855 KKASSERT(sizeof(callback
) == sizeof(void *));
857 msg
= devfs_msg_get();
858 msg
->mdv_load
= callback
;
859 msg
= devfs_msg_send_sync(DEVFS_SCAN_CALLBACK
, msg
);
867 * Acts as a message drain. Any message that is replied to here gets destroyed and
871 devfs_msg_autofree_reply(lwkt_port_t port
, lwkt_msg_t msg
)
873 devfs_msg_put((devfs_msg_t
)msg
);
877 * devfs_msg_get allocates a new devfs msg and returns it.
882 return objcache_get(devfs_msg_cache
, M_WAITOK
);
886 * devfs_msg_put deallocates a given devfs msg.
889 devfs_msg_put(devfs_msg_t msg
)
891 objcache_put(devfs_msg_cache
, msg
);
896 * devfs_msg_send is the generic asynchronous message sending facility
897 * for devfs. By default the reply port is the automatic disposal port.
900 devfs_msg_send(uint32_t cmd
, devfs_msg_t devfs_msg
)
902 lwkt_port_t port
= &devfs_msg_port
;
904 lwkt_initmsg(&devfs_msg
->hdr
, &devfs_dispose_port
, 0);
906 devfs_msg
->hdr
.u
.ms_result
= cmd
;
907 devfs_msg
->id
= atomic_fetchadd_int(&msg_id
, 1);
909 lwkt_sendmsg(port
, (lwkt_msg_t
)devfs_msg
);
911 return devfs_msg
->id
;
915 * devfs_msg_send_sync is the generic synchronous message sending
916 * facility for devfs. It initializes a local reply port and waits
917 * for the core's answer. This answer is then returned.
920 devfs_msg_send_sync(uint32_t cmd
, devfs_msg_t devfs_msg
)
922 struct lwkt_port rep_port
;
923 devfs_msg_t msg_incoming
;
924 lwkt_port_t port
= &devfs_msg_port
;
926 lwkt_initport_thread(&rep_port
, curthread
);
927 lwkt_initmsg(&devfs_msg
->hdr
, &rep_port
, 0);
929 devfs_msg
->hdr
.u
.ms_result
= cmd
;
930 devfs_msg
->id
= atomic_fetchadd_int(&msg_id
, 1);
932 lwkt_sendmsg(port
, (lwkt_msg_t
)devfs_msg
);
933 msg_incoming
= lwkt_waitport(&rep_port
, 0);
939 * sends a message with a generic argument.
942 devfs_msg_send_generic(uint32_t cmd
, void *load
)
944 devfs_msg_t devfs_msg
= devfs_msg_get();
945 devfs_msg
->mdv_load
= load
;
947 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_send_generic -1- (%p)\n", load
);
949 return devfs_msg_send(cmd
, devfs_msg
);
953 * sends a message with a name argument.
956 devfs_msg_send_name(uint32_t cmd
, char *name
)
958 devfs_msg_t devfs_msg
= devfs_msg_get();
959 devfs_msg
->mdv_name
= name
;
961 return devfs_msg_send(cmd
, devfs_msg
);
965 * sends a message with a mount argument.
968 devfs_msg_send_mount(uint32_t cmd
, struct devfs_mnt_data
*mnt
)
970 devfs_msg_t devfs_msg
= devfs_msg_get();
971 devfs_msg
->mdv_mnt
= mnt
;
973 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_send_mp -1- (%p)\n", mnt
);
975 return devfs_msg_send(cmd
, devfs_msg
);
979 * sends a message with an ops argument.
982 devfs_msg_send_ops(uint32_t cmd
, struct dev_ops
*ops
, int minor
)
984 devfs_msg_t devfs_msg
= devfs_msg_get();
985 devfs_msg
->mdv_ops
.ops
= ops
;
986 devfs_msg
->mdv_ops
.minor
= minor
;
988 return devfs_msg_send(cmd
, devfs_msg
);
992 * sends a message with a clone handler argument.
995 devfs_msg_send_chandler(uint32_t cmd
, char *name
, d_clone_t handler
)
997 devfs_msg_t devfs_msg
= devfs_msg_get();
998 devfs_msg
->mdv_chandler
.name
= name
;
999 devfs_msg
->mdv_chandler
.nhandler
= handler
;
1001 return devfs_msg_send(cmd
, devfs_msg
);
1005 * sends a message with a device argument.
1008 devfs_msg_send_dev(uint32_t cmd
, cdev_t dev
, uid_t uid
, gid_t gid
, int perms
)
1010 devfs_msg_t devfs_msg
= devfs_msg_get();
1011 devfs_msg
->mdv_dev
.dev
= dev
;
1012 devfs_msg
->mdv_dev
.uid
= uid
;
1013 devfs_msg
->mdv_dev
.gid
= gid
;
1014 devfs_msg
->mdv_dev
.perms
= perms
;
1016 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_send_dev -1- (%p)\n", dev
);
1018 return devfs_msg_send(cmd
, devfs_msg
);
1022 * sends a message with a link argument.
1025 devfs_msg_send_link(uint32_t cmd
, char *name
, char *target
, struct mount
*mp
)
1027 devfs_msg_t devfs_msg
= devfs_msg_get();
1028 devfs_msg
->mdv_link
.name
= name
;
1029 devfs_msg
->mdv_link
.target
= target
;
1030 devfs_msg
->mdv_link
.mp
= mp
;
1033 return devfs_msg_send(cmd
, devfs_msg
);
1037 * devfs_msg_core is the main devfs thread. It handles all incoming messages
1038 * and calls the relevant worker functions. By using messages it's assured
1039 * that events occur in the correct order.
1042 devfs_msg_core(void *arg
)
1047 struct devfs_mnt_data
*mnt
;
1048 struct devfs_node
*node
;
1050 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_core -1-\n");
1051 lwkt_initport_thread(&devfs_msg_port
, curthread
);
1052 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_core -2-\n");
1053 wakeup(td_core
/*devfs_id*/);
1054 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_core -3-\n");
1057 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_core -loop:4-\n");
1058 msg
= (devfs_msg_t
)lwkt_waitport(&devfs_msg_port
, 0);
1059 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_core, new msg: %x (unique id: %x)\n", (unsigned int)msg
->hdr
.u
.ms_result
, msg
->id
);
1060 lockmgr(&devfs_lock
, LK_EXCLUSIVE
);
1061 switch (msg
->hdr
.u
.ms_result
) {
1063 case DEVFS_DEVICE_CREATE
:
1064 dev
= msg
->mdv_dev
.dev
;
1065 devfs_debug(DEVFS_DEBUG_DEBUG
,
1066 "devfs_msg_core device create msg %s(%p)\n",
1068 devfs_create_dev_worker(dev
,
1071 msg
->mdv_dev
.perms
);
1074 case DEVFS_DEVICE_DESTROY
:
1075 devfs_debug(DEVFS_DEBUG_DEBUG
,
1076 "devfs_msg_core device destroy msg\n");
1077 dev
= msg
->mdv_dev
.dev
;
1078 devfs_destroy_dev_worker(dev
);
1081 case DEVFS_DESTROY_SUBNAMES
:
1082 devfs_destroy_subnames_worker(msg
->mdv_load
);
1085 case DEVFS_DESTROY_DEV_BY_OPS
:
1086 devfs_destroy_dev_by_ops_worker(msg
->mdv_ops
.ops
,
1087 msg
->mdv_ops
.minor
);
1090 case DEVFS_CREATE_ALL_DEV
:
1091 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_msg_core device create ALL msg\n");
1092 node
= (struct devfs_node
*)msg
->mdv_load
;
1093 devfs_create_all_dev_worker(node
);
1096 case DEVFS_MOUNT_ADD
:
1098 TAILQ_INSERT_TAIL(&devfs_mnt_list
, mnt
, link
);
1099 devfs_create_all_dev_worker(mnt
->root_node
);
1102 case DEVFS_MOUNT_DEL
:
1104 TAILQ_REMOVE(&devfs_mnt_list
, mnt
, link
);
1105 devfs_reaperp(mnt
->root_node
);
1106 if (mnt
->leak_count
) {
1107 devfs_debug(DEVFS_DEBUG_SHOW
,
1108 "Leaked %d devfs_node elements!\n",
1113 case DEVFS_CHANDLER_ADD
:
1114 devfs_chandler_add_worker(msg
->mdv_chandler
.name
, msg
->mdv_chandler
.nhandler
);
1117 case DEVFS_CHANDLER_DEL
:
1118 devfs_chandler_del_worker(msg
->mdv_chandler
.name
);
1121 case DEVFS_FIND_DEVICE_BY_NAME
:
1122 devfs_find_device_by_name_worker(msg
);
1125 case DEVFS_FIND_DEVICE_BY_UDEV
:
1126 devfs_find_device_by_udev_worker(msg
);
1129 case DEVFS_MAKE_ALIAS
:
1130 devfs_make_alias_worker((struct devfs_alias
*)msg
->mdv_load
);
1133 case DEVFS_APPLY_RULES
:
1134 devfs_apply_reset_rules_caller(msg
->mdv_name
, 1);
1137 case DEVFS_RESET_RULES
:
1138 devfs_apply_reset_rules_caller(msg
->mdv_name
, 0);
1141 case DEVFS_SCAN_CALLBACK
:
1142 devfs_scan_callback_worker((devfs_scan_t
*)msg
->mdv_load
);
1145 case DEVFS_CLR_SUBNAMES_FLAG
:
1146 devfs_clr_subnames_flag_worker(msg
->mdv_flags
.name
,
1147 msg
->mdv_flags
.flag
);
1150 case DEVFS_DESTROY_SUBNAMES_WO_FLAG
:
1151 devfs_destroy_subnames_without_flag_worker(msg
->mdv_flags
.name
,
1152 msg
->mdv_flags
.flag
);
1155 case DEVFS_TERMINATE_CORE
:
1161 devfs_debug(DEVFS_DEBUG_DEBUG
,
1162 "devfs_msg_core: unknown message "
1163 "received at core\n");
1166 lockmgr(&devfs_lock
, LK_RELEASE
);
1168 lwkt_replymsg((lwkt_msg_t
)msg
, 0);
1170 wakeup(td_core
/*devfs_id*/);
1175 * Worker function to insert a new dev into the dev list and initialize its
1176 * permissions. It also calls devfs_propagate_dev which in turn propagates
1177 * the change to all mount points.
1179 * The passed dev is already referenced. This reference is eaten by this
1180 * function and represents the dev's linkage into devfs_dev_list.
1183 devfs_create_dev_worker(cdev_t dev
, uid_t uid
, gid_t gid
, int perms
)
1186 devfs_debug(DEVFS_DEBUG_DEBUG
,
1187 "devfs_create_dev_worker -1- -%s- (%p)\n",
1192 dev
->si_perms
= perms
;
1194 devfs_link_dev(dev
);
1195 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_dev_worker -2-\n");
1196 devfs_propagate_dev(dev
, 1);
1198 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_dev_worker -end:3-\n");
1203 * Worker function to delete a dev from the dev list and free the cdev.
1204 * It also calls devfs_propagate_dev which in turn propagates the change
1205 * to all mount points.
1208 devfs_destroy_dev_worker(cdev_t dev
)
1213 KKASSERT((lockstatus(&devfs_lock
, curthread
)) == LK_EXCLUSIVE
);
1215 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_destroy_dev_worker -1- %s\n", dev
->si_name
);
1216 error
= devfs_unlink_dev(dev
);
1217 devfs_propagate_dev(dev
, 0);
1219 release_dev(dev
); /* link ref */
1223 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_destroy_dev_worker -end:5-\n");
1228 * Worker function to destroy all devices with a certain basename.
1229 * Calls devfs_destroy_dev_worker for the actual destruction.
1232 devfs_destroy_subnames_worker(char *name
)
1235 size_t len
= strlen(name
);
1237 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1238 if (!strncmp(dev
->si_name
, name
, len
)) {
1239 if (dev
->si_name
[len
] != '\0') {
1240 devfs_destroy_dev_worker(dev
);
1241 /* release_dev(dev); */
1249 devfs_clr_subnames_flag_worker(char *name
, uint32_t flag
)
1252 size_t len
= strlen(name
);
1254 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1255 if (!strncmp(dev
->si_name
, name
, len
)) {
1256 if (dev
->si_name
[len
] != '\0') {
1257 dev
->si_flags
&= ~flag
;
1266 devfs_destroy_subnames_without_flag_worker(char *name
, uint32_t flag
)
1269 size_t len
= strlen(name
);
1271 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1272 if (!strncmp(dev
->si_name
, name
, len
)) {
1273 if (dev
->si_name
[len
] != '\0') {
1274 if (!(dev
->si_flags
& flag
)) {
1275 devfs_destroy_dev_worker(dev
);
1285 * Worker function that creates all device nodes on top of a devfs
1289 devfs_create_all_dev_worker(struct devfs_node
*root
)
1294 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_all_dev_worker -1-\n");
1296 TAILQ_FOREACH(dev
, &devfs_dev_list
, link
) {
1297 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_all_dev_worker -loop:2- -%s-\n", dev
->si_name
);
1298 devfs_create_device_node(root
, dev
, NULL
, NULL
);
1300 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_all_dev_worker -end:3-\n");
1305 * Worker function that destroys all devices that match a specific
1306 * dev_ops and/or minor. If minor is less than 0, it is not matched
1307 * against. It also propagates all changes.
1310 devfs_destroy_dev_by_ops_worker(struct dev_ops
*ops
, int minor
)
1315 devfs_debug(DEVFS_DEBUG_DEBUG
,
1316 "devfs_destroy_dev_by_ops_worker -1-\n");
1318 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1319 if (dev
->si_ops
!= ops
)
1321 if ((minor
< 0) || (dev
->si_uminor
== minor
)) {
1322 devfs_debug(DEVFS_DEBUG_DEBUG
,
1323 "devfs_destroy_dev_by_ops_worker "
1326 devfs_destroy_dev_worker(dev
);
1329 devfs_debug(DEVFS_DEBUG_DEBUG
,
1330 "devfs_destroy_dev_by_ops_worker -end:3-\n");
1335 * Worker function that registers a new clone handler in devfs.
1338 devfs_chandler_add_worker(char *name
, d_clone_t
*nhandler
)
1340 struct devfs_clone_handler
*chandler
= NULL
;
1341 u_char len
= strlen(name
);
1346 TAILQ_FOREACH(chandler
, &devfs_chandler_list
, link
) {
1347 if (chandler
->namlen
== len
) {
1348 if (!memcmp(chandler
->name
, name
, len
)) {
1349 /* Clonable basename already exists */
1355 chandler
= kmalloc(sizeof(*chandler
), M_DEVFS
, M_WAITOK
| M_ZERO
);
1356 memcpy(chandler
->name
, name
, len
+1);
1357 chandler
->namlen
= len
;
1358 chandler
->nhandler
= nhandler
;
1360 TAILQ_INSERT_TAIL(&devfs_chandler_list
, chandler
, link
);
1365 * Worker function that removes a given clone handler from the
1366 * clone handler list.
1369 devfs_chandler_del_worker(char *name
)
1371 struct devfs_clone_handler
*chandler
, *chandler2
;
1372 u_char len
= strlen(name
);
1377 TAILQ_FOREACH_MUTABLE(chandler
, &devfs_chandler_list
, link
, chandler2
) {
1378 if (chandler
->namlen
!= len
)
1380 if (memcmp(chandler
->name
, name
, len
))
1382 TAILQ_REMOVE(&devfs_chandler_list
, chandler
, link
);
1383 kfree(chandler
, M_DEVFS
);
1390 * Worker function that finds a given device name and changes
1391 * the message received accordingly so that when replied to,
1392 * the answer is returned to the caller.
1395 devfs_find_device_by_name_worker(devfs_msg_t devfs_msg
)
1398 cdev_t found
= NULL
;
1400 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1401 if (!strcmp(devfs_msg
->mdv_name
, dev
->si_name
)) {
1406 devfs_msg
->mdv_cdev
= found
;
1412 * Worker function that finds a given device udev and changes
1413 * the message received accordingly so that when replied to,
1414 * the answer is returned to the caller.
1417 devfs_find_device_by_udev_worker(devfs_msg_t devfs_msg
)
1420 cdev_t found
= NULL
;
1422 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1423 if (((udev_t
)dev
->si_inode
) == devfs_msg
->mdv_udev
) {
1428 devfs_msg
->mdv_cdev
= found
;
1434 * Worker function that inserts a given alias into the
1435 * alias list, and propagates the alias to all mount
1439 devfs_make_alias_worker(struct devfs_alias
*alias
)
1441 struct devfs_alias
*alias2
;
1442 size_t len
= strlen(alias
->name
);
1445 TAILQ_FOREACH(alias2
, &devfs_alias_list
, link
) {
1446 if (!memcmp(alias
->name
, alias2
->name
, len
)) {
1453 TAILQ_INSERT_TAIL(&devfs_alias_list
, alias
, link
);
1454 devfs_alias_propagate(alias
);
1456 devfs_debug(DEVFS_DEBUG_DEBUG
,
1457 "Warning: duplicate devfs_make_alias for %s\n",
1459 kfree(alias
, M_DEVFS
);
1466 * Function that removes and frees all aliases.
1469 devfs_alias_reap(void)
1471 struct devfs_alias
*alias
, *alias2
;
1473 TAILQ_FOREACH_MUTABLE(alias
, &devfs_alias_list
, link
, alias2
) {
1474 TAILQ_REMOVE(&devfs_alias_list
, alias
, link
);
1475 kfree(alias
, M_DEVFS
);
1481 * Function that removes an alias matching a specific cdev and frees
1485 devfs_alias_remove(cdev_t dev
)
1487 struct devfs_alias
*alias
, *alias2
;
1489 TAILQ_FOREACH_MUTABLE(alias
, &devfs_alias_list
, link
, alias2
) {
1490 if (alias
->dev_target
== dev
) {
1491 TAILQ_REMOVE(&devfs_alias_list
, alias
, link
);
1492 kfree(alias
, M_DEVFS
);
1499 * This function propagates a new alias to all mount points.
1502 devfs_alias_propagate(struct devfs_alias
*alias
)
1504 struct devfs_mnt_data
*mnt
;
1506 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1507 devfs_alias_apply(mnt
->root_node
, alias
);
1513 * This function is a recursive function iterating through
1514 * all device nodes in the topology and, if applicable,
1515 * creating the relevant alias for a device node.
1518 devfs_alias_apply(struct devfs_node
*node
, struct devfs_alias
*alias
)
1520 struct devfs_node
*node1
, *node2
;
1522 KKASSERT(alias
!= NULL
);
1524 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1525 devfs_debug(DEVFS_DEBUG_DEBUG
, "This node is Pdir or Proot; has %d children\n", node
->nchildren
);
1526 if (node
->nchildren
> 2) {
1527 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1528 devfs_alias_apply(node1
, alias
);
1532 if (node
->d_dev
== alias
->dev_target
)
1533 devfs_alias_create(alias
->name
, node
);
1539 * This function checks if any alias possibly is applicable
1540 * to the given node. If so, the alias is created.
1543 devfs_alias_check_create(struct devfs_node
*node
)
1545 struct devfs_alias
*alias
;
1547 TAILQ_FOREACH(alias
, &devfs_alias_list
, link
) {
1548 if (node
->d_dev
== alias
->dev_target
)
1549 devfs_alias_create(alias
->name
, node
);
1555 * This function creates an alias with a given name
1556 * linking to a given devfs node. It also increments
1557 * the link count on the target node.
1560 devfs_alias_create(char *name_orig
, struct devfs_node
*target
)
1562 struct mount
*mp
= target
->mp
;
1563 struct devfs_node
*parent
= DEVFS_MNTDATA(mp
)->root_node
;
1564 struct devfs_node
*linknode
;
1565 char *create_path
= NULL
;
1566 char *name
, name_buf
[PATH_MAX
];
1568 KKASSERT((lockstatus(&devfs_lock
, curthread
)) == LK_EXCLUSIVE
);
1570 devfs_resolve_name_path(name_orig
, name_buf
, &create_path
, &name
);
1573 parent
= devfs_resolve_or_create_path(parent
, create_path
, 1);
1576 if (devfs_find_device_node_by_name(parent
, name
)) {
1577 devfs_debug(DEVFS_DEBUG_DEBUG
,
1578 "Node already exists: %s "
1579 "(devfs_make_alias_worker)!\n",
1585 linknode
= devfs_allocp(Plink
, name
, parent
, mp
, NULL
);
1586 if (linknode
== NULL
)
1589 linknode
->link_target
= target
;
1592 linknode
->flags
|= DEVFS_LINK
;
1599 * This function is called by the core and handles mount point
1600 * strings. It either calls the relevant worker (devfs_apply_
1601 * reset_rules_worker) on all mountpoints or only a specific
1605 devfs_apply_reset_rules_caller(char *mountto
, int apply
)
1607 struct devfs_mnt_data
*mnt
;
1608 size_t len
= strlen(mountto
);
1610 if (mountto
[0] != '*') {
1611 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1612 if ((len
== mnt
->mntonnamelen
) &&
1613 (!memcmp(mnt
->mp
->mnt_stat
.f_mntonname
, mountto
, len
))) {
1614 devfs_apply_reset_rules_worker(mnt
->root_node
, apply
);
1619 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1620 devfs_apply_reset_rules_worker(mnt
->root_node
, apply
);
1624 kfree(mountto
, M_DEVFS
);
1629 * This worker function applies or resets, depending on the arguments, a rule
1630 * to the whole given topology. *RECURSIVE*
1633 devfs_apply_reset_rules_worker(struct devfs_node
*node
, int apply
)
1635 struct devfs_node
*node1
, *node2
;
1637 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1638 devfs_debug(DEVFS_DEBUG_DEBUG
, "This node is Pdir or Proot; has %d children\n", node
->nchildren
);
1639 if (node
->nchildren
> 2) {
1640 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1641 devfs_apply_reset_rules_worker(node1
, apply
);
1647 devfs_rule_check_apply(node
);
1649 devfs_rule_reset_node(node
);
1656 * This function calls a given callback function for
1657 * every dev node in the devfs dev list.
1660 devfs_scan_callback_worker(devfs_scan_t
*callback
)
1664 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_scan_callback: %p -1-\n", callback
);
1666 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1670 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_scan_callback: finished\n");
1676 * This function tries to resolve a given directory, or if not
1677 * found and creation requested, creates the given directory.
1679 static struct devfs_node
*
1680 devfs_resolve_or_create_dir(struct devfs_node
*parent
, char *dir_name
,
1681 size_t name_len
, int create
)
1683 struct devfs_node
*node
, *found
= NULL
;
1685 TAILQ_FOREACH(node
, DEVFS_DENODE_HEAD(parent
), link
) {
1686 if (name_len
== node
->d_dir
.d_namlen
) {
1687 if (!memcmp(dir_name
, node
->d_dir
.d_name
, name_len
)) {
1694 if ((found
== NULL
) && (create
)) {
1695 found
= devfs_allocp(Pdir
, dir_name
, parent
, parent
->mp
, NULL
);
1702 * This function tries to resolve a complete path. If creation is requested,
1703 * if a given part of the path cannot be resolved (because it doesn't exist),
1707 devfs_resolve_or_create_path(struct devfs_node
*parent
, char *path
, int create
)
1709 struct devfs_node
*node
= parent
;
1718 for (; *path
!= '\0' ; path
++) {
1723 node
= devfs_resolve_or_create_dir(node
, buf
, idx
, create
);
1730 return devfs_resolve_or_create_dir(node
, buf
, idx
, create
);
1734 * Takes a full path and strips it into a directory path and a name.
1735 * For a/b/c/foo, it returns foo in namep and a/b/c in pathp. It
1736 * requires a working buffer with enough size to keep the whole
1740 devfs_resolve_name_path(char *fullpath
, char *buf
, char **pathp
, char **namep
)
1744 size_t len
= strlen(fullpath
) + 1;
1747 KKASSERT((fullpath
!= NULL
) && (buf
!= NULL
) && (pathp
!= NULL
) && (namep
!= NULL
));
1749 memcpy(buf
, fullpath
, len
);
1751 for (i
= len
-1; i
>= 0; i
--) {
1752 if (buf
[i
] == '/') {
1772 * This function creates a new devfs node for a given device. It can
1773 * handle a complete path as device name, and accordingly creates
1774 * the path and the final device node.
1776 * The reference count on the passed dev remains unchanged.
1779 devfs_create_device_node(struct devfs_node
*root
, cdev_t dev
,
1780 char *dev_name
, char *path_fmt
, ...)
1782 struct devfs_node
*parent
, *node
= NULL
;
1784 char *name
, name_buf
[PATH_MAX
];
1788 char *create_path
= NULL
;
1789 char *names
= "pqrsPQRS";
1791 if (path_fmt
!= NULL
) {
1792 path
= kmalloc(PATH_MAX
+1, M_DEVFS
, M_WAITOK
);
1794 __va_start(ap
, path_fmt
);
1795 i
= kvcprintf(path_fmt
, NULL
, path
, 10, ap
);
1800 parent
= devfs_resolve_or_create_path(root
, path
, 1);
1803 devfs_resolve_name_path(((dev_name
== NULL
) && (dev
))?(dev
->si_name
):(dev_name
), name_buf
, &create_path
, &name
);
1806 parent
= devfs_resolve_or_create_path(parent
, create_path
, 1);
1809 if (devfs_find_device_node_by_name(parent
, name
)) {
1810 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_device_node: "
1811 "DEVICE %s ALREADY EXISTS!!! Ignoring creation request.\n", name
);
1814 devfs_debug(DEVFS_DEBUG_DEBUG
, "parent->d_dir.d_name=%s\n", parent
->d_dir
.d_name
);
1815 node
= devfs_allocp(Pdev
, name
, parent
, parent
->mp
, dev
);
1816 devfs_debug(DEVFS_DEBUG_DEBUG
, "node->d_dir.d_name=%s\n", node
->d_dir
.d_name
);
1819 /* Ugly unix98 pty magic, to hide pty master (ptm) devices and their directory */
1820 if ((dev
) && (strlen(dev
->si_name
) >= 4) && (!memcmp(dev
->si_name
, "ptm/", 4))) {
1821 node
->parent
->flags
|= DEVFS_HIDDEN
;
1822 node
->flags
|= DEVFS_HIDDEN
;
1825 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_device_node: marker A\n");
1826 /* Ugly pty magic, to tag pty devices as such and hide them if needed */
1827 if ((strlen(name
) >= 3) && (!memcmp(name
, "pty", 3)))
1828 node
->flags
|= (DEVFS_PTY
| DEVFS_INVISIBLE
);
1830 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_device_node: marker B\n");
1831 if ((strlen(name
) >= 3) && (!memcmp(name
, "tty", 3))) {
1833 for (i
= 0; i
< strlen(names
); i
++) {
1834 if (name
[3] == names
[i
]) {
1840 node
->flags
|= (DEVFS_PTY
| DEVFS_INVISIBLE
);
1842 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_create_device_node: marker C\n");
1845 if (path_fmt
!= NULL
)
1846 kfree(path
, M_DEVFS
);
1852 * This function finds a given device node in the topology with a given
1856 devfs_find_device_node(struct devfs_node
*node
, cdev_t target
)
1858 struct devfs_node
*node1
, *node2
, *found
= NULL
;
1860 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1861 devfs_debug(DEVFS_DEBUG_DEBUG
, "This node is Pdir or Proot; has %d children\n", node
->nchildren
);
1862 if (node
->nchildren
> 2) {
1863 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1864 if ((found
= devfs_find_device_node(node1
, target
)))
1868 } else if (node
->node_type
== Pdev
) {
1869 if (node
->d_dev
== target
)
1877 * This function finds a device node in the topology by its
1878 * name and returns it.
1881 devfs_find_device_node_by_name(struct devfs_node
*parent
, char *target
)
1883 struct devfs_node
*node
, *found
= NULL
;
1884 size_t len
= strlen(target
);
1886 TAILQ_FOREACH(node
, DEVFS_DENODE_HEAD(parent
), link
) {
1887 if ((len
== node
->d_dir
.d_namlen
) && (!memcmp(node
->d_dir
.d_name
, target
, len
))) {
1897 * This function takes a cdev and removes its devfs node in the
1898 * given topology. The cdev remains intact.
1901 devfs_destroy_device_node(struct devfs_node
*root
, cdev_t target
)
1903 struct devfs_node
*node
, *parent
;
1904 char *name
, name_buf
[PATH_MAX
];
1905 char *create_path
= NULL
;
1909 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_destroy_device_node\n");
1910 memcpy(name_buf
, target
->si_name
, strlen(target
->si_name
)+1);
1912 devfs_resolve_name_path(target
->si_name
, name_buf
, &create_path
, &name
);
1913 devfs_debug(DEVFS_DEBUG_DEBUG
, "create_path: %s\n", create_path
);
1914 devfs_debug(DEVFS_DEBUG_DEBUG
, "name: %s\n", name
);
1917 parent
= devfs_resolve_or_create_path(root
, create_path
, 0);
1920 devfs_debug(DEVFS_DEBUG_DEBUG
, "-> marker <-\n");
1923 devfs_debug(DEVFS_DEBUG_DEBUG
, "->d_dir.d_name=%s\n", parent
->d_dir
.d_name
);
1924 node
= devfs_find_device_node_by_name(parent
, name
);
1925 devfs_debug(DEVFS_DEBUG_DEBUG
,
1926 "->d_dir.d_name=%s\n",
1927 ((node
) ? (node
->d_dir
.d_name
) : "SHIT!"));
1935 * Just set perms and ownership for given node.
1938 devfs_set_perms(struct devfs_node
*node
, uid_t uid
, gid_t gid
, u_short mode
, u_long flags
)
1940 node
->mode
= mode
; /* files access mode and type */
1941 node
->uid
= uid
; /* owner user id */
1942 node
->gid
= gid
; /* owner group id */
1948 * Propagates a device attach/detach to all mount
1949 * points. Also takes care of automatic alias removal
1950 * for a deleted cdev.
1953 devfs_propagate_dev(cdev_t dev
, int attach
)
1955 struct devfs_mnt_data
*mnt
;
1957 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_propagate_dev -1-\n");
1958 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1959 devfs_debug(DEVFS_DEBUG_DEBUG
,
1960 "devfs_propagate_dev -loop:2-\n");
1962 /* Device is being attached */
1963 devfs_create_device_node(mnt
->root_node
, dev
,
1966 /* Device is being detached */
1967 devfs_alias_remove(dev
);
1968 devfs_destroy_device_node(mnt
->root_node
, dev
);
1971 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_propagate_dev -end:3-\n");
1976 * devfs_node_to_path takes a node and a buffer of a size of
1977 * at least PATH_MAX, resolves the full path from the root
1978 * node and writes it in a humanly-readable format into the
1980 * If DEVFS_STASH_DEPTH is less than the directory level up
1981 * to the root node, only the last DEVFS_STASH_DEPTH levels
1982 * of the path are resolved.
1985 devfs_node_to_path(struct devfs_node
*node
, char *buffer
)
1987 #define DEVFS_STASH_DEPTH 32
1988 struct devfs_node
*node_stash
[DEVFS_STASH_DEPTH
];
1990 memset(buffer
, 0, PATH_MAX
);
1992 for (i
= 0; (i
< DEVFS_STASH_DEPTH
) && (node
->node_type
!= Proot
); i
++) {
1993 node_stash
[i
] = node
;
1994 node
= node
->parent
;
1998 for (offset
= 0; i
>= 0; i
--) {
1999 memcpy(buffer
+offset
, node_stash
[i
]->d_dir
.d_name
, node_stash
[i
]->d_dir
.d_namlen
);
2000 offset
+= node_stash
[i
]->d_dir
.d_namlen
;
2002 *(buffer
+offset
) = '/';
2006 #undef DEVFS_STASH_DEPTH
2011 * devfs_clone either returns a basename from a complete name by
2012 * returning the length of the name without trailing digits, or,
2013 * if clone != 0, calls the device's clone handler to get a new
2014 * device, which in turn is returned in devp.
2017 devfs_clone(char *name
, size_t *namlenp
, cdev_t
*devp
, int clone
, struct ucred
*cred
)
2021 size_t len
= *namlenp
;
2023 struct devfs_clone_handler
*chandler
;
2024 struct dev_clone_args ap
;
2027 for (; (len
> 0) && (DEVFS_ISDIGIT(name
[len
-1])); len
--);
2030 TAILQ_FOREACH(chandler
, &devfs_chandler_list
, link
) {
2031 devfs_debug(DEVFS_DEBUG_DEBUG
, "len=%d, chandler->namlen=%d\n", len
, chandler
->namlen
);
2032 devfs_debug(DEVFS_DEBUG_DEBUG
, "name=%s, chandler->name=%s\n", name
, chandler
->name
);
2033 if ((chandler
->namlen
== len
) &&
2034 (!memcmp(chandler
->name
, name
, len
)) &&
2035 (chandler
->nhandler
)) {
2036 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_nclone: found clone handler for the base name at %p\n", chandler
->nhandler
);
2042 error
= (chandler
->nhandler
)(&ap
);
2059 * Registers a new orphan in the orphan list.
2062 devfs_tracer_add_orphan(struct devfs_node
*node
)
2064 struct devfs_orphan
*orphan
;
2067 orphan
= kmalloc(sizeof(struct devfs_orphan
), M_DEVFS
, M_WAITOK
);
2068 orphan
->node
= node
;
2070 KKASSERT((node
->flags
& DEVFS_ORPHANED
) == 0);
2071 node
->flags
|= DEVFS_ORPHANED
;
2072 TAILQ_INSERT_TAIL(DEVFS_ORPHANLIST(node
->mp
), orphan
, link
);
2076 * Removes an orphan from the orphan list.
2079 devfs_tracer_del_orphan(struct devfs_node
*node
)
2081 struct devfs_orphan
*orphan
;
2085 TAILQ_FOREACH(orphan
, DEVFS_ORPHANLIST(node
->mp
), link
) {
2086 if (orphan
->node
== node
) {
2087 node
->flags
&= ~DEVFS_ORPHANED
;
2088 TAILQ_REMOVE(DEVFS_ORPHANLIST(node
->mp
), orphan
, link
);
2089 kfree(orphan
, M_DEVFS
);
2096 * Counts the orphans in the orphan list, and if cleanup
2097 * is specified, also frees the orphan and removes it from
2101 devfs_tracer_orphan_count(struct mount
*mp
, int cleanup
)
2103 struct devfs_orphan
*orphan
, *orphan2
;
2106 TAILQ_FOREACH_MUTABLE(orphan
, DEVFS_ORPHANLIST(mp
), link
, orphan2
) {
2109 TAILQ_REMOVE(DEVFS_ORPHANLIST(mp
), orphan
, link
);
2110 orphan
->node
->flags
&= ~DEVFS_ORPHANED
;
2111 devfs_freep(orphan
->node
);
2112 kfree(orphan
, M_DEVFS
);
2120 * Fetch an ino_t from the global d_ino by increasing it
2124 devfs_fetch_ino(void)
2128 spin_lock_wr(&ino_lock
);
2130 spin_unlock_wr(&ino_lock
);
2136 * Allocates a new cdev and initializes it's most basic
2140 devfs_new_cdev(struct dev_ops
*ops
, int minor
)
2142 cdev_t dev
= sysref_alloc(&cdev_sysref_class
);
2143 sysref_activate(&dev
->si_sysref
);
2145 devfs_debug(DEVFS_DEBUG_DEBUG
,
2146 "new_cdev: clearing first %d bytes\n",
2147 offsetof(struct cdev
, si_sysref
));
2148 memset(dev
, 0, offsetof(struct cdev
, si_sysref
));
2153 dev
->si_drv1
= NULL
;
2154 dev
->si_drv2
= NULL
;
2155 dev
->si_lastread
= 0; /* time_second */
2156 dev
->si_lastwrite
= 0; /* time_second */
2161 dev
->si_uminor
= minor
;
2162 dev
->si_inode
= devfs_fetch_ino();
2168 devfs_cdev_terminate(cdev_t dev
)
2172 /* Check if it is locked already. if not, we acquire the devfs lock */
2173 if (!(lockstatus(&devfs_lock
, curthread
)) == LK_EXCLUSIVE
) {
2174 lockmgr(&devfs_lock
, LK_EXCLUSIVE
);
2178 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_cdev_terminate: Taking care of dev->si_name=%s\n", dev
->si_name
);
2180 /* Propagate destruction, just in case */
2181 devfs_propagate_dev(dev
, 0);
2183 /* If we acquired the lock, we also get rid of it */
2185 lockmgr(&devfs_lock
, LK_RELEASE
);
2187 /* Finally destroy the device */
2188 sysref_put(&dev
->si_sysref
);
2192 * Links a given cdev into the dev list.
2195 devfs_link_dev(cdev_t dev
)
2197 KKASSERT((dev
->si_flags
& SI_DEVFS_LINKED
) == 0);
2198 dev
->si_flags
|= SI_DEVFS_LINKED
;
2199 TAILQ_INSERT_TAIL(&devfs_dev_list
, dev
, link
);
2205 * Removes a given cdev from the dev list. The caller is responsible for
2206 * releasing the reference on the device associated with the linkage.
2208 * Returns EALREADY if the dev has already been unlinked.
2211 devfs_unlink_dev(cdev_t dev
)
2213 if ((dev
->si_flags
& SI_DEVFS_LINKED
)) {
2214 TAILQ_REMOVE(&devfs_dev_list
, dev
, link
);
2215 dev
->si_flags
&= ~SI_DEVFS_LINKED
;
2222 devfs_node_is_accessible(struct devfs_node
*node
)
2224 if ((node
) && (!(node
->flags
& DEVFS_HIDDEN
)))
2231 devfs_config(void *arg
)
2235 msg
= devfs_msg_get();
2237 kprintf("devfs_config: sync'ing up\n");
2238 msg
= devfs_msg_send_sync(DEVFS_SYNC
, msg
);
2243 * Called on init of devfs; creates the objcaches and
2244 * spawns off the devfs core thread. Also initializes
2250 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_init() called\n");
2251 /* Create objcaches for nodes, msgs and devs */
2252 devfs_node_cache
= objcache_create("devfs-node-cache", 0, 0,
2254 objcache_malloc_alloc
,
2255 objcache_malloc_free
,
2256 &devfs_node_malloc_args
);
2258 devfs_msg_cache
= objcache_create("devfs-msg-cache", 0, 0,
2260 objcache_malloc_alloc
,
2261 objcache_malloc_free
,
2262 &devfs_msg_malloc_args
);
2264 devfs_dev_cache
= objcache_create("devfs-dev-cache", 0, 0,
2266 objcache_malloc_alloc
,
2267 objcache_malloc_free
,
2268 &devfs_dev_malloc_args
);
2270 /* Initialize the reply-only port which acts as a message drain */
2271 lwkt_initport_replyonly(&devfs_dispose_port
, devfs_msg_autofree_reply
);
2273 /* Initialize *THE* devfs lock */
2274 lockinit(&devfs_lock
, "devfs_core lock", 0, 0);
2277 lwkt_create(devfs_msg_core
, /*args*/NULL
, &td_core
, NULL
,
2278 0, 0, "devfs_msg_core");
2280 tsleep(td_core
/*devfs_id*/, 0, "devfsc", 0);
2282 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_init finished\n");
2286 * Called on unload of devfs; takes care of destroying the core
2287 * and the objcaches. Also removes aliases that are no longer needed.
2292 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_uninit() called\n");
2294 devfs_msg_send(DEVFS_TERMINATE_CORE
, NULL
);
2296 tsleep(td_core
/*devfs_id*/, 0, "devfsc", 0);
2297 tsleep(td_core
/*devfs_id*/, 0, "devfsc", 10000);
2299 /* Destroy the objcaches */
2300 objcache_destroy(devfs_msg_cache
);
2301 objcache_destroy(devfs_node_cache
);
2302 objcache_destroy(devfs_dev_cache
);
2308 * This is a sysctl handler to assist userland devname(3) to
2309 * find the device name for a given udev.
2312 devfs_sysctl_devname_helper(SYSCTL_HANDLER_ARGS
)
2319 if ((error
= SYSCTL_IN(req
, &udev
, sizeof(udev_t
))))
2322 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs sysctl, received udev: %d\n", udev
);
2327 if ((found
= devfs_find_device_by_udev(udev
)) == NULL
)
2330 return(SYSCTL_OUT(req
, found
->si_name
, strlen(found
->si_name
) + 1));
2334 SYSCTL_PROC(_kern
, OID_AUTO
, devname
, CTLTYPE_OPAQUE
|CTLFLAG_RW
|CTLFLAG_ANYBODY
,
2335 NULL
, 0, devfs_sysctl_devname_helper
, "", "helper for devname(3)");
2337 static SYSCTL_NODE(_vfs
, OID_AUTO
, devfs
, CTLFLAG_RW
, 0, "devfs");
2338 TUNABLE_INT("vfs.devfs.debug", &devfs_debug_enable
);
2339 SYSCTL_INT(_vfs_devfs
, OID_AUTO
, debug
, CTLFLAG_RW
, &devfs_debug_enable
, 0, "Enable DevFS debugging");
2341 SYSINIT(vfs_devfs_register
, SI_SUB_PRE_DRIVERS
, SI_ORDER_FIRST
, devfs_init
, NULL
);
2342 SYSUNINIT(vfs_devfs_register
, SI_SUB_PRE_DRIVERS
, SI_ORDER_ANY
, devfs_uninit
, NULL
);