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 <sys/systm.h>
49 #include <vfs/devfs/devfs.h>
50 #include <vfs/devfs/devfs_rules.h>
52 MALLOC_DEFINE(M_DEVFS
, "devfs", "Device File System (devfs) allocations");
53 DEVFS_DECLARE_CLONE_BITMAP(ops_id
);
55 * SYSREF Integration - reference counting, allocation,
56 * sysid and syslink integration.
58 static void devfs_cdev_terminate(cdev_t dev
);
59 static struct sysref_class cdev_sysref_class
= {
62 .proto
= SYSREF_PROTO_DEV
,
63 .offset
= offsetof(struct cdev
, si_sysref
),
64 .objsize
= sizeof(struct cdev
),
68 .terminate
= (sysref_terminate_func_t
)devfs_cdev_terminate
72 static struct objcache
*devfs_node_cache
;
73 static struct objcache
*devfs_msg_cache
;
74 static struct objcache
*devfs_dev_cache
;
76 static struct objcache_malloc_args devfs_node_malloc_args
= {
77 sizeof(struct devfs_node
), M_DEVFS
};
78 struct objcache_malloc_args devfs_msg_malloc_args
= {
79 sizeof(struct devfs_msg
), M_DEVFS
};
80 struct objcache_malloc_args devfs_dev_malloc_args
= {
81 sizeof(struct cdev
), M_DEVFS
};
83 static struct devfs_dev_head devfs_dev_list
=
84 TAILQ_HEAD_INITIALIZER(devfs_dev_list
);
85 static struct devfs_mnt_head devfs_mnt_list
=
86 TAILQ_HEAD_INITIALIZER(devfs_mnt_list
);
87 static struct devfs_chandler_head devfs_chandler_list
=
88 TAILQ_HEAD_INITIALIZER(devfs_chandler_list
);
89 static struct devfs_alias_head devfs_alias_list
=
90 TAILQ_HEAD_INITIALIZER(devfs_alias_list
);
92 struct lock devfs_lock
;
93 static struct lwkt_port devfs_dispose_port
;
94 static struct lwkt_port devfs_msg_port
;
95 static struct thread
*td_core
;
97 static struct spinlock ino_lock
;
99 static int devfs_debug_enable
;
100 static int devfs_run
;
102 static ino_t
devfs_fetch_ino(void);
103 static int devfs_gc_dirs(struct devfs_node
*);
104 static int devfs_gc_links(struct devfs_node
*, struct devfs_node
*, size_t);
105 static int devfs_create_all_dev_worker(struct devfs_node
*);
106 static int devfs_create_dev_worker(cdev_t
, uid_t
, gid_t
, int);
107 static int devfs_destroy_dev_worker(cdev_t
);
108 static int devfs_destroy_subnames_worker(char *);
109 static int devfs_destroy_dev_by_ops_worker(struct dev_ops
*, int);
110 static int devfs_propagate_dev(cdev_t
, int);
111 static int devfs_unlink_dev(cdev_t dev
);
112 static void devfs_msg_exec(devfs_msg_t msg
);
114 static int devfs_chandler_add_worker(char *, d_clone_t
*);
115 static int devfs_chandler_del_worker(char *);
117 static void devfs_msg_autofree_reply(lwkt_port_t
, lwkt_msg_t
);
118 static void devfs_msg_core(void *);
120 static int devfs_find_device_by_name_worker(devfs_msg_t
);
121 static int devfs_find_device_by_udev_worker(devfs_msg_t
);
123 static struct vnode
*devfs_inode_to_vnode_worker(struct devfs_node
*, ino_t
);
125 static int devfs_apply_reset_rules_caller(char *, int);
126 static int devfs_apply_reset_rules_worker(struct devfs_node
*, int);
128 static int devfs_scan_callback_worker(devfs_scan_t
*);
130 static struct devfs_node
*devfs_resolve_or_create_dir(struct devfs_node
*,
131 char *, size_t, int);
133 static int devfs_make_alias_worker(struct devfs_alias
*);
134 static int devfs_alias_remove(cdev_t
);
135 static int devfs_alias_reap(void);
136 static int devfs_alias_propagate(struct devfs_alias
*);
137 static int devfs_alias_apply(struct devfs_node
*, struct devfs_alias
*);
138 static int devfs_alias_check_create(struct devfs_node
*);
140 static int devfs_clr_subnames_flag_worker(char *, uint32_t);
141 static int devfs_destroy_subnames_without_flag_worker(char *, uint32_t);
144 * devfs_debug() is a SYSCTL and TUNABLE controlled debug output function
148 devfs_debug(int level
, char *fmt
, ...)
153 if (level
<= devfs_debug_enable
)
161 * devfs_allocp() Allocates a new devfs node with the specified
162 * parameters. The node is also automatically linked into the topology
163 * if a parent is specified. It also calls the rule and alias stuff to
164 * be applied on the new node
167 devfs_allocp(devfs_nodetype devfsnodetype
, char *name
,
168 struct devfs_node
*parent
, struct mount
*mp
, cdev_t dev
)
170 struct devfs_node
*node
= NULL
;
171 size_t namlen
= strlen(name
);
173 node
= objcache_get(devfs_node_cache
, M_WAITOK
);
174 bzero(node
, sizeof(*node
));
176 atomic_add_int(&(DEVFS_MNTDATA(mp
)->leak_count
), 1);
181 node
->d_dir
.d_ino
= devfs_fetch_ino();
184 * Cookie jar for children. Leave 0 and 1 for '.' and '..' entries
187 node
->cookie_jar
= 2;
190 * Access Control members
192 node
->mode
= DEVFS_DEFAULT_MODE
;
193 node
->uid
= DEVFS_DEFAULT_UID
;
194 node
->gid
= DEVFS_DEFAULT_GID
;
196 switch (devfsnodetype
) {
199 * Ensure that we don't recycle the root vnode by marking it as
200 * linked into the topology.
202 node
->flags
|= DEVFS_NODE_LINKED
;
204 TAILQ_INIT(DEVFS_DENODE_HEAD(node
));
205 node
->d_dir
.d_type
= DT_DIR
;
210 node
->d_dir
.d_type
= DT_LNK
;
214 node
->d_dir
.d_type
= DT_REG
;
219 node
->d_dir
.d_type
= DT_CHR
;
222 node
->mode
= dev
->si_perms
;
223 node
->uid
= dev
->si_uid
;
224 node
->gid
= dev
->si_gid
;
226 devfs_alias_check_create(node
);
231 panic("devfs_allocp: unknown node type");
235 node
->node_type
= devfsnodetype
;
237 /* Initialize the dirent structure of each devfs vnode */
238 KKASSERT(namlen
< 256);
239 node
->d_dir
.d_namlen
= namlen
;
240 node
->d_dir
.d_name
= kmalloc(namlen
+1, M_DEVFS
, M_WAITOK
);
241 memcpy(node
->d_dir
.d_name
, name
, namlen
);
242 node
->d_dir
.d_name
[namlen
] = '\0';
244 /* Initialize the parent node element */
245 node
->parent
= parent
;
248 devfs_rule_check_apply(node
);
250 /* Initialize *time members */
251 nanotime(&node
->atime
);
252 node
->mtime
= node
->ctime
= node
->atime
;
255 * Associate with parent as last step, clean out namecache
258 if ((parent
!= NULL
) &&
259 ((parent
->node_type
== Proot
) || (parent
->node_type
== Pdir
))) {
261 node
->cookie
= parent
->cookie_jar
++;
262 node
->flags
|= DEVFS_NODE_LINKED
;
263 TAILQ_INSERT_TAIL(DEVFS_DENODE_HEAD(parent
), node
, link
);
265 /* This forces negative namecache lookups to clear */
266 ++mp
->mnt_namecache_gen
;
273 * devfs_allocv() allocates a new vnode based on a devfs node.
276 devfs_allocv(struct vnode
**vpp
, struct devfs_node
*node
)
284 while ((vp
= node
->v_node
) != NULL
) {
285 error
= vget(vp
, LK_EXCLUSIVE
);
286 if (error
!= ENOENT
) {
292 if ((error
= getnewvnode(VT_DEVFS
, node
->mp
, vpp
, 0, 0)) != 0)
297 if (node
->v_node
!= NULL
) {
306 switch (node
->node_type
) {
323 KKASSERT(node
->d_dev
);
325 vp
->v_uminor
= node
->d_dev
->si_uminor
;
328 v_associate_rdev(vp
, node
->d_dev
);
329 vp
->v_ops
= &node
->mp
->mnt_vn_spec_ops
;
333 panic("devfs_allocv: unknown node type");
341 * devfs_allocvp allocates both a devfs node (with the given settings) and a vnode
342 * based on the newly created devfs node.
345 devfs_allocvp(struct mount
*mp
, struct vnode
**vpp
, devfs_nodetype devfsnodetype
,
346 char *name
, struct devfs_node
*parent
, cdev_t dev
)
348 struct devfs_node
*node
;
350 node
= devfs_allocp(devfsnodetype
, name
, parent
, mp
, dev
);
353 devfs_allocv(vpp
, node
);
361 * Destroy the devfs_node. The node must be unlinked from the topology.
363 * This function will also destroy any vnode association with the node
366 * The cdev_t itself remains intact.
369 devfs_freep(struct devfs_node
*node
)
374 KKASSERT(((node
->flags
& DEVFS_NODE_LINKED
) == 0) ||
375 (node
->node_type
== Proot
));
376 KKASSERT((node
->flags
& DEVFS_DESTROYED
) == 0);
378 atomic_subtract_int(&(DEVFS_MNTDATA(node
->mp
)->leak_count
), 1);
379 if (node
->symlink_name
) {
380 kfree(node
->symlink_name
, M_DEVFS
);
381 node
->symlink_name
= NULL
;
385 * Remove the node from the orphan list if it is still on it.
387 if (node
->flags
& DEVFS_ORPHANED
)
388 devfs_tracer_del_orphan(node
);
391 * Disassociate the vnode from the node. This also prevents the
392 * vnode's reclaim code from double-freeing the node.
394 if ((vp
= node
->v_node
) != NULL
) {
399 if (node
->d_dir
.d_name
)
400 kfree(node
->d_dir
.d_name
, M_DEVFS
);
401 node
->flags
|= DEVFS_DESTROYED
;
403 objcache_put(devfs_node_cache
, node
);
409 * Unlink the devfs node from the topology and add it to the orphan list.
410 * The node will later be destroyed by freep.
412 * Any vnode association, including the v_rdev and v_data, remains intact
416 devfs_unlinkp(struct devfs_node
*node
)
418 struct devfs_node
*parent
;
422 * Add the node to the orphan list, so it is referenced somewhere, to
423 * so we don't leak it.
425 devfs_tracer_add_orphan(node
);
427 parent
= node
->parent
;
430 * If the parent is known we can unlink the node out of the topology
433 TAILQ_REMOVE(DEVFS_DENODE_HEAD(parent
), node
, link
);
435 KKASSERT((parent
->nchildren
>= 0));
436 node
->flags
&= ~DEVFS_NODE_LINKED
;
443 * devfs_reaperp() is a recursive function that iterates through all the
444 * topology, unlinking and freeing all devfs nodes.
447 devfs_reaperp(struct devfs_node
*node
)
449 struct devfs_node
*node1
, *node2
;
451 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
452 if (node
->nchildren
> 2) {
453 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
),
455 devfs_reaperp(node1
);
466 * devfs_gc() is devfs garbage collector. It takes care of unlinking and
467 * freeing a node, but also removes empty directories and links that link
468 * via devfs auto-link mechanism to the node being deleted.
471 devfs_gc(struct devfs_node
*node
)
473 struct devfs_node
*root_node
= DEVFS_MNTDATA(node
->mp
)->root_node
;
475 devfs_gc_links(root_node
, node
, node
->nlinks
);
477 devfs_gc_dirs(root_node
);
485 * devfs_gc_dirs() is a helper function for devfs_gc, unlinking and freeing
489 devfs_gc_dirs(struct devfs_node
*node
)
491 struct devfs_node
*node1
, *node2
;
493 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
494 if (node
->nchildren
> 2) {
495 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
),
497 devfs_gc_dirs(node1
);
501 if (node
->nchildren
== 2) {
511 * devfs_gc_links() is a helper function for devfs_gc, unlinking and freeing
512 * eauto-linked nodes linking to the node being deleted.
515 devfs_gc_links(struct devfs_node
*node
, struct devfs_node
*target
,
518 struct devfs_node
*node1
, *node2
;
521 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
522 if (node
->nchildren
> 2) {
523 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
),
525 nlinks
= devfs_gc_links(node1
, target
, nlinks
);
528 } else if (node
->link_target
== target
) {
535 KKASSERT(nlinks
>= 0);
541 * devfs_create_dev() is the asynchronous entry point for device creation.
542 * It just sends a message with the relevant details to the devfs core.
544 * This function will reference the passed device. The reference is owned
545 * by devfs and represents all of the device's node associations.
548 devfs_create_dev(cdev_t dev
, uid_t uid
, gid_t gid
, int perms
)
551 devfs_msg_send_dev(DEVFS_DEVICE_CREATE
, dev
, uid
, gid
, perms
);
557 * devfs_destroy_dev() is the asynchronous entry point for device destruction.
558 * It just sends a message with the relevant details to the devfs core.
561 devfs_destroy_dev(cdev_t dev
)
563 devfs_msg_send_dev(DEVFS_DEVICE_DESTROY
, dev
, 0, 0, 0);
568 * devfs_mount_add() is the synchronous entry point for adding a new devfs
569 * mount. It sends a synchronous message with the relevant details to the
573 devfs_mount_add(struct devfs_mnt_data
*mnt
)
577 msg
= devfs_msg_get();
579 msg
= devfs_msg_send_sync(DEVFS_MOUNT_ADD
, msg
);
586 * devfs_mount_del() is the synchronous entry point for removing a devfs mount.
587 * It sends a synchronous message with the relevant details to the devfs core.
590 devfs_mount_del(struct devfs_mnt_data
*mnt
)
594 msg
= devfs_msg_get();
596 msg
= devfs_msg_send_sync(DEVFS_MOUNT_DEL
, msg
);
603 * devfs_destroy_subnames() is the synchronous entry point for device
604 * destruction by subname. It just sends a message with the relevant details to
608 devfs_destroy_subnames(char *name
)
612 msg
= devfs_msg_get();
613 msg
->mdv_load
= name
;
614 msg
= devfs_msg_send_sync(DEVFS_DESTROY_SUBNAMES
, msg
);
620 devfs_clr_subnames_flag(char *name
, uint32_t flag
)
624 msg
= devfs_msg_get();
625 msg
->mdv_flags
.name
= name
;
626 msg
->mdv_flags
.flag
= flag
;
627 msg
= devfs_msg_send_sync(DEVFS_CLR_SUBNAMES_FLAG
, msg
);
634 devfs_destroy_subnames_without_flag(char *name
, uint32_t flag
)
638 msg
= devfs_msg_get();
639 msg
->mdv_flags
.name
= name
;
640 msg
->mdv_flags
.flag
= flag
;
641 msg
= devfs_msg_send_sync(DEVFS_DESTROY_SUBNAMES_WO_FLAG
, msg
);
648 * devfs_create_all_dev is the asynchronous entry point to trigger device
649 * node creation. It just sends a message with the relevant details to
653 devfs_create_all_dev(struct devfs_node
*root
)
655 devfs_msg_send_generic(DEVFS_CREATE_ALL_DEV
, root
);
660 * devfs_destroy_dev_by_ops is the asynchronous entry point to destroy all
661 * devices with a specific set of dev_ops and minor. It just sends a
662 * message with the relevant details to the devfs core.
665 devfs_destroy_dev_by_ops(struct dev_ops
*ops
, int minor
)
667 devfs_msg_send_ops(DEVFS_DESTROY_DEV_BY_OPS
, ops
, minor
);
672 * devfs_clone_handler_add is the synchronous entry point to add a new
673 * clone handler. It just sends a message with the relevant details to
677 devfs_clone_handler_add(char *name
, d_clone_t
*nhandler
)
681 msg
= devfs_msg_get();
682 msg
->mdv_chandler
.name
= name
;
683 msg
->mdv_chandler
.nhandler
= nhandler
;
684 msg
= devfs_msg_send_sync(DEVFS_CHANDLER_ADD
, msg
);
690 * devfs_clone_handler_del is the synchronous entry point to remove a
691 * clone handler. It just sends a message with the relevant details to
695 devfs_clone_handler_del(char *name
)
699 msg
= devfs_msg_get();
700 msg
->mdv_chandler
.name
= name
;
701 msg
->mdv_chandler
.nhandler
= NULL
;
702 msg
= devfs_msg_send_sync(DEVFS_CHANDLER_DEL
, msg
);
708 * devfs_find_device_by_name is the synchronous entry point to find a
709 * device given its name. It sends a synchronous message with the
710 * relevant details to the devfs core and returns the answer.
713 devfs_find_device_by_name(const char *fmt
, ...)
717 char target
[PATH_MAX
+1];
725 i
= kvcprintf(fmt
, NULL
, target
, 10, ap
);
729 msg
= devfs_msg_get();
730 msg
->mdv_name
= target
;
731 msg
= devfs_msg_send_sync(DEVFS_FIND_DEVICE_BY_NAME
, msg
);
732 found
= msg
->mdv_cdev
;
739 * devfs_find_device_by_udev is the synchronous entry point to find a
740 * device given its udev number. It sends a synchronous message with
741 * the relevant details to the devfs core and returns the answer.
744 devfs_find_device_by_udev(udev_t udev
)
749 msg
= devfs_msg_get();
750 msg
->mdv_udev
= udev
;
751 msg
= devfs_msg_send_sync(DEVFS_FIND_DEVICE_BY_UDEV
, msg
);
752 found
= msg
->mdv_cdev
;
755 devfs_debug(DEVFS_DEBUG_DEBUG
,
756 "devfs_find_device_by_udev found? %s -end:3-\n",
757 ((found
) ? found
->si_name
:"NO"));
762 devfs_inode_to_vnode(struct mount
*mp
, ino_t target
)
764 struct vnode
*vp
= NULL
;
770 msg
= devfs_msg_get();
771 msg
->mdv_ino
.mp
= mp
;
772 msg
->mdv_ino
.ino
= target
;
773 msg
= devfs_msg_send_sync(DEVFS_INODE_TO_VNODE
, msg
);
774 vp
= msg
->mdv_ino
.vp
;
775 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
782 * devfs_make_alias is the asynchronous entry point to register an alias
783 * for a device. It just sends a message with the relevant details to the
787 devfs_make_alias(char *name
, cdev_t dev_target
)
789 struct devfs_alias
*alias
;
794 alias
= kmalloc(sizeof(struct devfs_alias
), M_DEVFS
, M_WAITOK
);
795 alias
->name
= kmalloc(len
+ 1, M_DEVFS
, M_WAITOK
);
796 memcpy(alias
->name
, name
, len
+ 1);
798 alias
->dev_target
= dev_target
;
800 devfs_msg_send_generic(DEVFS_MAKE_ALIAS
, alias
);
805 * devfs_apply_rules is the asynchronous entry point to trigger application
806 * of all rules. It just sends a message with the relevant details to the
810 devfs_apply_rules(char *mntto
)
815 namelen
= strlen(mntto
) + 1;
816 new_name
= kmalloc(namelen
, M_DEVFS
, M_WAITOK
);
817 memcpy(new_name
, mntto
, namelen
);
818 devfs_msg_send_name(DEVFS_APPLY_RULES
, new_name
);
824 * devfs_reset_rules is the asynchronous entry point to trigger reset of all
825 * rules. It just sends a message with the relevant details to the devfs core.
828 devfs_reset_rules(char *mntto
)
833 namelen
= strlen(mntto
) + 1;
834 new_name
= kmalloc(namelen
, M_DEVFS
, M_WAITOK
);
835 memcpy(new_name
, mntto
, namelen
);
836 devfs_msg_send_name(DEVFS_RESET_RULES
, new_name
);
843 * devfs_scan_callback is the asynchronous entry point to call a callback
845 * It just sends a message with the relevant details to the devfs core.
848 devfs_scan_callback(devfs_scan_t
*callback
)
852 KKASSERT(sizeof(callback
) == sizeof(void *));
854 msg
= devfs_msg_get();
855 msg
->mdv_load
= callback
;
856 msg
= devfs_msg_send_sync(DEVFS_SCAN_CALLBACK
, msg
);
864 * Acts as a message drain. Any message that is replied to here gets destroyed
865 * and the memory freed.
868 devfs_msg_autofree_reply(lwkt_port_t port
, lwkt_msg_t msg
)
870 devfs_msg_put((devfs_msg_t
)msg
);
874 * devfs_msg_get allocates a new devfs msg and returns it.
879 return objcache_get(devfs_msg_cache
, M_WAITOK
);
883 * devfs_msg_put deallocates a given devfs msg.
886 devfs_msg_put(devfs_msg_t msg
)
888 objcache_put(devfs_msg_cache
, msg
);
893 * devfs_msg_send is the generic asynchronous message sending facility
894 * for devfs. By default the reply port is the automatic disposal port.
896 * If the current thread is the devfs_msg_port thread we execute the
897 * operation synchronously.
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
;
908 if (port
->mpu_td
== curthread
) {
909 devfs_msg_exec(devfs_msg
);
910 lwkt_replymsg(&devfs_msg
->hdr
, 0);
912 lwkt_sendmsg(port
, (lwkt_msg_t
)devfs_msg
);
917 * devfs_msg_send_sync is the generic synchronous message sending
918 * facility for devfs. It initializes a local reply port and waits
919 * for the core's answer. This answer is then returned.
922 devfs_msg_send_sync(uint32_t cmd
, devfs_msg_t devfs_msg
)
924 struct lwkt_port rep_port
;
925 devfs_msg_t msg_incoming
;
926 lwkt_port_t port
= &devfs_msg_port
;
928 lwkt_initport_thread(&rep_port
, curthread
);
929 lwkt_initmsg(&devfs_msg
->hdr
, &rep_port
, 0);
931 devfs_msg
->hdr
.u
.ms_result
= cmd
;
933 lwkt_sendmsg(port
, (lwkt_msg_t
)devfs_msg
);
934 msg_incoming
= lwkt_waitport(&rep_port
, 0);
940 * sends a message with a generic argument.
943 devfs_msg_send_generic(uint32_t cmd
, void *load
)
945 devfs_msg_t devfs_msg
= devfs_msg_get();
947 devfs_msg
->mdv_load
= load
;
948 devfs_msg_send(cmd
, devfs_msg
);
952 * sends a message with a name argument.
955 devfs_msg_send_name(uint32_t cmd
, char *name
)
957 devfs_msg_t devfs_msg
= devfs_msg_get();
959 devfs_msg
->mdv_name
= name
;
960 devfs_msg_send(cmd
, devfs_msg
);
964 * sends a message with a mount argument.
967 devfs_msg_send_mount(uint32_t cmd
, struct devfs_mnt_data
*mnt
)
969 devfs_msg_t devfs_msg
= devfs_msg_get();
971 devfs_msg
->mdv_mnt
= mnt
;
972 devfs_msg_send(cmd
, devfs_msg
);
976 * sends a message with an ops argument.
979 devfs_msg_send_ops(uint32_t cmd
, struct dev_ops
*ops
, int minor
)
981 devfs_msg_t devfs_msg
= devfs_msg_get();
983 devfs_msg
->mdv_ops
.ops
= ops
;
984 devfs_msg
->mdv_ops
.minor
= minor
;
985 devfs_msg_send(cmd
, devfs_msg
);
989 * sends a message with a clone handler argument.
992 devfs_msg_send_chandler(uint32_t cmd
, char *name
, d_clone_t handler
)
994 devfs_msg_t devfs_msg
= devfs_msg_get();
996 devfs_msg
->mdv_chandler
.name
= name
;
997 devfs_msg
->mdv_chandler
.nhandler
= handler
;
998 devfs_msg_send(cmd
, devfs_msg
);
1002 * sends a message with a device argument.
1005 devfs_msg_send_dev(uint32_t cmd
, cdev_t dev
, uid_t uid
, gid_t gid
, int perms
)
1007 devfs_msg_t devfs_msg
= devfs_msg_get();
1009 devfs_msg
->mdv_dev
.dev
= dev
;
1010 devfs_msg
->mdv_dev
.uid
= uid
;
1011 devfs_msg
->mdv_dev
.gid
= gid
;
1012 devfs_msg
->mdv_dev
.perms
= perms
;
1014 devfs_msg_send(cmd
, devfs_msg
);
1018 * sends a message with a link argument.
1021 devfs_msg_send_link(uint32_t cmd
, char *name
, char *target
, struct mount
*mp
)
1023 devfs_msg_t devfs_msg
= devfs_msg_get();
1025 devfs_msg
->mdv_link
.name
= name
;
1026 devfs_msg
->mdv_link
.target
= target
;
1027 devfs_msg
->mdv_link
.mp
= mp
;
1028 devfs_msg_send(cmd
, devfs_msg
);
1032 * devfs_msg_core is the main devfs thread. It handles all incoming messages
1033 * and calls the relevant worker functions. By using messages it's assured
1034 * that events occur in the correct order.
1037 devfs_msg_core(void *arg
)
1042 lwkt_initport_thread(&devfs_msg_port
, curthread
);
1046 msg
= (devfs_msg_t
)lwkt_waitport(&devfs_msg_port
, 0);
1047 devfs_debug(DEVFS_DEBUG_DEBUG
,
1048 "devfs_msg_core, new msg: %x\n",
1049 (unsigned int)msg
->hdr
.u
.ms_result
);
1050 devfs_msg_exec(msg
);
1051 lwkt_replymsg(&msg
->hdr
, 0);
1058 devfs_msg_exec(devfs_msg_t msg
)
1060 struct devfs_mnt_data
*mnt
;
1061 struct devfs_node
*node
;
1065 * Acquire the devfs lock to ensure safety of all called functions
1067 lockmgr(&devfs_lock
, LK_EXCLUSIVE
);
1069 switch (msg
->hdr
.u
.ms_result
) {
1070 case DEVFS_DEVICE_CREATE
:
1071 dev
= msg
->mdv_dev
.dev
;
1072 devfs_create_dev_worker(dev
,
1075 msg
->mdv_dev
.perms
);
1077 case DEVFS_DEVICE_DESTROY
:
1078 dev
= msg
->mdv_dev
.dev
;
1079 devfs_destroy_dev_worker(dev
);
1081 case DEVFS_DESTROY_SUBNAMES
:
1082 devfs_destroy_subnames_worker(msg
->mdv_load
);
1084 case DEVFS_DESTROY_DEV_BY_OPS
:
1085 devfs_destroy_dev_by_ops_worker(msg
->mdv_ops
.ops
,
1086 msg
->mdv_ops
.minor
);
1088 case DEVFS_CREATE_ALL_DEV
:
1089 node
= (struct devfs_node
*)msg
->mdv_load
;
1090 devfs_create_all_dev_worker(node
);
1092 case DEVFS_MOUNT_ADD
:
1094 TAILQ_INSERT_TAIL(&devfs_mnt_list
, mnt
, link
);
1095 devfs_create_all_dev_worker(mnt
->root_node
);
1097 case DEVFS_MOUNT_DEL
:
1099 TAILQ_REMOVE(&devfs_mnt_list
, mnt
, link
);
1100 devfs_reaperp(mnt
->root_node
);
1101 if (mnt
->leak_count
) {
1102 devfs_debug(DEVFS_DEBUG_SHOW
,
1103 "Leaked %d devfs_node elements!\n",
1107 case DEVFS_CHANDLER_ADD
:
1108 devfs_chandler_add_worker(msg
->mdv_chandler
.name
,
1109 msg
->mdv_chandler
.nhandler
);
1111 case DEVFS_CHANDLER_DEL
:
1112 devfs_chandler_del_worker(msg
->mdv_chandler
.name
);
1114 case DEVFS_FIND_DEVICE_BY_NAME
:
1115 devfs_find_device_by_name_worker(msg
);
1117 case DEVFS_FIND_DEVICE_BY_UDEV
:
1118 devfs_find_device_by_udev_worker(msg
);
1120 case DEVFS_MAKE_ALIAS
:
1121 devfs_make_alias_worker((struct devfs_alias
*)msg
->mdv_load
);
1123 case DEVFS_APPLY_RULES
:
1124 devfs_apply_reset_rules_caller(msg
->mdv_name
, 1);
1126 case DEVFS_RESET_RULES
:
1127 devfs_apply_reset_rules_caller(msg
->mdv_name
, 0);
1129 case DEVFS_SCAN_CALLBACK
:
1130 devfs_scan_callback_worker((devfs_scan_t
*)msg
->mdv_load
);
1132 case DEVFS_CLR_SUBNAMES_FLAG
:
1133 devfs_clr_subnames_flag_worker(msg
->mdv_flags
.name
,
1134 msg
->mdv_flags
.flag
);
1136 case DEVFS_DESTROY_SUBNAMES_WO_FLAG
:
1137 devfs_destroy_subnames_without_flag_worker(msg
->mdv_flags
.name
,
1138 msg
->mdv_flags
.flag
);
1140 case DEVFS_INODE_TO_VNODE
:
1141 msg
->mdv_ino
.vp
= devfs_inode_to_vnode_worker(
1142 DEVFS_MNTDATA(msg
->mdv_ino
.mp
)->root_node
,
1145 case DEVFS_TERMINATE_CORE
:
1151 devfs_debug(DEVFS_DEBUG_WARNING
,
1152 "devfs_msg_core: unknown message "
1153 "received at core\n");
1156 lockmgr(&devfs_lock
, LK_RELEASE
);
1160 * Worker function to insert a new dev into the dev list and initialize its
1161 * permissions. It also calls devfs_propagate_dev which in turn propagates
1162 * the change to all mount points.
1164 * The passed dev is already referenced. This reference is eaten by this
1165 * function and represents the dev's linkage into devfs_dev_list.
1168 devfs_create_dev_worker(cdev_t dev
, uid_t uid
, gid_t gid
, int perms
)
1174 dev
->si_perms
= perms
;
1176 devfs_link_dev(dev
);
1177 devfs_propagate_dev(dev
, 1);
1183 * Worker function to delete a dev from the dev list and free the cdev.
1184 * It also calls devfs_propagate_dev which in turn propagates the change
1185 * to all mount points.
1188 devfs_destroy_dev_worker(cdev_t dev
)
1193 KKASSERT((lockstatus(&devfs_lock
, curthread
)) == LK_EXCLUSIVE
);
1195 error
= devfs_unlink_dev(dev
);
1196 devfs_propagate_dev(dev
, 0);
1198 release_dev(dev
); /* link ref */
1206 * Worker function to destroy all devices with a certain basename.
1207 * Calls devfs_destroy_dev_worker for the actual destruction.
1210 devfs_destroy_subnames_worker(char *name
)
1213 size_t len
= strlen(name
);
1215 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1216 if ((!strncmp(dev
->si_name
, name
, len
)) &&
1217 (dev
->si_name
[len
] != '\0')) {
1218 devfs_destroy_dev_worker(dev
);
1225 devfs_clr_subnames_flag_worker(char *name
, uint32_t flag
)
1228 size_t len
= strlen(name
);
1230 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1231 if ((!strncmp(dev
->si_name
, name
, len
)) &&
1232 (dev
->si_name
[len
] != '\0')) {
1233 dev
->si_flags
&= ~flag
;
1241 devfs_destroy_subnames_without_flag_worker(char *name
, uint32_t flag
)
1244 size_t len
= strlen(name
);
1246 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1247 if ((!strncmp(dev
->si_name
, name
, len
)) &&
1248 (dev
->si_name
[len
] != '\0')) {
1249 if (!(dev
->si_flags
& flag
)) {
1250 devfs_destroy_dev_worker(dev
);
1259 * Worker function that creates all device nodes on top of a devfs
1263 devfs_create_all_dev_worker(struct devfs_node
*root
)
1269 TAILQ_FOREACH(dev
, &devfs_dev_list
, link
) {
1270 devfs_create_device_node(root
, dev
, NULL
, NULL
);
1277 * Worker function that destroys all devices that match a specific
1278 * dev_ops and/or minor. If minor is less than 0, it is not matched
1279 * against. It also propagates all changes.
1282 devfs_destroy_dev_by_ops_worker(struct dev_ops
*ops
, int minor
)
1288 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1289 if (dev
->si_ops
!= ops
)
1291 if ((minor
< 0) || (dev
->si_uminor
== minor
)) {
1292 devfs_destroy_dev_worker(dev
);
1300 * Worker function that registers a new clone handler in devfs.
1303 devfs_chandler_add_worker(char *name
, d_clone_t
*nhandler
)
1305 struct devfs_clone_handler
*chandler
= NULL
;
1306 u_char len
= strlen(name
);
1311 TAILQ_FOREACH(chandler
, &devfs_chandler_list
, link
) {
1312 if (chandler
->namlen
!= len
)
1315 if (!memcmp(chandler
->name
, name
, len
)) {
1316 /* Clonable basename already exists */
1321 chandler
= kmalloc(sizeof(*chandler
), M_DEVFS
, M_WAITOK
| M_ZERO
);
1322 chandler
->name
= kmalloc(len
+1, M_DEVFS
, M_WAITOK
);
1323 memcpy(chandler
->name
, name
, len
+1);
1324 chandler
->namlen
= len
;
1325 chandler
->nhandler
= nhandler
;
1327 TAILQ_INSERT_TAIL(&devfs_chandler_list
, chandler
, link
);
1332 * Worker function that removes a given clone handler from the
1333 * clone handler list.
1336 devfs_chandler_del_worker(char *name
)
1338 struct devfs_clone_handler
*chandler
, *chandler2
;
1339 u_char len
= strlen(name
);
1344 TAILQ_FOREACH_MUTABLE(chandler
, &devfs_chandler_list
, link
, chandler2
) {
1345 if (chandler
->namlen
!= len
)
1347 if (memcmp(chandler
->name
, name
, len
))
1350 TAILQ_REMOVE(&devfs_chandler_list
, chandler
, link
);
1351 kfree(chandler
->name
, M_DEVFS
);
1352 kfree(chandler
, M_DEVFS
);
1360 * Worker function that finds a given device name and changes
1361 * the message received accordingly so that when replied to,
1362 * the answer is returned to the caller.
1365 devfs_find_device_by_name_worker(devfs_msg_t devfs_msg
)
1367 struct devfs_alias
*alias
;
1369 cdev_t found
= NULL
;
1371 TAILQ_FOREACH(dev
, &devfs_dev_list
, link
) {
1372 if (strcmp(devfs_msg
->mdv_name
, dev
->si_name
) == 0) {
1377 if (found
== NULL
) {
1378 TAILQ_FOREACH(alias
, &devfs_alias_list
, link
) {
1379 if (strcmp(devfs_msg
->mdv_name
, alias
->name
) == 0) {
1380 found
= alias
->dev_target
;
1385 devfs_msg
->mdv_cdev
= found
;
1391 * Worker function that finds a given device udev and changes
1392 * the message received accordingly so that when replied to,
1393 * the answer is returned to the caller.
1396 devfs_find_device_by_udev_worker(devfs_msg_t devfs_msg
)
1399 cdev_t found
= NULL
;
1401 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1402 if (((udev_t
)dev
->si_inode
) == devfs_msg
->mdv_udev
) {
1407 devfs_msg
->mdv_cdev
= found
;
1413 * Worker function that inserts a given alias into the
1414 * alias list, and propagates the alias to all mount
1418 devfs_make_alias_worker(struct devfs_alias
*alias
)
1420 struct devfs_alias
*alias2
;
1421 size_t len
= strlen(alias
->name
);
1424 TAILQ_FOREACH(alias2
, &devfs_alias_list
, link
) {
1425 if (len
!= alias2
->namlen
)
1428 if (!memcmp(alias
->name
, alias2
->name
, len
)) {
1436 * The alias doesn't exist yet, so we add it to the alias list
1438 TAILQ_INSERT_TAIL(&devfs_alias_list
, alias
, link
);
1439 devfs_alias_propagate(alias
);
1441 devfs_debug(DEVFS_DEBUG_WARNING
,
1442 "Warning: duplicate devfs_make_alias for %s\n",
1444 kfree(alias
->name
, M_DEVFS
);
1445 kfree(alias
, M_DEVFS
);
1452 * Function that removes and frees all aliases.
1455 devfs_alias_reap(void)
1457 struct devfs_alias
*alias
, *alias2
;
1459 TAILQ_FOREACH_MUTABLE(alias
, &devfs_alias_list
, link
, alias2
) {
1460 TAILQ_REMOVE(&devfs_alias_list
, alias
, link
);
1461 kfree(alias
, M_DEVFS
);
1467 * Function that removes an alias matching a specific cdev and frees
1471 devfs_alias_remove(cdev_t dev
)
1473 struct devfs_alias
*alias
, *alias2
;
1475 TAILQ_FOREACH_MUTABLE(alias
, &devfs_alias_list
, link
, alias2
) {
1476 if (alias
->dev_target
== dev
) {
1477 TAILQ_REMOVE(&devfs_alias_list
, alias
, link
);
1478 kfree(alias
, M_DEVFS
);
1485 * This function propagates a new alias to all mount points.
1488 devfs_alias_propagate(struct devfs_alias
*alias
)
1490 struct devfs_mnt_data
*mnt
;
1492 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1493 devfs_alias_apply(mnt
->root_node
, alias
);
1499 * This function is a recursive function iterating through
1500 * all device nodes in the topology and, if applicable,
1501 * creating the relevant alias for a device node.
1504 devfs_alias_apply(struct devfs_node
*node
, struct devfs_alias
*alias
)
1506 struct devfs_node
*node1
, *node2
;
1508 KKASSERT(alias
!= NULL
);
1510 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1511 if (node
->nchildren
> 2) {
1512 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1513 devfs_alias_apply(node1
, alias
);
1517 if (node
->d_dev
== alias
->dev_target
)
1518 devfs_alias_create(alias
->name
, node
);
1524 * This function checks if any alias possibly is applicable
1525 * to the given node. If so, the alias is created.
1528 devfs_alias_check_create(struct devfs_node
*node
)
1530 struct devfs_alias
*alias
;
1532 TAILQ_FOREACH(alias
, &devfs_alias_list
, link
) {
1533 if (node
->d_dev
== alias
->dev_target
)
1534 devfs_alias_create(alias
->name
, node
);
1540 * This function creates an alias with a given name
1541 * linking to a given devfs node. It also increments
1542 * the link count on the target node.
1545 devfs_alias_create(char *name_orig
, struct devfs_node
*target
)
1547 struct mount
*mp
= target
->mp
;
1548 struct devfs_node
*parent
= DEVFS_MNTDATA(mp
)->root_node
;
1549 struct devfs_node
*linknode
;
1550 char *create_path
= NULL
;
1551 char *name
, name_buf
[PATH_MAX
];
1553 KKASSERT((lockstatus(&devfs_lock
, curthread
)) == LK_EXCLUSIVE
);
1555 devfs_resolve_name_path(name_orig
, name_buf
, &create_path
, &name
);
1558 parent
= devfs_resolve_or_create_path(parent
, create_path
, 1);
1561 if (devfs_find_device_node_by_name(parent
, name
)) {
1562 devfs_debug(DEVFS_DEBUG_WARNING
,
1563 "Node already exists: %s "
1564 "(devfs_make_alias_worker)!\n",
1570 linknode
= devfs_allocp(Plink
, name
, parent
, mp
, NULL
);
1571 if (linknode
== NULL
)
1574 linknode
->link_target
= target
;
1581 * This function is called by the core and handles mount point
1582 * strings. It either calls the relevant worker (devfs_apply_
1583 * reset_rules_worker) on all mountpoints or only a specific
1587 devfs_apply_reset_rules_caller(char *mountto
, int apply
)
1589 struct devfs_mnt_data
*mnt
;
1590 size_t len
= strlen(mountto
);
1592 if (mountto
[0] == '*') {
1593 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1594 devfs_apply_reset_rules_worker(mnt
->root_node
, apply
);
1597 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1598 if ((len
!= mnt
->mntonnamelen
))
1601 if (!memcmp(mnt
->mp
->mnt_stat
.f_mntonname
, mountto
, len
)) {
1602 devfs_apply_reset_rules_worker(mnt
->root_node
, apply
);
1608 kfree(mountto
, M_DEVFS
);
1613 * This worker function applies or resets, depending on the arguments, a rule
1614 * to the whole given topology. *RECURSIVE*
1617 devfs_apply_reset_rules_worker(struct devfs_node
*node
, int apply
)
1619 struct devfs_node
*node1
, *node2
;
1621 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1622 if (node
->nchildren
> 2) {
1623 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1624 devfs_apply_reset_rules_worker(node1
, apply
);
1630 devfs_rule_check_apply(node
);
1632 devfs_rule_reset_node(node
);
1639 * This function calls a given callback function for
1640 * every dev node in the devfs dev list.
1643 devfs_scan_callback_worker(devfs_scan_t
*callback
)
1647 TAILQ_FOREACH_MUTABLE(dev
, &devfs_dev_list
, link
, dev1
) {
1656 * This function tries to resolve a given directory, or if not
1657 * found and creation requested, creates the given directory.
1659 static struct devfs_node
*
1660 devfs_resolve_or_create_dir(struct devfs_node
*parent
, char *dir_name
,
1661 size_t name_len
, int create
)
1663 struct devfs_node
*node
, *found
= NULL
;
1665 TAILQ_FOREACH(node
, DEVFS_DENODE_HEAD(parent
), link
) {
1666 if (name_len
!= node
->d_dir
.d_namlen
)
1669 if (!memcmp(dir_name
, node
->d_dir
.d_name
, name_len
)) {
1675 if ((found
== NULL
) && (create
)) {
1676 found
= devfs_allocp(Pdir
, dir_name
, parent
, parent
->mp
, NULL
);
1683 * This function tries to resolve a complete path. If creation is requested,
1684 * if a given part of the path cannot be resolved (because it doesn't exist),
1688 devfs_resolve_or_create_path(struct devfs_node
*parent
, char *path
, int create
)
1690 struct devfs_node
*node
= parent
;
1699 for (; *path
!= '\0' ; path
++) {
1704 node
= devfs_resolve_or_create_dir(node
, buf
, idx
, create
);
1711 return devfs_resolve_or_create_dir(node
, buf
, idx
, create
);
1715 * Takes a full path and strips it into a directory path and a name.
1716 * For a/b/c/foo, it returns foo in namep and a/b/c in pathp. It
1717 * requires a working buffer with enough size to keep the whole
1721 devfs_resolve_name_path(char *fullpath
, char *buf
, char **pathp
, char **namep
)
1725 size_t len
= strlen(fullpath
) + 1;
1728 KKASSERT((fullpath
!= NULL
) && (buf
!= NULL
));
1729 KKASSERT((pathp
!= NULL
) && (namep
!= NULL
));
1731 memcpy(buf
, fullpath
, len
);
1733 for (i
= len
-1; i
>= 0; i
--) {
1734 if (buf
[i
] == '/') {
1754 * This function creates a new devfs node for a given device. It can
1755 * handle a complete path as device name, and accordingly creates
1756 * the path and the final device node.
1758 * The reference count on the passed dev remains unchanged.
1761 devfs_create_device_node(struct devfs_node
*root
, cdev_t dev
,
1762 char *dev_name
, char *path_fmt
, ...)
1764 struct devfs_node
*parent
, *node
= NULL
;
1766 char *name
, name_buf
[PATH_MAX
];
1770 char *create_path
= NULL
;
1771 char *names
= "pqrsPQRS";
1773 if (path_fmt
!= NULL
) {
1774 path
= kmalloc(PATH_MAX
+1, M_DEVFS
, M_WAITOK
);
1776 __va_start(ap
, path_fmt
);
1777 i
= kvcprintf(path_fmt
, NULL
, path
, 10, ap
);
1782 parent
= devfs_resolve_or_create_path(root
, path
, 1);
1785 devfs_resolve_name_path(
1786 ((dev_name
== NULL
) && (dev
))?(dev
->si_name
):(dev_name
),
1787 name_buf
, &create_path
, &name
);
1790 parent
= devfs_resolve_or_create_path(parent
, create_path
, 1);
1793 if (devfs_find_device_node_by_name(parent
, name
)) {
1794 devfs_debug(DEVFS_DEBUG_WARNING
, "devfs_create_device_node: "
1795 "DEVICE %s ALREADY EXISTS!!! Ignoring creation request.\n", name
);
1799 node
= devfs_allocp(Pdev
, name
, parent
, parent
->mp
, dev
);
1803 * Ugly unix98 pty magic, to hide pty master (ptm) devices and their
1806 if ((dev
) && (strlen(dev
->si_name
) >= 4) &&
1807 (!memcmp(dev
->si_name
, "ptm/", 4))) {
1808 node
->parent
->flags
|= DEVFS_HIDDEN
;
1809 node
->flags
|= DEVFS_HIDDEN
;
1814 * Ugly pty magic, to tag pty devices as such and hide them if needed.
1816 if ((strlen(name
) >= 3) && (!memcmp(name
, "pty", 3)))
1817 node
->flags
|= (DEVFS_PTY
| DEVFS_INVISIBLE
);
1819 if ((strlen(name
) >= 3) && (!memcmp(name
, "tty", 3))) {
1821 for (i
= 0; i
< strlen(names
); i
++) {
1822 if (name
[3] == names
[i
]) {
1828 node
->flags
|= (DEVFS_PTY
| DEVFS_INVISIBLE
);
1832 if (path_fmt
!= NULL
)
1833 kfree(path
, M_DEVFS
);
1839 * This function finds a given device node in the topology with a given
1843 devfs_find_device_node(struct devfs_node
*node
, cdev_t target
)
1845 struct devfs_node
*node1
, *node2
, *found
= NULL
;
1847 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1848 if (node
->nchildren
> 2) {
1849 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1850 if ((found
= devfs_find_device_node(node1
, target
)))
1854 } else if (node
->node_type
== Pdev
) {
1855 if (node
->d_dev
== target
)
1863 * This function finds a device node in the topology by its
1864 * name and returns it.
1867 devfs_find_device_node_by_name(struct devfs_node
*parent
, char *target
)
1869 struct devfs_node
*node
, *found
= NULL
;
1870 size_t len
= strlen(target
);
1872 TAILQ_FOREACH(node
, DEVFS_DENODE_HEAD(parent
), link
) {
1873 if (len
!= node
->d_dir
.d_namlen
)
1876 if (!memcmp(node
->d_dir
.d_name
, target
, len
)) {
1885 static struct vnode
*
1886 devfs_inode_to_vnode_worker(struct devfs_node
*node
, ino_t target
)
1888 struct devfs_node
*node1
, *node2
;
1891 if ((node
->node_type
== Proot
) || (node
->node_type
== Pdir
)) {
1892 if (node
->nchildren
> 2) {
1893 TAILQ_FOREACH_MUTABLE(node1
, DEVFS_DENODE_HEAD(node
), link
, node2
) {
1894 if ((vp
= devfs_inode_to_vnode_worker(node1
, target
)))
1900 if (node
->d_dir
.d_ino
== target
) {
1903 vget(vp
, LK_EXCLUSIVE
| LK_RETRY
);
1906 devfs_allocv(&vp
, node
);
1916 * This function takes a cdev and removes its devfs node in the
1917 * given topology. The cdev remains intact.
1920 devfs_destroy_device_node(struct devfs_node
*root
, cdev_t target
)
1922 struct devfs_node
*node
, *parent
;
1923 char *name
, name_buf
[PATH_MAX
];
1924 char *create_path
= NULL
;
1928 memcpy(name_buf
, target
->si_name
, strlen(target
->si_name
)+1);
1930 devfs_resolve_name_path(target
->si_name
, name_buf
, &create_path
, &name
);
1933 parent
= devfs_resolve_or_create_path(root
, create_path
, 0);
1940 node
= devfs_find_device_node_by_name(parent
, name
);
1949 * Just set perms and ownership for given node.
1952 devfs_set_perms(struct devfs_node
*node
, uid_t uid
, gid_t gid
,
1953 u_short mode
, u_long flags
)
1963 * Propagates a device attach/detach to all mount
1964 * points. Also takes care of automatic alias removal
1965 * for a deleted cdev.
1968 devfs_propagate_dev(cdev_t dev
, int attach
)
1970 struct devfs_mnt_data
*mnt
;
1972 TAILQ_FOREACH(mnt
, &devfs_mnt_list
, link
) {
1974 /* Device is being attached */
1975 devfs_create_device_node(mnt
->root_node
, dev
,
1978 /* Device is being detached */
1979 devfs_alias_remove(dev
);
1980 devfs_destroy_device_node(mnt
->root_node
, dev
);
1987 * devfs_node_to_path takes a node and a buffer of a size of
1988 * at least PATH_MAX, resolves the full path from the root
1989 * node and writes it in a humanly-readable format into the
1991 * If DEVFS_STASH_DEPTH is less than the directory level up
1992 * to the root node, only the last DEVFS_STASH_DEPTH levels
1993 * of the path are resolved.
1996 devfs_node_to_path(struct devfs_node
*node
, char *buffer
)
1998 #define DEVFS_STASH_DEPTH 32
1999 struct devfs_node
*node_stash
[DEVFS_STASH_DEPTH
];
2001 memset(buffer
, 0, PATH_MAX
);
2003 for (i
= 0; (i
< DEVFS_STASH_DEPTH
) && (node
->node_type
!= Proot
); i
++) {
2004 node_stash
[i
] = node
;
2005 node
= node
->parent
;
2009 for (offset
= 0; i
>= 0; i
--) {
2010 memcpy(buffer
+offset
, node_stash
[i
]->d_dir
.d_name
,
2011 node_stash
[i
]->d_dir
.d_namlen
);
2012 offset
+= node_stash
[i
]->d_dir
.d_namlen
;
2014 *(buffer
+offset
) = '/';
2018 #undef DEVFS_STASH_DEPTH
2023 * devfs_clone either returns a basename from a complete name by
2024 * returning the length of the name without trailing digits, or,
2025 * if clone != 0, calls the device's clone handler to get a new
2026 * device, which in turn is returned in devp.
2029 devfs_clone(char *name
, size_t *namlenp
, cdev_t
*devp
, int clone
,
2034 size_t len
= *namlenp
;
2036 struct devfs_clone_handler
*chandler
;
2037 struct dev_clone_args ap
;
2040 for (; (len
> 0) && (DEVFS_ISDIGIT(name
[len
-1])); len
--);
2043 TAILQ_FOREACH(chandler
, &devfs_chandler_list
, link
) {
2044 if ((chandler
->namlen
== len
) &&
2045 (!memcmp(chandler
->name
, name
, len
)) &&
2046 (chandler
->nhandler
)) {
2052 error
= (chandler
->nhandler
)(&ap
);
2069 * Registers a new orphan in the orphan list.
2072 devfs_tracer_add_orphan(struct devfs_node
*node
)
2074 struct devfs_orphan
*orphan
;
2077 orphan
= kmalloc(sizeof(struct devfs_orphan
), M_DEVFS
, M_WAITOK
);
2078 orphan
->node
= node
;
2080 KKASSERT((node
->flags
& DEVFS_ORPHANED
) == 0);
2081 node
->flags
|= DEVFS_ORPHANED
;
2082 TAILQ_INSERT_TAIL(DEVFS_ORPHANLIST(node
->mp
), orphan
, link
);
2086 * Removes an orphan from the orphan list.
2089 devfs_tracer_del_orphan(struct devfs_node
*node
)
2091 struct devfs_orphan
*orphan
;
2095 TAILQ_FOREACH(orphan
, DEVFS_ORPHANLIST(node
->mp
), link
) {
2096 if (orphan
->node
== node
) {
2097 node
->flags
&= ~DEVFS_ORPHANED
;
2098 TAILQ_REMOVE(DEVFS_ORPHANLIST(node
->mp
), orphan
, link
);
2099 kfree(orphan
, M_DEVFS
);
2106 * Counts the orphans in the orphan list, and if cleanup
2107 * is specified, also frees the orphan and removes it from
2111 devfs_tracer_orphan_count(struct mount
*mp
, int cleanup
)
2113 struct devfs_orphan
*orphan
, *orphan2
;
2116 TAILQ_FOREACH_MUTABLE(orphan
, DEVFS_ORPHANLIST(mp
), link
, orphan2
) {
2119 * If we are instructed to clean up, we do so.
2122 TAILQ_REMOVE(DEVFS_ORPHANLIST(mp
), orphan
, link
);
2123 orphan
->node
->flags
&= ~DEVFS_ORPHANED
;
2124 devfs_freep(orphan
->node
);
2125 kfree(orphan
, M_DEVFS
);
2133 * Fetch an ino_t from the global d_ino by increasing it
2137 devfs_fetch_ino(void)
2141 spin_lock_wr(&ino_lock
);
2143 spin_unlock_wr(&ino_lock
);
2149 * Allocates a new cdev and initializes it's most basic
2153 devfs_new_cdev(struct dev_ops
*ops
, int minor
)
2155 cdev_t dev
= sysref_alloc(&cdev_sysref_class
);
2156 sysref_activate(&dev
->si_sysref
);
2158 memset(dev
, 0, offsetof(struct cdev
, si_sysref
));
2163 dev
->si_drv1
= NULL
;
2164 dev
->si_drv2
= NULL
;
2165 dev
->si_lastread
= 0; /* time_second */
2166 dev
->si_lastwrite
= 0; /* time_second */
2171 dev
->si_uminor
= minor
;
2172 dev
->si_inode
= makeudev(devfs_reference_ops(ops
), minor
);
2178 devfs_cdev_terminate(cdev_t dev
)
2182 /* Check if it is locked already. if not, we acquire the devfs lock */
2183 if (!(lockstatus(&devfs_lock
, curthread
)) == LK_EXCLUSIVE
) {
2184 lockmgr(&devfs_lock
, LK_EXCLUSIVE
);
2188 /* Propagate destruction, just in case */
2189 devfs_propagate_dev(dev
, 0);
2191 /* If we acquired the lock, we also get rid of it */
2193 lockmgr(&devfs_lock
, LK_RELEASE
);
2195 devfs_release_ops(dev
->si_ops
);
2197 /* Finally destroy the device */
2198 sysref_put(&dev
->si_sysref
);
2202 * Links a given cdev into the dev list.
2205 devfs_link_dev(cdev_t dev
)
2207 KKASSERT((dev
->si_flags
& SI_DEVFS_LINKED
) == 0);
2208 dev
->si_flags
|= SI_DEVFS_LINKED
;
2209 TAILQ_INSERT_TAIL(&devfs_dev_list
, dev
, link
);
2215 * Removes a given cdev from the dev list. The caller is responsible for
2216 * releasing the reference on the device associated with the linkage.
2218 * Returns EALREADY if the dev has already been unlinked.
2221 devfs_unlink_dev(cdev_t dev
)
2223 if ((dev
->si_flags
& SI_DEVFS_LINKED
)) {
2224 TAILQ_REMOVE(&devfs_dev_list
, dev
, link
);
2225 dev
->si_flags
&= ~SI_DEVFS_LINKED
;
2232 devfs_node_is_accessible(struct devfs_node
*node
)
2234 if ((node
) && (!(node
->flags
& DEVFS_HIDDEN
)))
2241 devfs_reference_ops(struct dev_ops
*ops
)
2245 if (ops
->head
.refs
== 0) {
2246 ops
->head
.id
= devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(ops_id
), 255);
2247 if (ops
->head
.id
== -1) {
2248 /* Ran out of unique ids */
2249 devfs_debug(DEVFS_DEBUG_WARNING
,
2250 "devfs_reference_ops: WARNING: ran out of unique ids\n");
2253 unit
= ops
->head
.id
;
2260 devfs_release_ops(struct dev_ops
*ops
)
2264 if (ops
->head
.refs
== 0) {
2265 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(ops_id
), ops
->head
.id
);
2274 msg
= devfs_msg_get();
2275 msg
= devfs_msg_send_sync(DEVFS_SYNC
, msg
);
2280 * Called on init of devfs; creates the objcaches and
2281 * spawns off the devfs core thread. Also initializes
2287 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_init() called\n");
2288 /* Create objcaches for nodes, msgs and devs */
2289 devfs_node_cache
= objcache_create("devfs-node-cache", 0, 0,
2291 objcache_malloc_alloc
,
2292 objcache_malloc_free
,
2293 &devfs_node_malloc_args
);
2295 devfs_msg_cache
= objcache_create("devfs-msg-cache", 0, 0,
2297 objcache_malloc_alloc
,
2298 objcache_malloc_free
,
2299 &devfs_msg_malloc_args
);
2301 devfs_dev_cache
= objcache_create("devfs-dev-cache", 0, 0,
2303 objcache_malloc_alloc
,
2304 objcache_malloc_free
,
2305 &devfs_dev_malloc_args
);
2307 devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(ops_id
));
2309 /* Initialize the reply-only port which acts as a message drain */
2310 lwkt_initport_replyonly(&devfs_dispose_port
, devfs_msg_autofree_reply
);
2312 /* Initialize *THE* devfs lock */
2313 lockinit(&devfs_lock
, "devfs_core lock", 0, 0);
2316 lwkt_create(devfs_msg_core
, /*args*/NULL
, &td_core
, NULL
,
2317 0, 0, "devfs_msg_core");
2319 tsleep(td_core
/*devfs_id*/, 0, "devfsc", 0);
2321 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_init finished\n");
2325 * Called on unload of devfs; takes care of destroying the core
2326 * and the objcaches. Also removes aliases that are no longer needed.
2331 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs_uninit() called\n");
2333 devfs_msg_send(DEVFS_TERMINATE_CORE
, NULL
);
2335 tsleep(td_core
/*devfs_id*/, 0, "devfsc", 0);
2336 tsleep(td_core
/*devfs_id*/, 0, "devfsc", 10000);
2338 devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(ops_id
));
2340 /* Destroy the objcaches */
2341 objcache_destroy(devfs_msg_cache
);
2342 objcache_destroy(devfs_node_cache
);
2343 objcache_destroy(devfs_dev_cache
);
2349 * This is a sysctl handler to assist userland devname(3) to
2350 * find the device name for a given udev.
2353 devfs_sysctl_devname_helper(SYSCTL_HANDLER_ARGS
)
2360 if ((error
= SYSCTL_IN(req
, &udev
, sizeof(udev_t
))))
2363 devfs_debug(DEVFS_DEBUG_DEBUG
, "devfs sysctl, received udev: %d\n", udev
);
2368 if ((found
= devfs_find_device_by_udev(udev
)) == NULL
)
2371 return(SYSCTL_OUT(req
, found
->si_name
, strlen(found
->si_name
) + 1));
2375 SYSCTL_PROC(_kern
, OID_AUTO
, devname
, CTLTYPE_OPAQUE
|CTLFLAG_RW
|CTLFLAG_ANYBODY
,
2376 NULL
, 0, devfs_sysctl_devname_helper
, "", "helper for devname(3)");
2378 static SYSCTL_NODE(_vfs
, OID_AUTO
, devfs
, CTLFLAG_RW
, 0, "devfs");
2379 TUNABLE_INT("vfs.devfs.debug", &devfs_debug_enable
);
2380 SYSCTL_INT(_vfs_devfs
, OID_AUTO
, debug
, CTLFLAG_RW
, &devfs_debug_enable
,
2381 0, "Enable DevFS debugging");
2383 SYSINIT(vfs_devfs_register
, SI_SUB_PRE_DRIVERS
, SI_ORDER_FIRST
,
2385 SYSUNINIT(vfs_devfs_register
, SI_SUB_PRE_DRIVERS
, SI_ORDER_ANY
,
2386 devfs_uninit
, NULL
);