xref: /dflybsd-src/sys/vfs/devfs/devfs_core.c (revision 3e82b46c18bc48fdb3c1d60729c7661b3a0bf6bf)
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Alex Hornung <ahornung@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #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>
40 #include <sys/lock.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>
50 
51 MALLOC_DEFINE(M_DEVFS, "devfs", "Device File System (devfs) allocations");
52 
53 /*
54  * SYSREF Integration - reference counting, allocation,
55  * sysid and syslink integration.
56  */
57 static void devfs_cdev_terminate(cdev_t dev);
58 static struct sysref_class     cdev_sysref_class = {
59 	.name =         "cdev",
60 	.mtype =        M_DEVFS,
61 	.proto =        SYSREF_PROTO_DEV,
62 	.offset =       offsetof(struct cdev, si_sysref),
63 	.objsize =      sizeof(struct cdev),
64 	.mag_capacity = 32,
65 	.flags =        0,
66 	.ops =  {
67 		.terminate = (sysref_terminate_func_t)devfs_cdev_terminate
68 	}
69 };
70 
71 static struct objcache	*devfs_node_cache;
72 static struct objcache 	*devfs_msg_cache;
73 static struct objcache	*devfs_dev_cache;
74 
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 };
81 
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);
86 
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;
91 //static void *devfs_id = (void *)0xDE33A;
92 
93 static ino_t 	d_ino = 0;
94 static __uint32_t	msg_id = 0;
95 static struct spinlock  ino_lock;
96 static int devfs_debug_enable = 0;
97 
98 static ino_t devfs_fetch_ino(void);
99 static int devfs_gc_dirs(struct devfs_node *);
100 static int devfs_gc_links(struct devfs_node *, struct devfs_node *, size_t);
101 static int devfs_create_all_dev_worker(struct devfs_node *);
102 static int devfs_create_dev_worker(cdev_t, uid_t, gid_t, int);
103 static int devfs_destroy_dev_worker(cdev_t);
104 static int devfs_destroy_subnames_worker(char *);
105 static int devfs_destroy_dev_by_ops_worker(struct dev_ops *, int);
106 static int devfs_propagate_dev(cdev_t, int);
107 
108 static int devfs_chandler_add_worker(char *, d_clone_t *);
109 static int devfs_chandler_del_worker(char *);
110 
111 static void devfs_msg_autofree_reply(lwkt_port_t, lwkt_msg_t);
112 static void devfs_msg_core(void *);
113 
114 static int devfs_find_device_by_name_worker(devfs_msg_t);
115 static int devfs_find_device_by_udev_worker(devfs_msg_t);
116 
117 static int devfs_apply_reset_rules_caller(char *, int);
118 static int devfs_apply_reset_rules_worker(struct devfs_node *, int);
119 
120 static int devfs_scan_callback_worker(devfs_scan_t *);
121 
122 static struct devfs_node *devfs_resolve_or_create_dir(struct devfs_node *, char *, size_t, int);
123 
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 *);
130 
131 /*
132  * devfs_debug() is a SYSCTL and TUNABLE controlled debug output function using kvprintf
133  */
134 int
135 devfs_debug(int level, char *fmt, ...)
136 {
137 	__va_list ap;
138 
139 	__va_start(ap, fmt);
140 	if (level <= devfs_debug_enable)
141 		kvprintf(fmt, ap);
142 	__va_end(ap);
143 
144 	return 0;
145 }
146 
147 /*
148  * devfs_allocp() Allocates a new devfs node with the specified parameters. The node is also automatically linked
149  * into the topology if a parent is specified. It also calls the rule and alias stuff to be applied on the new
150  * node
151  */
152 struct devfs_node *
153 devfs_allocp(devfs_nodetype devfsnodetype, char *name, struct devfs_node *parent, struct mount *mp, cdev_t dev)
154 {
155 	struct devfs_node *node = NULL;
156 	size_t namlen = strlen(name);
157 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocp -1- for %s\n", name?name:"NULL");
158 
159 	node = objcache_get(devfs_node_cache, M_WAITOK);
160 
161 	atomic_add_int(&(DEVFS_MNTDATA(mp)->leak_count), 1);
162 
163 	node->nchildren = 1;
164 	node->mp = mp;
165 	node->d_dir.d_ino = devfs_fetch_ino();
166 	node->flags = 0;
167 	node->cookie_jar = 2; /* Leave 0 and 1 for '.' and '..', respectively */
168 
169 	/* Access Control members */
170 	node->mode = DEVFS_DEFAULT_MODE;	/* files access mode and type */
171 	node->uid = DEVFS_DEFAULT_UID;		/* owner user id */
172 	node->gid = DEVFS_DEFAULT_GID;		/* owner group id */
173 
174 	/* Null the symlink */
175 	node->symlink_name = NULL;
176 	node->symlink_namelen = 0;
177 	node->link_target = NULL;
178 
179 	/* Null the count of links to this node */
180 	node->nlinks = 0;
181 
182 	switch (devfsnodetype) {
183 	case Proot:
184 		node->flags |= DEVFS_NODE_LINKED; //Make sure we don't recycle the root vnode
185 	case Pdir:
186 		TAILQ_INIT(DEVFS_DENODE_HEAD(node));
187 		node->d_dir.d_type = DT_DIR;
188 		node->nchildren = 2;
189 		break;
190 
191 	case Plink:
192 		node->d_dir.d_type = DT_LNK;
193 		break;
194 
195 	case Preg:
196 		node->d_dir.d_type = DT_REG;
197 		break;
198 
199 	case Pdev:
200 		if (dev != NULL) {
201 			node->d_dir.d_type = DT_CHR;
202 			node->d_dev = dev;
203 			node->d_dir.d_ino = dev->si_inode;
204 
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 */
208 
209 			devfs_alias_check_create(node);
210 		}
211 		break;
212 
213 	default:
214 		panic("devfs_allocp: unknown node type");
215 	}
216 
217 	node->v_node = NULL;
218 	node->node_type = devfsnodetype;
219 
220 	/* Init the dirent structure of each devfs vnode */
221 	node->d_dir.d_namlen = namlen;
222 	memcpy(node->d_dir.d_name, name, namlen);
223 	node->d_dir.d_name[namlen] = '\0';
224 
225 	/* Initialize the parent node element */
226 	node->parent = parent;
227 
228 	/* Apply rules */
229 	devfs_rule_check_apply(node);
230 
231 	/* If there is a parent, increment the number of his children and add the new
232 	 * child to the parent's list of children */
233 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocp: about to insert node\n");
234 	if ((parent != NULL) &&
235 		((parent->node_type == Proot) || (parent->node_type == Pdir))) {
236 		TAILQ_INSERT_TAIL(DEVFS_DENODE_HEAD(parent), node, link);
237 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocp: node inserted\n");
238 		parent->nchildren++;
239 		node->cookie = parent->cookie_jar++;
240 		node->flags |= DEVFS_NODE_LINKED;
241 	}
242 
243 	/* xtime members */
244 	nanotime(&node->atime);
245 	node->mtime = node->ctime = node->atime;
246 
247 	/* Null out open references to this "file" */
248 	node->refs = 0;
249 
250 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocp -end:2-\n");
251 	return node;
252 }
253 
254 /*
255  * devfs_allocv() allocates a new vnode based on a devfs node.
256  */
257 int
258 devfs_allocv(struct vnode **vpp, struct devfs_node *node)
259 {
260 	struct vnode *vp;
261 	int error = 0;
262 
263 	KKASSERT(node);
264 
265 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -1-\n");
266 
267 try_again:
268 	while ((vp = node->v_node) != NULL) {
269 		error = vget(vp, LK_EXCLUSIVE);
270 		if (error != ENOENT) {
271 			*vpp = vp;
272 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv, code path 2...\n");
273 			goto out;
274 		}
275 	}
276 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -3-\n");
277 
278 	//XXX: afaik getnewvnode doesn't return anything but 0.
279 
280 	if ((error = getnewvnode(VT_DEVFS, node->mp, vpp, 0, 0)) != 0)
281 		goto out;
282 
283 	vp = *vpp;
284 
285 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -4-\n");
286 
287 	if (node->v_node != NULL) {
288 		vp->v_type = VBAD;
289 		vx_put(vp);
290 		goto try_again;
291 	}
292 
293 	vp->v_data = node;
294 	node->v_node = vp;
295 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -5-\n");
296 
297 	switch (node->node_type) {
298 	case Proot:
299 		vp->v_flag |= VROOT;
300 	case Pdir:
301 		vp->v_type = VDIR;
302 		break;
303 
304 	case Plink:
305 		vp->v_type = VLNK;
306 		break;
307 
308 	case Preg:
309 		vp->v_type = VREG;
310 		break;
311 
312 	case Pdev:
313 		vp->v_type = VCHR;
314 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -6-\n");
315 		KKASSERT(node->d_dev);
316 
317 		if (node->d_dev) {
318 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -7-\n");
319 			vp->v_uminor = node->d_dev->si_uminor;
320 			vp->v_umajor = 0;
321 			vp->v_rdev = node->d_dev;
322 			vp->v_ops = &node->mp->mnt_vn_spec_ops;
323 			//v_associate_rdev(vp, node->d_dev);
324 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -8-\n");
325 		} else {
326 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv: type is Pdev but d_dev is not set!!!!\n");
327 		}
328 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -9-\n");
329 		break;
330 
331 	default:
332 		panic("devfs_allocv: unknown node type");
333 	}
334 
335 out:
336 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -10-\n");
337 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocv -end:11-\n");
338 	return error;
339 }
340 
341 /*
342  * devfs_allocvp allocates both a devfs node (with the given settings) and a vnode
343  * based on the newly created devfs node.
344  */
345 int
346 devfs_allocvp(struct mount *mp, struct vnode **vpp, devfs_nodetype devfsnodetype,
347 				char *name, struct devfs_node *parent, cdev_t dev)
348 {
349 	struct devfs_node *node;
350 
351 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocvp -1-\n");
352 	node = devfs_allocp(devfsnodetype, name, parent, mp, dev);
353 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocvp -2-\n");
354 	if (node != NULL)
355 		devfs_allocv(vpp, node);
356 	else
357 		*vpp = NULL;
358 
359 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_allocvp -end:3-\n");
360 
361 	return 0;
362 }
363 
364 /*
365  * devfs_freep frees a devfs node *ONLY* if it is the root node or the node is not linked
366  * into the topology anymore. It also calls the tracer helper to keep track of possible
367  * orphans.
368  */
369 int
370 devfs_freep(struct devfs_node *node)
371 {
372 	KKASSERT(node);
373 	KKASSERT(((node->flags & DEVFS_NODE_LINKED) == 0) || (node->node_type == Proot));
374 
375 	atomic_subtract_int(&(DEVFS_MNTDATA(node->mp)->leak_count), 1);
376 	if (node->symlink_name)	{
377 		kfree(node->symlink_name, M_DEVFS);
378 		node->symlink_name = NULL;
379 	}
380 
381 	if ((node->flags & DEVFS_NO_TRACE) == 0)
382 		devfs_tracer_del_orphan(node);
383 
384 	//XXX: Add something to make sure that no vnode is associated with this devfs node
385 	objcache_put(devfs_node_cache, node);
386 
387 	return 0;
388 }
389 
390 /*
391  * devfs_unlinkp unlinks a devfs node out of the topology and adds the node
392  * to the orphan list. It is later removed by freep.
393  * If a vnode is still associated to the devfs node, then the vnode's rdev
394  * is NULLed.
395  */
396 int
397 devfs_unlinkp(struct devfs_node *node)
398 {
399 	struct devfs_node *parent;
400 	KKASSERT(node);
401 
402 	devfs_tracer_add_orphan(node);
403 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_unlinkp for %s\n", node->d_dir.d_name);
404 	parent = node->parent;
405 
406 	/* If the parent is known we can unlink the node out of the topology */
407 	if (parent)	{
408 		TAILQ_REMOVE(DEVFS_DENODE_HEAD(parent), node, link);
409 		parent->nchildren--;
410 		KKASSERT((parent->nchildren >= 0));
411 		node->flags &= ~DEVFS_NODE_LINKED;
412 	}
413 	node->parent = NULL;
414 
415 	/* Invalidate vnode as a device node */
416 	if (node->v_node)
417 		node->v_node->v_rdev = NULL;
418 
419 	return 0;
420 }
421 
422 /*
423  * devfs_reaperp() is a recursive function that iterates through all the topology,
424  * unlinking and freeing all devfs nodes.
425  */
426 int
427 devfs_reaperp(struct devfs_node *node)
428 {
429 	struct devfs_node *node1, *node2;
430 
431 	//devfs_debug(DEVFS_DEBUG_DEBUG, "This node is called %s\n", node->d_dir.d_name);
432 	if ((node->node_type == Proot) || (node->node_type == Pdir)) {
433 		devfs_debug(DEVFS_DEBUG_DEBUG, "This node is Pdir or Proot; has %d children\n", node->nchildren);
434 		if (node->nchildren > 2) {
435 			TAILQ_FOREACH_MUTABLE(node1, DEVFS_DENODE_HEAD(node), link, node2)	{
436 				devfs_reaperp(node1);
437 			}
438 		}
439 	}
440 	//devfs_debug(DEVFS_DEBUG_DEBUG, "This node is called %s and it is being freed\n", node->d_dir.d_name);
441 	devfs_unlinkp(node);
442 	devfs_freep(node);
443 
444 	return 0;
445 }
446 
447 /*
448  * devfs_gc() is devfs garbage collector. It takes care of unlinking and freeing a
449  * node, but also removes empty directories and links that link via devfs auto-link
450  * mechanism to the node being deleted.
451  */
452 int
453 devfs_gc(struct devfs_node *node)
454 {
455 	struct devfs_node *root_node = DEVFS_MNTDATA(node->mp)->root_node;
456 
457 	devfs_gc_links(root_node, node, node->nlinks);
458 	devfs_unlinkp(node);
459 	devfs_gc_dirs(root_node);
460 
461 	devfs_freep(node);
462 
463 	return 0;
464 }
465 
466 /*
467  * devfs_gc_dirs() is a helper function for devfs_gc, unlinking and freeing
468  * empty directories.
469  */
470 static int
471 devfs_gc_dirs(struct devfs_node *node)
472 {
473 	struct devfs_node *node1, *node2;
474 
475 	//devfs_debug(DEVFS_DEBUG_DEBUG, "This node is called %s\n", node->d_dir.d_name);
476 
477 	if ((node->node_type == Proot) || (node->node_type == Pdir)) {
478 		devfs_debug(DEVFS_DEBUG_DEBUG, "This node is Pdir or Proot; has %d children\n", node->nchildren);
479 		if (node->nchildren > 2) {
480 			TAILQ_FOREACH_MUTABLE(node1, DEVFS_DENODE_HEAD(node), link, node2)	{
481 				devfs_gc_dirs(node1);
482 			}
483 		}
484 
485 		if (node->nchildren == 2) {
486 			devfs_debug(DEVFS_DEBUG_DEBUG, "This node is called %s and it is empty\n", node->d_dir.d_name);
487 			devfs_unlinkp(node);
488 			devfs_freep(node);
489 		}
490 	}
491 
492 	return 0;
493 }
494 
495 /*
496  * devfs_gc_links() is a helper function for devfs_gc, unlinking and freeing
497  * eauto-linked nodes linking to the node being deleted.
498  */
499 static int
500 devfs_gc_links(struct devfs_node *node, struct devfs_node *target, size_t nlinks)
501 {
502 	struct devfs_node *node1, *node2;
503 
504 	if (nlinks > 0) {
505 		if ((node->node_type == Proot) || (node->node_type == Pdir)) {
506 			devfs_debug(DEVFS_DEBUG_DEBUG, "This node is Pdir or Proot; has %d children\n", node->nchildren);
507 			if (node->nchildren > 2) {
508 				TAILQ_FOREACH_MUTABLE(node1, DEVFS_DENODE_HEAD(node), link, node2)	{
509 					nlinks = devfs_gc_links(node1, target, nlinks);
510 				}
511 			}
512 		} else if (node->link_target == target) {
513 			nlinks--;
514 			devfs_unlinkp(node);
515 			devfs_freep(node);
516 		}
517 	}
518 
519 	KKASSERT(nlinks >= 0);
520 
521 	return nlinks;
522 }
523 
524 /*
525  * devfs_create_dev() is the asynchronous entry point for device creation. It
526  * just sends a message with the relevant details to the devfs core.
527  */
528 int
529 devfs_create_dev(cdev_t dev, uid_t uid, gid_t gid, int perms)
530 {
531 	__uint64_t id;
532 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_dev -1-, name: %s (%p)\n", dev->si_name, dev);
533 	id = devfs_msg_send_dev(DEVFS_DEVICE_CREATE, dev, uid, gid, perms);
534 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_dev -end:2- (unique id: %x) / (%p)\n", id, dev);
535 	return 0;
536 }
537 
538 /*
539  * devfs_destroy_dev() is the asynchronous entry point for device destruction. It
540  * just sends a message with the relevant details to the devfs core.
541  */
542 int
543 devfs_destroy_dev(cdev_t dev)
544 {
545 	devfs_msg_send_dev(DEVFS_DEVICE_DESTROY, dev, 0, 0, 0);
546 	return 0;
547 }
548 
549 /*
550  * devfs_mount_add() is the synchronous entry point for adding a new devfs mount.
551  * It sends a synchronous message with the relevant details to the devfs core.
552  */
553 int
554 devfs_mount_add(struct devfs_mnt_data *mnt)
555 {
556 	devfs_msg_t msg;
557 
558 	msg = devfs_msg_get();
559 	msg->m_mnt = mnt;
560 	msg = devfs_msg_send_sync(DEVFS_MOUNT_ADD, msg);
561 	devfs_msg_put(msg);
562 
563 	return 0;
564 }
565 
566 /*
567  * devfs_mount_del() is the synchronous entry point for removing a devfs mount.
568  * It sends a synchronous message with the relevant details to the devfs core.
569  */
570 int
571 devfs_mount_del(struct devfs_mnt_data *mnt)
572 {
573 	devfs_msg_t msg;
574 
575 	msg = devfs_msg_get();
576 	msg->m_mnt = mnt;
577 	msg = devfs_msg_send_sync(DEVFS_MOUNT_DEL, msg);
578 	devfs_msg_put(msg);
579 
580 	return 0;
581 }
582 
583 /*
584  * devfs_destroy_subnames() is the asynchronous entry point for device destruction
585  * by subname. It just sends a message with the relevant details to the devfs core.
586  */
587 int
588 devfs_destroy_subnames(char *name)
589 {
590 	devfs_msg_send_generic(DEVFS_DESTROY_SUBNAMES, name);
591 	return 0;
592 }
593 
594 /*
595  * devfs_create_all_dev is the asynchronous entry point to trigger device node creation.
596  * It just sends a message with the relevant details to the devfs core.
597  */
598 int
599 devfs_create_all_dev(struct devfs_node *root)
600 {
601 	devfs_msg_send_generic(DEVFS_CREATE_ALL_DEV, root);
602 	return 0;
603 }
604 
605 /*
606  * devfs_destroy_dev_by_ops is the asynchronous entry point to destroy all devices with
607  * a specific set of dev_ops and minor.
608  * It just sends a message with the relevant details to the devfs core.
609  */
610 int
611 devfs_destroy_dev_by_ops(struct dev_ops *ops, int minor)
612 {
613 	devfs_msg_send_ops(DEVFS_DESTROY_DEV_BY_OPS, ops, minor);
614 	return 0;
615 }
616 
617 /*
618  * devfs_clone_handler_add is the asynchronous entry point to add a new clone handler.
619  * It just sends a message with the relevant details to the devfs core.
620  */
621 int
622 devfs_clone_handler_add(char *name, d_clone_t *nhandler)
623 {
624 	devfs_msg_send_chandler(DEVFS_CHANDLER_ADD, name, nhandler);
625 	return 0;
626 }
627 
628 /*
629  * devfs_clone_handler_del is the asynchronous entry point to remove a clone handler.
630  * It just sends a message with the relevant details to the devfs core.
631  */
632 int
633 devfs_clone_handler_del(char *name)
634 {
635 	devfs_msg_send_chandler(DEVFS_CHANDLER_DEL, name, NULL);
636 	return 0;
637 }
638 
639 /*
640  * devfs_find_device_by_name is the synchronous entry point to find a device given
641  * its name.
642  * It sends a synchronous message with the relevant details to the devfs core and
643  * returns the answer.
644  */
645 cdev_t
646 devfs_find_device_by_name(const char *fmt, ...)
647 {
648 	cdev_t found = NULL;
649 	devfs_msg_t msg;
650 	char target[PATH_MAX+1];
651 	__va_list ap;
652 	int i;
653 
654 	if (fmt == NULL)
655 		return NULL;
656 
657 
658 	__va_start(ap, fmt);
659 	i = kvcprintf(fmt, NULL, target, 10, ap);
660 	target[i] = '\0';
661 	__va_end(ap);
662 
663 
664 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_name: %s -1-\n", target);
665 	msg = devfs_msg_get();
666 	msg->m_name = target;
667 	msg = devfs_msg_send_sync(DEVFS_FIND_DEVICE_BY_NAME, msg);
668 	found = msg->m_cdev;
669 	devfs_msg_put(msg);
670 
671 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_name found? %s  -end:2-\n", (found)?"YES":"NO");
672 	return found;
673 }
674 
675 /*
676  * devfs_find_device_by_udev is the synchronous entry point to find a device given
677  * its udev number.
678  * It sends a synchronous message with the relevant details to the devfs core and
679  * returns the answer.
680  */
681 cdev_t
682 devfs_find_device_by_udev(udev_t udev)
683 {
684 	cdev_t found = NULL;
685 	devfs_msg_t msg;
686 
687 	msg = devfs_msg_get();
688 	msg->m_udev = udev;
689 	msg = devfs_msg_send_sync(DEVFS_FIND_DEVICE_BY_UDEV, msg);
690 	found = msg->m_cdev;
691 	devfs_msg_put(msg);
692 
693 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_udev found? %s  -end:3-\n", (found)?found->si_name:"NO");
694 	return found;
695 }
696 
697 /*
698  * devfs_make_alias is the asynchronous entry point to register an alias for a device.
699  * It just sends a message with the relevant details to the devfs core.
700  */
701 int
702 devfs_make_alias(char *name, cdev_t dev_target)
703 {
704 	struct devfs_alias *alias = kmalloc(sizeof(struct devfs_alias), M_DEVFS, M_WAITOK);
705 	memcpy(alias->name, name, strlen(name) + 1);
706 	alias->dev_target = dev_target;
707 
708 	devfs_msg_send_generic(DEVFS_MAKE_ALIAS, alias);
709 	return 0;
710 }
711 
712 /*
713  * devfs_apply_rules is the asynchronous entry point to trigger application of all rules.
714  * It just sends a message with the relevant details to the devfs core.
715  */
716 int
717 devfs_apply_rules(char *mntto)
718 {
719 	char *new_name;
720 	size_t	namelen;
721 
722 	namelen = strlen(mntto) + 1;
723 
724 	new_name = kmalloc(namelen, M_DEVFS, M_WAITOK);
725 
726 	memcpy(new_name, mntto, namelen);
727 
728 	devfs_msg_send_name(DEVFS_APPLY_RULES, new_name);
729 	return 0;
730 }
731 
732 /*
733  * devfs_reset_rules is the asynchronous entry point to trigger reset of all rules.
734  * It just sends a message with the relevant details to the devfs core.
735  */
736 int
737 devfs_reset_rules(char *mntto)
738 {
739 	char *new_name;
740 	size_t	namelen;
741 
742 	namelen = strlen(mntto) + 1;
743 
744 	new_name = kmalloc(namelen, M_DEVFS, M_WAITOK);
745 
746 	memcpy(new_name, mntto, namelen);
747 
748 	devfs_msg_send_name(DEVFS_RESET_RULES, new_name);
749 	return 0;
750 }
751 
752 
753 /*
754  * devfs_scan_callback is the asynchronous entry point to call a callback
755  * on all cdevs.
756  * It just sends a message with the relevant details to the devfs core.
757  */
758 int
759 devfs_scan_callback(devfs_scan_t *callback)
760 {
761 	devfs_msg_t msg;
762 
763 	/* Make sure that function pointers have the size of a generic pointer (innecessary) */
764 	KKASSERT(sizeof(callback) == sizeof(void *));
765 
766 	msg = devfs_msg_get();
767 	msg->m_load = callback;
768 	msg = devfs_msg_send_sync(DEVFS_SCAN_CALLBACK, msg);
769 	devfs_msg_put(msg);
770 
771 	return 0;
772 }
773 
774 
775 /*
776  * Acts as a message drain. Any message that is replied to here gets destroyed and
777  * the memory freed.
778  */
779 static void
780 devfs_msg_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
781 {
782 	devfs_msg_put((devfs_msg_t)msg);
783 }
784 
785 /*
786  * devfs_msg_get allocates a new devfs msg and returns it.
787  */
788 devfs_msg_t
789 devfs_msg_get()
790 {
791 	return objcache_get(devfs_msg_cache, M_WAITOK);
792 }
793 
794 /*
795  * devfs_msg_put deallocates a given devfs msg.
796  */
797 int
798 devfs_msg_put(devfs_msg_t msg)
799 {
800 	objcache_put(devfs_msg_cache, msg);
801 	return 0;
802 }
803 
804 /*
805  * devfs_msg_send is the generic asynchronous message sending facility
806  * for devfs. By default the reply port is the automatic disposal port.
807  */
808 __uint32_t
809 devfs_msg_send(uint32_t cmd, devfs_msg_t devfs_msg)
810 {
811 	lwkt_port_t port = &devfs_msg_port;
812 
813     lwkt_initmsg(&devfs_msg->hdr, &devfs_dispose_port, 0);
814 
815     devfs_msg->hdr.u.ms_result = cmd;
816 	devfs_msg->id = atomic_fetchadd_int(&msg_id, 1);
817 
818     lwkt_sendmsg(port, (lwkt_msg_t)devfs_msg);
819 
820 	return devfs_msg->id;
821 }
822 
823 /*
824  * devfs_msg_send_sync is the generic synchronous message sending
825  * facility for devfs. It initializes a local reply port and waits
826  * for the core's answer. This answer is then returned.
827  */
828 devfs_msg_t
829 devfs_msg_send_sync(uint32_t cmd, devfs_msg_t devfs_msg)
830 {
831 	struct lwkt_port rep_port;
832 	devfs_msg_t	msg_incoming;
833 	lwkt_port_t port = &devfs_msg_port;
834 
835 	lwkt_initport_thread(&rep_port, curthread);
836     lwkt_initmsg(&devfs_msg->hdr, &rep_port, 0);
837 
838     devfs_msg->hdr.u.ms_result = cmd;
839 	devfs_msg->id = atomic_fetchadd_int(&msg_id, 1);
840 
841     lwkt_sendmsg(port, (lwkt_msg_t)devfs_msg);
842 	msg_incoming = lwkt_waitport(&rep_port, 0);
843 
844 	return msg_incoming;
845 }
846 
847 /*
848  * sends a message with a generic argument.
849  */
850 __uint32_t
851 devfs_msg_send_generic(uint32_t cmd, void *load)
852 {
853     devfs_msg_t devfs_msg = devfs_msg_get();
854     devfs_msg->m_load = load;
855 
856 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_send_generic -1- (%p)\n", load);
857 
858 	return devfs_msg_send(cmd, devfs_msg);
859 }
860 
861 /*
862  * sends a message with a name argument.
863  */
864 __uint32_t
865 devfs_msg_send_name(uint32_t cmd, char *name)
866 {
867     devfs_msg_t devfs_msg = devfs_msg_get();
868     devfs_msg->m_name = name;
869 
870 	return devfs_msg_send(cmd, devfs_msg);
871 }
872 
873 /*
874  * sends a message with a mount argument.
875  */
876 __uint32_t
877 devfs_msg_send_mount(uint32_t cmd, struct devfs_mnt_data *mnt)
878 {
879     devfs_msg_t devfs_msg = devfs_msg_get();
880     devfs_msg->m_mnt = mnt;
881 
882 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_send_mp -1- (%p)\n", mnt);
883 
884 	return devfs_msg_send(cmd, devfs_msg);
885 }
886 
887 /*
888  * sends a message with an ops argument.
889  */
890 __uint32_t
891 devfs_msg_send_ops(uint32_t cmd, struct dev_ops *ops, int minor)
892 {
893     devfs_msg_t devfs_msg = devfs_msg_get();
894     devfs_msg->m_ops.ops = ops;
895 	devfs_msg->m_ops.minor = minor;
896 
897 	return devfs_msg_send(cmd, devfs_msg);
898 }
899 
900 /*
901  * sends a message with a clone handler argument.
902  */
903 __uint32_t
904 devfs_msg_send_chandler(uint32_t cmd, char *name, d_clone_t handler)
905 {
906     devfs_msg_t devfs_msg = devfs_msg_get();
907     devfs_msg->m_chandler.name = name;
908 	devfs_msg->m_chandler.nhandler = handler;
909 
910 	return devfs_msg_send(cmd, devfs_msg);
911 }
912 
913 /*
914  * sends a message with a device argument.
915  */
916 __uint32_t
917 devfs_msg_send_dev(uint32_t cmd, cdev_t dev, uid_t uid, gid_t gid, int perms)
918 {
919     devfs_msg_t devfs_msg = devfs_msg_get();
920     devfs_msg->m_dev.dev = dev;
921 	devfs_msg->m_dev.uid = uid;
922 	devfs_msg->m_dev.gid = gid;
923 	devfs_msg->m_dev.perms = perms;
924 
925 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_send_dev -1- (%p)\n", dev);
926 
927 	return devfs_msg_send(cmd, devfs_msg);
928 }
929 
930 /*
931  * sends a message with a link argument.
932  */
933 //XXX: dead code!
934 __uint32_t
935 devfs_msg_send_link(uint32_t cmd, char *name, char *target, struct mount *mp)
936 {
937     devfs_msg_t devfs_msg = devfs_msg_get();
938     devfs_msg->m_link.name = name;
939 	devfs_msg->m_link.target = target;
940 	devfs_msg->m_link.mp = mp;
941 
942 
943 	return devfs_msg_send(cmd, devfs_msg);
944 }
945 
946 /*
947  * devfs_msg_core is the main devfs thread. It handles all incoming messages
948  * and calls the relevant worker functions. By using messages it's assured
949  * that events occur in the correct order.
950  */
951 static void
952 devfs_msg_core(void *arg)
953 {
954     uint8_t  run = 1;
955     devfs_msg_t msg;
956 	cdev_t	dev;
957 	struct devfs_mnt_data *mnt;
958 	struct devfs_node *node;
959 
960 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core -1-\n");
961 	lwkt_initport_thread(&devfs_msg_port, curthread);
962 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core -2-\n");
963 	wakeup(td_core/*devfs_id*/);
964 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core -3-\n");
965 
966     while (run) {
967 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core -loop:4-\n");
968         msg = (devfs_msg_t)lwkt_waitport(&devfs_msg_port, 0);
969 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core, new msg: %x (unique id: %x)\n", (unsigned int)msg->hdr.u.ms_result, msg->id);
970 		lockmgr(&devfs_lock, LK_EXCLUSIVE);
971         switch (msg->hdr.u.ms_result) {
972 
973         case DEVFS_DEVICE_CREATE:
974 			dev = msg->m_dev.dev;
975 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core device create msg %s (%p)\n", dev->si_name, dev);
976 			devfs_create_dev_worker(dev, msg->m_dev.uid, msg->m_dev.gid, msg->m_dev.perms);
977 			break;
978 
979 		case DEVFS_DEVICE_DESTROY:
980 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core device destroy msg\n");
981 			dev = msg->m_dev.dev;
982 			devfs_destroy_dev_worker(dev);
983             break;
984 
985 		case DEVFS_DESTROY_SUBNAMES:
986 			devfs_destroy_subnames_worker(msg->m_load);
987 			break;
988 
989 		case DEVFS_DESTROY_DEV_BY_OPS:
990 			devfs_destroy_dev_by_ops_worker(msg->m_ops.ops, msg->m_ops.minor);
991 			break;
992 
993 		case DEVFS_CREATE_ALL_DEV:
994 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core device create ALL msg\n");
995 			node = (struct devfs_node *)msg->m_load;
996 			devfs_create_all_dev_worker(node);
997 			break;
998 
999 		case DEVFS_MOUNT_ADD:
1000 			mnt = msg->m_mnt;
1001 			TAILQ_INSERT_TAIL(&devfs_mnt_list, mnt, link);
1002 			devfs_create_all_dev_worker(mnt->root_node);
1003 			break;
1004 
1005 		case DEVFS_MOUNT_DEL:
1006 			mnt = msg->m_mnt;
1007 			TAILQ_REMOVE(&devfs_mnt_list, mnt, link);
1008 			devfs_debug(DEVFS_DEBUG_DEBUG, "There are still %d devfs_node elements!!!\n", mnt->leak_count);
1009 			devfs_reaperp(mnt->root_node);
1010 			devfs_debug(DEVFS_DEBUG_DEBUG, "Leaked %d devfs_node elements!!!\n", mnt->leak_count);
1011 			break;
1012 
1013 		case DEVFS_CHANDLER_ADD:
1014 			devfs_chandler_add_worker(msg->m_chandler.name, msg->m_chandler.nhandler);
1015 			break;
1016 
1017 		case DEVFS_CHANDLER_DEL:
1018 			devfs_chandler_del_worker(msg->m_chandler.name);
1019 			break;
1020 
1021 		case DEVFS_FIND_DEVICE_BY_NAME:
1022 			devfs_find_device_by_name_worker(msg);
1023 			break;
1024 
1025 		case DEVFS_FIND_DEVICE_BY_UDEV:
1026 			devfs_find_device_by_udev_worker(msg);
1027 			break;
1028 
1029 		case DEVFS_MAKE_ALIAS:
1030 			devfs_make_alias_worker((struct devfs_alias *)msg->m_load);
1031 			break;
1032 
1033 		case DEVFS_APPLY_RULES:
1034 			devfs_apply_reset_rules_caller(msg->m_name, 1);
1035 			break;
1036 
1037 		case DEVFS_RESET_RULES:
1038 			devfs_apply_reset_rules_caller(msg->m_name, 0);
1039 			break;
1040 
1041 		case DEVFS_SCAN_CALLBACK:
1042 			devfs_scan_callback_worker((devfs_scan_t *)msg->m_load);
1043 			break;
1044 
1045         case DEVFS_TERMINATE_CORE:
1046             run = 0;
1047             break;
1048 
1049 		case DEVFS_SYNC:
1050 			break;
1051 
1052         default:
1053             devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_msg_core: unknown message received at core\n");
1054         }
1055 		lockmgr(&devfs_lock, LK_RELEASE);
1056 
1057         lwkt_replymsg((lwkt_msg_t)msg, 0);
1058     }
1059 	wakeup(td_core/*devfs_id*/);
1060 	lwkt_exit();
1061 }
1062 
1063 /*
1064  * Worker function to insert a new dev into the dev list and initialize its
1065  * permissions. It also calls devfs_propagate_dev which in turn propagates
1066  * the change to all mount points.
1067  */
1068 static int
1069 devfs_create_dev_worker(cdev_t dev, uid_t uid, gid_t gid, int perms)
1070 {
1071 	KKASSERT(dev);
1072 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_dev_worker -1- -%s- (%p)\n", dev->si_name, dev);
1073 
1074 	dev->si_uid = uid;
1075 	dev->si_gid = gid;
1076 	dev->si_perms = perms;
1077 
1078 	devfs_link_dev(dev);
1079 	reference_dev(dev);
1080 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_dev_worker -2-\n");
1081 	devfs_propagate_dev(dev, 1);
1082 
1083 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_dev_worker -end:3-\n");
1084 	return 0;
1085 }
1086 
1087 /*
1088  * Worker function to delete a dev from the dev list and free the cdev.
1089  * It also calls devfs_propagate_dev which in turn propagates the change
1090  * to all mount points.
1091  */
1092 static int
1093 devfs_destroy_dev_worker(cdev_t dev)
1094 {
1095 	KKASSERT(dev);
1096 	KKASSERT((lockstatus(&devfs_lock, curthread)) == LK_EXCLUSIVE);
1097 
1098 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_destroy_dev_worker -1- %s\n", dev->si_name);
1099 	devfs_unlink_dev(dev);
1100 	devfs_propagate_dev(dev, 0);
1101 	release_dev(dev);
1102 	release_dev(dev);
1103 	//objcache_put(devfs_dev_cache, dev);
1104 
1105 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_destroy_dev_worker -end:5-\n");
1106 	return 0;
1107 }
1108 
1109 /*
1110  * Worker function to destroy all devices with a certain basename.
1111  * Calls devfs_destroy_dev_worker for the actual destruction.
1112  */
1113 static int
1114 devfs_destroy_subnames_worker(char *name)
1115 {
1116 	cdev_t dev, dev1;
1117 	//cdev_t found = NULL;
1118 	size_t len = strlen(name);
1119 
1120     TAILQ_FOREACH_MUTABLE(dev, &devfs_dev_list, link, dev1) {
1121 		if (!strncmp(dev->si_name, name, len)) {
1122 			if (dev->si_name[len] != '\0')
1123 				devfs_destroy_dev_worker(dev);
1124 		}
1125     }
1126 
1127 	return 0;
1128 }
1129 
1130 /*
1131  * Worker function that creates all device nodes on top of a devfs
1132  * root node.
1133  */
1134 static int
1135 devfs_create_all_dev_worker(struct devfs_node *root)
1136 {
1137 	cdev_t dev;
1138 
1139 	KKASSERT(root);
1140 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_all_dev_worker -1-\n");
1141 
1142     TAILQ_FOREACH(dev, &devfs_dev_list, link) {
1143 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_all_dev_worker -loop:2- -%s-\n", dev->si_name);
1144 		devfs_create_device_node(root, dev, NULL, NULL);
1145     }
1146 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_all_dev_worker -end:3-\n");
1147 	return 0;
1148 }
1149 
1150 /*
1151  * Worker function that destroys all devices that match a specific
1152  * dev_ops and/or minor. If minor is less than 0, it is not matched
1153  * against. It also propagates all changes.
1154  */
1155 static int
1156 devfs_destroy_dev_by_ops_worker(struct dev_ops *ops, int minor)
1157 {
1158 	cdev_t dev, dev1;
1159 
1160 	KKASSERT(ops);
1161 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_destroy_dev_by_ops_worker -1-\n");
1162 
1163     TAILQ_FOREACH_MUTABLE(dev, &devfs_dev_list, link, dev1) {
1164 		if (dev->si_ops == ops) {
1165 			if ((minor < 0) || (dev->si_uminor == minor)) {
1166 				devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_destroy_dev_by_ops_worker -loop:2- -%s-\n", dev->si_name);
1167 				//TAILQ_REMOVE(&devfs_dev_list, dev, link);
1168 				devfs_unlink_dev(dev);
1169 				devfs_propagate_dev(dev, 0);
1170 				release_dev(dev);
1171 				//objcache_put(devfs_dev_cache, dev);
1172 			}
1173 		}
1174     }
1175 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_destroy_dev_by_ops_worker -end:3-\n");
1176 	return 0;
1177 }
1178 
1179 /*
1180  * Worker function that registers a new clone handler in devfs.
1181  */
1182 static int
1183 devfs_chandler_add_worker(char *name, d_clone_t *nhandler)
1184 {
1185 	struct devfs_clone_handler *chandler = NULL;
1186 	u_char len = strlen(name);
1187 
1188 	if (!len)
1189 		return 1;
1190 
1191     TAILQ_FOREACH(chandler, &devfs_chandler_list, link) {
1192 		if (chandler->namlen == len) {
1193 			if (!memcmp(chandler->name, name, len)) {
1194 				/* Clonable basename already exists */
1195 				return 1;
1196 			}
1197 		}
1198 	}
1199 
1200 	chandler = kmalloc(sizeof(struct devfs_clone_handler), M_DEVFS, M_WAITOK);
1201 	memcpy(chandler->name, name, len+1);
1202 	chandler->namlen = len;
1203 	chandler->nhandler = nhandler;
1204 
1205 	TAILQ_INSERT_TAIL(&devfs_chandler_list, chandler, link);
1206 	return 0;
1207 }
1208 
1209 /*
1210  * Worker function that removes a given clone handler from the
1211  * clone handler list.
1212  */
1213 static int
1214 devfs_chandler_del_worker(char *name)
1215 {
1216 	struct devfs_clone_handler *chandler, *chandler2;
1217 	u_char len = strlen(name);
1218 
1219 	if (!len)
1220 		return 1;
1221 
1222     TAILQ_FOREACH_MUTABLE(chandler, &devfs_chandler_list, link, chandler2) {
1223 		if (chandler->namlen == len) {
1224 			if (!memcmp(chandler->name, name, len)) {
1225 				TAILQ_REMOVE(&devfs_chandler_list, chandler, link);
1226 				kfree(chandler, M_DEVFS);
1227 				//break;
1228 			}
1229 		}
1230 	}
1231 
1232 	return 0;
1233 }
1234 
1235 /*
1236  * Worker function that finds a given device name and changes
1237  * the message received accordingly so that when replied to,
1238  * the answer is returned to the caller.
1239  */
1240 static int
1241 devfs_find_device_by_name_worker(devfs_msg_t devfs_msg)
1242 {
1243 	cdev_t dev, dev1;
1244 	cdev_t found = NULL;
1245 	//devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_name: %s -1-\n", target);
1246 
1247     TAILQ_FOREACH_MUTABLE(dev, &devfs_dev_list, link, dev1) {
1248 		//devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_name -loop:2- -%s-\n", dev->si_name);
1249 		if (!strcmp(devfs_msg->m_name, dev->si_name)) {
1250 			found = dev;
1251 			break;
1252 		}
1253     }
1254 	devfs_msg->m_cdev = found;
1255 
1256 	return 0;
1257 }
1258 
1259 /*
1260  * Worker function that finds a given device udev and changes
1261  * the message received accordingly so that when replied to,
1262  * the answer is returned to the caller.
1263  */
1264 static int
1265 devfs_find_device_by_udev_worker(devfs_msg_t devfs_msg)
1266 {
1267 	cdev_t dev, dev1;
1268 	cdev_t found = NULL;
1269 	//devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_name: %s -1-\n", target);
1270 
1271     TAILQ_FOREACH_MUTABLE(dev, &devfs_dev_list, link, dev1) {
1272 		//devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_find_device_by_name -loop:2- -%s-\n", dev->si_name);
1273 		if (((udev_t)dev->si_inode) == devfs_msg->m_udev) {
1274 			found = dev;
1275 			break;
1276 		}
1277     }
1278 	devfs_msg->m_cdev = found;
1279 
1280 	return 0;
1281 }
1282 
1283 /*
1284  * Worker function that inserts a given alias into the
1285  * alias list, and propagates the alias to all mount
1286  * points.
1287  */
1288 static int
1289 devfs_make_alias_worker(struct devfs_alias *alias)
1290 {
1291 	struct devfs_alias *alias2;
1292 	size_t len = strlen(alias->name);
1293 	int found = 0;
1294 
1295 	TAILQ_FOREACH(alias2, &devfs_alias_list, link) {
1296 		if (!memcmp(alias->name, alias2->name, len)) {
1297 			found = 1;
1298 			break;
1299 		}
1300 	}
1301 
1302 	if (!found) {
1303 		TAILQ_INSERT_TAIL(&devfs_alias_list, alias, link);
1304 		devfs_alias_propagate(alias);
1305 	} else {
1306 		devfs_debug(DEVFS_DEBUG_DEBUG, "Warning: duplicate devfs_make_alias for %s\n", alias->name);
1307 		kfree(alias, M_DEVFS);
1308 	}
1309 
1310 	return 0;
1311 }
1312 
1313 /*
1314  * Function that removes and frees all aliases.
1315  */
1316 static int
1317 devfs_alias_reap(void)
1318 {
1319 	struct devfs_alias *alias, *alias2;
1320 
1321 	TAILQ_FOREACH_MUTABLE(alias, &devfs_alias_list, link, alias2) {
1322 		TAILQ_REMOVE(&devfs_alias_list, alias, link);
1323 		kfree(alias, M_DEVFS);
1324 	}
1325 	return 0;
1326 }
1327 
1328 /*
1329  * Function that removes an alias matching a specific cdev and frees
1330  * it accordingly.
1331  */
1332 static int
1333 devfs_alias_remove(cdev_t dev)
1334 {
1335 	struct devfs_alias *alias, *alias2;
1336 
1337 	TAILQ_FOREACH_MUTABLE(alias, &devfs_alias_list, link, alias2) {
1338 		if (alias->dev_target == dev) {
1339 			TAILQ_REMOVE(&devfs_alias_list, alias, link);
1340 			kfree(alias, M_DEVFS);
1341 		}
1342 	}
1343 	return 0;
1344 }
1345 
1346 /*
1347  * This function propagates a new alias to all mount points.
1348  */
1349 static int
1350 devfs_alias_propagate(struct devfs_alias *alias)
1351 {
1352 	struct devfs_mnt_data *mnt;
1353 
1354 	TAILQ_FOREACH(mnt, &devfs_mnt_list, link) {
1355 		devfs_alias_apply(mnt->root_node, alias);
1356 	}
1357 	return 0;
1358 }
1359 
1360 /*
1361  * This function is a recursive function iterating through
1362  * all device nodes in the topology and, if applicable,
1363  * creating the relevant alias for a device node.
1364  */
1365 static int
1366 devfs_alias_apply(struct devfs_node *node, struct devfs_alias *alias)
1367 {
1368 	struct devfs_node *node1, *node2;
1369 
1370 	KKASSERT(alias != NULL);
1371 
1372 	if ((node->node_type == Proot) || (node->node_type == Pdir)) {
1373 		devfs_debug(DEVFS_DEBUG_DEBUG, "This node is Pdir or Proot; has %d children\n", node->nchildren);
1374 		if (node->nchildren > 2) {
1375 			TAILQ_FOREACH_MUTABLE(node1, DEVFS_DENODE_HEAD(node), link, node2)	{
1376 				devfs_alias_apply(node1, alias);
1377 			}
1378 		}
1379 	} else {
1380 		if (node->d_dev == alias->dev_target)
1381 			devfs_alias_create(alias->name, node);
1382 	}
1383 	return 0;
1384 }
1385 
1386 /*
1387  * This function checks if any alias possibly is applicable
1388  * to the given node. If so, the alias is created.
1389  */
1390 static int
1391 devfs_alias_check_create(struct devfs_node *node)
1392 {
1393 	struct devfs_alias *alias;
1394 
1395 	TAILQ_FOREACH(alias, &devfs_alias_list, link) {
1396 		if (node->d_dev == alias->dev_target)
1397 			devfs_alias_create(alias->name, node);
1398 	}
1399 	return 0;
1400 }
1401 
1402 /*
1403  * This function creates an alias with a given name
1404  * linking to a given devfs node. It also increments
1405  * the link count on the target node.
1406  */
1407 int
1408 devfs_alias_create(char *name_orig, struct devfs_node *target)
1409 {
1410 	struct mount *mp = target->mp;
1411 	struct devfs_node *parent = DEVFS_MNTDATA(mp)->root_node;
1412 	struct devfs_node *linknode;
1413 
1414 	//char *path = NULL;
1415 	char *create_path = NULL;
1416 	char *name, name_buf[PATH_MAX];
1417 
1418 	//XXX: possibly put this in many worker functions (at least those with ext. API)
1419 	KKASSERT((lockstatus(&devfs_lock, curthread)) == LK_EXCLUSIVE);
1420 
1421 	devfs_resolve_name_path(name_orig, name_buf, &create_path, &name);
1422 
1423 	if (create_path)
1424 		parent = devfs_resolve_or_create_path(parent, create_path, 1);
1425 
1426 
1427 	if (devfs_find_device_node_by_name(parent, name)) {
1428 		devfs_debug(DEVFS_DEBUG_DEBUG, "Node already exists: %s (devfs_make_alias_worker)!\n", name);
1429 		return 1;
1430 	}
1431 
1432 
1433 	linknode = devfs_allocp(Plink, name, parent, mp, NULL);
1434 	if (linknode == NULL)
1435 		return 1;
1436 
1437 	linknode->link_target = target;
1438 	target->nlinks++;
1439 	//linknode->flags |= DEVFS_LINK;
1440 
1441 	return 0;
1442 }
1443 
1444 /*
1445  * This function is called by the core and handles mount point
1446  * strings. It either calls the relevant worker (devfs_apply_
1447  * reset_rules_worker) on all mountpoints or only a specific
1448  * one.
1449  */
1450 static int
1451 devfs_apply_reset_rules_caller(char *mountto, int apply)
1452 {
1453 	//int found = 0;
1454 	struct devfs_mnt_data *mnt;
1455 	size_t len = strlen(mountto);
1456 
1457 	if (mountto[0] != '*') {
1458 		TAILQ_FOREACH(mnt, &devfs_mnt_list, link) {
1459 			if ((len == mnt->mntonnamelen) &&
1460 				(!memcmp(mnt->mp->mnt_stat.f_mntonname, mountto, len))) {
1461 				devfs_apply_reset_rules_worker(mnt->root_node, apply);
1462 				break;
1463 			}
1464 		}
1465 	} else {
1466 		TAILQ_FOREACH(mnt, &devfs_mnt_list, link) {
1467 			devfs_apply_reset_rules_worker(mnt->root_node, apply);
1468 		}
1469 	}
1470 
1471 	kfree(mountto, M_DEVFS);
1472 	return 0;
1473 }
1474 
1475 /*
1476  * This worker function applies or resets, depending on the arguments, a rule
1477  * to the whole given topology. *RECURSIVE*
1478  */
1479 static int
1480 devfs_apply_reset_rules_worker(struct devfs_node *node, int apply)
1481 {
1482 	struct devfs_node *node1, *node2;
1483 
1484 	if ((node->node_type == Proot) || (node->node_type == Pdir)) {
1485 		devfs_debug(DEVFS_DEBUG_DEBUG, "This node is Pdir or Proot; has %d children\n", node->nchildren);
1486 		if (node->nchildren > 2) {
1487 			TAILQ_FOREACH_MUTABLE(node1, DEVFS_DENODE_HEAD(node), link, node2)	{
1488 				devfs_apply_reset_rules_worker(node1, apply);
1489 			}
1490 		}
1491 	}
1492 
1493 	if (apply)
1494 		devfs_rule_check_apply(node);
1495 	else
1496 		devfs_rule_reset_node(node);
1497 
1498 	return 0;
1499 }
1500 
1501 
1502 /*
1503  * This function calls a given callback function for
1504  * every dev node in the devfs dev list.
1505  */
1506 static int
1507 devfs_scan_callback_worker(devfs_scan_t *callback)
1508 {
1509 	cdev_t dev, dev1;
1510 
1511 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_scan_callback: %p -1-\n", callback);
1512 
1513     TAILQ_FOREACH_MUTABLE(dev, &devfs_dev_list, link, dev1) {
1514 		callback(dev);
1515     }
1516 
1517 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_scan_callback: finished\n");
1518 	return 0;
1519 }
1520 
1521 
1522 /*
1523  * This function tries to resolve a given directory, or if not
1524  * found and creation requested, creates the given directory.
1525  */
1526 static struct devfs_node *
1527 devfs_resolve_or_create_dir(struct devfs_node *parent, char *dir_name, size_t name_len, int create)
1528 {
1529 	struct devfs_node *node, *found = NULL;
1530 
1531 	TAILQ_FOREACH(node, DEVFS_DENODE_HEAD(parent), link) {
1532 		if (name_len == node->d_dir.d_namlen) {
1533 			if (!memcmp(dir_name, node->d_dir.d_name, name_len)) {
1534 				found = node;
1535 				break;
1536 			}
1537 		}
1538 	}
1539 
1540 	if ((found == NULL) && (create)) {
1541 		found = devfs_allocp(Pdir, dir_name, parent, parent->mp, NULL);
1542 	}
1543 
1544 	return found;
1545 }
1546 
1547 /*
1548  * This function tries to resolve a complete path. If creation is requested,
1549  * if a given part of the path cannot be resolved (because it doesn't exist),
1550  * it is created.
1551  */
1552 struct devfs_node *
1553 devfs_resolve_or_create_path(struct devfs_node *parent, char *path, int create)
1554 {
1555 	struct devfs_node *node = parent;
1556 	char buf[PATH_MAX];
1557 	size_t idx = 0;
1558 
1559 
1560 	if (path == NULL)
1561 		return parent;
1562 
1563 
1564 	for (; *path != '\0' ; path++) {
1565 		if (*path != '/') {
1566 			buf[idx++] = *path;
1567 		} else {
1568 			buf[idx] = '\0';
1569 			node = devfs_resolve_or_create_dir(node, buf, idx, create);
1570 			if (node == NULL)
1571 				return NULL;
1572 			idx = 0;
1573 		}
1574 	}
1575 	buf[idx] = '\0';
1576 	return devfs_resolve_or_create_dir(node, buf, idx, create);
1577 }
1578 
1579 /*
1580  * Takes a full path and strips it into a directory path and a name.
1581  * For a/b/c/foo, it returns foo in namep and a/b/c in pathp. It
1582  * requires a working buffer with enough size to keep the whole
1583  * fullpath.
1584  */
1585 int
1586 devfs_resolve_name_path(char *fullpath, char *buf, char **pathp, char **namep)
1587 {
1588 	char *name = NULL;
1589 	char *path = NULL;
1590 	size_t len = strlen(fullpath) + 1;
1591 	int i;
1592 
1593 	KKASSERT((fullpath != NULL) && (buf != NULL) && (pathp != NULL) && (namep != NULL));
1594 
1595 	memcpy(buf, fullpath, len);
1596 
1597 	for (i = len-1; i>= 0; i--) {
1598 		if (buf[i] == '/') {
1599 			buf[i] = '\0';
1600 			name = &(buf[i+1]);
1601 			path = buf;
1602 			break;
1603 		}
1604 	}
1605 
1606 	*pathp = path;
1607 
1608 	if (name) {
1609 		*namep = name;
1610 	} else {
1611 		*namep = buf;
1612 	}
1613 
1614 	return 0;
1615 }
1616 
1617 /*
1618  * This function creates a new devfs node for a given device. It can
1619  * handle a complete path as device name, and accordingly creates
1620  * the path and the final device node.
1621  */
1622 struct devfs_node *
1623 devfs_create_device_node(struct devfs_node *root, cdev_t dev, char *dev_name, char *path_fmt, ...)
1624 {
1625 	struct devfs_node *parent, *node = NULL;
1626 	char *path = NULL;
1627 	char *name, name_buf[PATH_MAX];
1628 	__va_list ap;
1629 	int i, found;
1630 
1631 	char *create_path = NULL;
1632 	char *names = "pqrsPQRS";
1633 
1634 
1635 	//devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_device_node : -%s- (%p)\n", dev->si_name, dev);
1636 
1637 	if (path_fmt != NULL) {
1638 		path = kmalloc(PATH_MAX+1, M_DEVFS, M_WAITOK);
1639 
1640 		__va_start(ap, path_fmt);
1641 		i = kvcprintf(path_fmt, NULL, path, 10, ap);
1642 		path[i] = '\0';
1643 		__va_end(ap);
1644 	}
1645 
1646 	parent = devfs_resolve_or_create_path(root, path, 1);
1647 	KKASSERT(parent);
1648 
1649 	if (dev)
1650 		reference_dev(dev);
1651 
1652 	devfs_resolve_name_path(((dev_name == NULL) && (dev))?(dev->si_name):(dev_name), name_buf, &create_path, &name);
1653 
1654 	if (create_path)
1655 		parent = devfs_resolve_or_create_path(parent, create_path, 1);
1656 
1657 
1658 	if (devfs_find_device_node_by_name(parent, name)) {
1659 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_device_node: DEVICE %s ALREADY EXISTS!!! Ignoring creation request.\n", name);
1660 		goto out;
1661 	}
1662 	devfs_debug(DEVFS_DEBUG_DEBUG, "parent->d_dir.d_name=%s\n", parent->d_dir.d_name);
1663 	node = devfs_allocp(Pdev, name, parent, parent->mp, dev);
1664 	devfs_debug(DEVFS_DEBUG_DEBUG, "node->d_dir.d_name=%s\n", node->d_dir.d_name);
1665 
1666 	/* Ugly unix98 pty magic, to hide pty master (ptm) devices and their directory */
1667 	if ((dev) && (strlen(dev->si_name) >= 4) && (!memcmp(dev->si_name, "ptm/", 4))) {
1668 		//node->parent->flags |= DEVFS_HIDDEN;
1669 		//node->flags |= DEVFS_HIDDEN;
1670 	}
1671 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_device_node: marker A\n");
1672 	/* Ugly pty magic, to tag pty devices as such and hide them if needed */
1673 	if ((strlen(name) >= 3) && (!memcmp(name, "pty", 3)))
1674 		node->flags |= (DEVFS_PTY | DEVFS_INVISIBLE);
1675 
1676 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_device_node: marker B\n");
1677 	if ((strlen(name) >= 3) && (!memcmp(name, "tty", 3))) {
1678 		found = 0;
1679 		for (i = 0; i < strlen(names); i++) {
1680 			if (name[3] == names[i]) {
1681 				found = 1;
1682 				break;
1683 			}
1684 		}
1685 		if (found)
1686 			node->flags |= (DEVFS_PTY | DEVFS_INVISIBLE);
1687 	}
1688 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_create_device_node: marker C\n");
1689 
1690 out:
1691 	if (path_fmt != NULL)
1692 		kfree(path, M_DEVFS);
1693 	if (dev)
1694 		release_dev(dev);
1695 
1696 	return node;
1697 }
1698 
1699 /*
1700  * This function finds a given device node in the topology with a given
1701  * cdev.
1702  */
1703 struct devfs_node *
1704 devfs_find_device_node(struct devfs_node *node, cdev_t target)
1705 {
1706 	struct devfs_node *node1, *node2, *found = NULL;
1707 
1708 	if ((node->node_type == Proot) || (node->node_type == Pdir)) {
1709 		devfs_debug(DEVFS_DEBUG_DEBUG, "This node is Pdir or Proot; has %d children\n", node->nchildren);
1710 		if (node->nchildren > 2) {
1711 			TAILQ_FOREACH_MUTABLE(node1, DEVFS_DENODE_HEAD(node), link, node2)	{
1712 				if ((found = devfs_find_device_node(node1, target)))
1713 					return found;
1714 			}
1715 		}
1716 	} else if (node->node_type == Pdev) {
1717 		if (node->d_dev == target)
1718 			return node;
1719 	}
1720 	//devfs_debug(DEVFS_DEBUG_DEBUG, "This node is called %s\n", (found)?found->d_dir.d_name:"NOTFOUND");
1721 
1722 	return NULL;
1723 }
1724 
1725 /*
1726  * This function finds a device node in the topology by its
1727  * name and returns it.
1728  */
1729 struct devfs_node *
1730 devfs_find_device_node_by_name(struct devfs_node *parent, char *target)
1731 {
1732 	struct devfs_node *node, *found = NULL;
1733 	size_t len = strlen(target);
1734 
1735 	TAILQ_FOREACH(node, DEVFS_DENODE_HEAD(parent), link) {
1736 		if ((len == node->d_dir.d_namlen) && (!memcmp(node->d_dir.d_name, target, len))) {
1737 			found = node;
1738 			break;
1739 		}
1740 	}
1741 
1742 	return found;
1743 }
1744 
1745 /*
1746  * This function takes a cdev and destroys its devfs node in the
1747  * given topology.
1748  */
1749 int
1750 devfs_destroy_device_node(struct devfs_node *root, cdev_t target)
1751 {
1752 	struct devfs_node *node, *parent;
1753 
1754 	char *name, name_buf[PATH_MAX];
1755 	//__va_list ap;
1756 	//int i;
1757 
1758 	char *create_path = NULL;
1759 
1760 	KKASSERT(target);
1761 
1762 
1763 
1764 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_destroy_device_node\n");
1765 	memcpy(name_buf, target->si_name, strlen(target->si_name)+1);
1766 
1767 	devfs_resolve_name_path(target->si_name, name_buf, &create_path, &name);
1768 	devfs_debug(DEVFS_DEBUG_DEBUG, "create_path: %s\n", create_path);
1769 	devfs_debug(DEVFS_DEBUG_DEBUG, "name: %s\n", name);
1770 
1771 	if (create_path)
1772 		parent = devfs_resolve_or_create_path(root, create_path, 0);
1773 	else
1774 		parent = root;
1775 	devfs_debug(DEVFS_DEBUG_DEBUG, "-> marker <-\n");
1776 	if (parent == NULL)
1777 		return 1;
1778 	devfs_debug(DEVFS_DEBUG_DEBUG, "->d_dir.d_name=%s\n", parent->d_dir.d_name);
1779 	node = devfs_find_device_node_by_name(parent, name);
1780 	devfs_debug(DEVFS_DEBUG_DEBUG, "->d_dir.d_name=%s\n", (node)?(node->d_dir.d_name):"SHIT!");
1781 	if (node) {
1782 		devfs_gc(node);
1783 	}
1784 
1785 	return 0;
1786 }
1787 
1788 /*
1789  * Just set perms and ownership for given node.
1790  */
1791 int
1792 devfs_set_perms(struct devfs_node *node, uid_t uid, gid_t gid, u_short mode, u_long flags)
1793 {
1794 	node->mode = mode;		/* files access mode and type */
1795 	node->uid = uid;		/* owner user id */
1796 	node->gid = gid;		/* owner group id */
1797 	//node->flags = flags;
1798 
1799 	return 0;
1800 }
1801 
1802 /*
1803  * Propagates a device attach/detach to all mount
1804  * points. Also takes care of automatic alias removal
1805  * for a deleted cdev.
1806  */
1807 static int
1808 devfs_propagate_dev(cdev_t dev, int attach)
1809 {
1810 	struct devfs_mnt_data *mnt;
1811 
1812 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_propagate_dev -1-\n");
1813 	TAILQ_FOREACH(mnt, &devfs_mnt_list, link) {
1814 		devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_propagate_dev -loop:2-\n");
1815 		if (attach) {
1816 			/* Device is being attached */
1817 			//devfs_create_device_node(struct devfs_node *root, struct devfs_dev *dev, char *dev_name, char *path_fmt, ...)
1818 			devfs_create_device_node(mnt->root_node, dev, NULL, NULL );
1819 		} else {
1820 			/* Device is being detached */
1821 			//devfs_destroy_device_node(struct devfs_node *root, struct devfs_dev *target)
1822 			devfs_alias_remove(dev);
1823 			devfs_destroy_device_node(mnt->root_node, dev);
1824 		}
1825 	}
1826 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_propagate_dev -end:3-\n");
1827 	return 0;
1828 }
1829 
1830 /*
1831  * devfs_node_to_path takes a node and a buffer of a size of
1832  * at least PATH_MAX, resolves the full path from the root
1833  * node and writes it in a humanly-readable format into the
1834  * buffer.
1835  * If DEVFS_STASH_DEPTH is less than the directory level up
1836  * to the root node, only the last DEVFS_STASH_DEPTH levels
1837  * of the path are resolved.
1838  */
1839 int
1840 devfs_node_to_path(struct devfs_node *node, char *buffer)
1841 {
1842 #define DEVFS_STASH_DEPTH	32
1843 	struct devfs_node *node_stash[DEVFS_STASH_DEPTH];
1844 	int i, offset;
1845 	memset(buffer, 0, PATH_MAX);
1846 
1847 	for (i = 0; (i < DEVFS_STASH_DEPTH) && (node->node_type != Proot); i++) {
1848 		node_stash[i] = node;
1849 		node = node->parent;
1850 	}
1851 	i--;
1852 
1853 	for (offset = 0; i >= 0; i--) {
1854 		memcpy(buffer+offset, node_stash[i]->d_dir.d_name, node_stash[i]->d_dir.d_namlen);
1855 		offset += node_stash[i]->d_dir.d_namlen;
1856 		if (i > 0) {
1857 			*(buffer+offset) = '/';
1858 			offset++;
1859 		}
1860 	}
1861 #undef DEVFS_STASH_DEPTH
1862 	return 0;
1863 }
1864 
1865 /*
1866  * devfs_clone either returns a basename from a complete name by
1867  * returning the length of the name without trailing digits, or,
1868  * if clone != 0, calls the device's clone handler to get a new
1869  * device, which in turn is returned in devp.
1870  */
1871 int
1872 devfs_clone(char *name, size_t *namlenp, cdev_t *devp, int clone, struct ucred *cred)
1873 {
1874 	KKASSERT(namlenp);
1875 
1876 	size_t len = *namlenp;
1877 	int error = 1;
1878 	struct devfs_clone_handler *chandler;
1879 	struct dev_clone_args ap;
1880 
1881 	if (!clone) {
1882 		for (; (len > 0) && (DEVFS_ISDIGIT(name[len-1])); len--);
1883 	}
1884 
1885     TAILQ_FOREACH(chandler, &devfs_chandler_list, link) {
1886 		devfs_debug(DEVFS_DEBUG_DEBUG, "len=%d, chandler->namlen=%d\n", len, chandler->namlen);
1887 		devfs_debug(DEVFS_DEBUG_DEBUG, "name=%s, chandler->name=%s\n", name, chandler->name);
1888 		if ((chandler->namlen == len) &&
1889 			(!memcmp(chandler->name, name, len)) &&
1890 			(chandler->nhandler)) {
1891 			devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nclone: found clone handler for the base name at %p\n", chandler->nhandler);
1892 			if (clone) {
1893 				ap.a_dev = NULL;
1894 				ap.a_name = name;
1895 				ap.a_namelen = len;
1896 				ap.a_cred = cred;
1897 				error = (chandler->nhandler)(&ap);
1898 				KKASSERT(devp);
1899 				*devp = ap.a_dev;
1900 			} else {
1901 				*namlenp = len;
1902 				error = 0;
1903 			}
1904 
1905 			break;
1906 		}
1907 	}
1908 
1909 	return error;
1910 }
1911 
1912 
1913 /*
1914  * Registers a new orphan in the orphan list.
1915  */
1916 void
1917 devfs_tracer_add_orphan(struct devfs_node *node)
1918 {
1919 	struct devfs_orphan *orphan;
1920 
1921 	KKASSERT(node);
1922 	orphan = kmalloc(sizeof(struct devfs_orphan), M_DEVFS, M_WAITOK);
1923 	orphan->node = node;
1924 
1925 	TAILQ_INSERT_TAIL(DEVFS_ORPHANLIST(node->mp), orphan, link);
1926 }
1927 
1928 /*
1929  * Removes an orphan from the orphan list.
1930  */
1931 void
1932 devfs_tracer_del_orphan(struct devfs_node *node)
1933 {
1934 	struct devfs_orphan *orphan;
1935 
1936 	KKASSERT(node);
1937 
1938 	TAILQ_FOREACH(orphan, DEVFS_ORPHANLIST(node->mp), link)	{
1939 		if (orphan->node == node) {
1940 			TAILQ_REMOVE(DEVFS_ORPHANLIST(node->mp), orphan, link);
1941 			kfree(orphan, M_DEVFS);
1942 			break;
1943 		}
1944 	}
1945 }
1946 
1947 /*
1948  * Counts the orphans in the orphan list, and if cleanup
1949  * is specified, also frees the orphan and removes it from
1950  * the list.
1951  */
1952 size_t
1953 devfs_tracer_orphan_count(struct mount *mp, int cleanup)
1954 {
1955 	struct devfs_orphan *orphan, *orphan2;
1956 	size_t count = 0;
1957 
1958 	TAILQ_FOREACH_MUTABLE(orphan, DEVFS_ORPHANLIST(mp), link, orphan2)	{
1959 		count++;
1960 		if (cleanup) {
1961 			orphan->node->flags |= DEVFS_NO_TRACE;
1962 			devfs_freep(orphan->node);
1963 			TAILQ_REMOVE(DEVFS_ORPHANLIST(mp), orphan, link);
1964 			kfree(orphan, M_DEVFS);
1965 		}
1966 	}
1967 
1968 	return count;
1969 }
1970 
1971 /*
1972  * Fetch an ino_t from the global d_ino by increasing it
1973  * while spinlocked.
1974  */
1975 static ino_t
1976 devfs_fetch_ino(void)
1977 {
1978 	ino_t	ret;
1979 
1980 	spin_lock_wr(&ino_lock);
1981 	ret = d_ino++;
1982 	spin_unlock_wr(&ino_lock);
1983 
1984 	return ret;
1985 }
1986 
1987 /*
1988  * Allocates a new cdev and initializes it's most basic
1989  * fields.
1990  */
1991 cdev_t
1992 devfs_new_cdev(struct dev_ops *ops, int minor)
1993 {
1994 //	cdev_t dev = objcache_get(devfs_dev_cache, M_WAITOK);
1995 //	memset(dev, 0, sizeof(struct cdev));
1996 
1997 	cdev_t dev = sysref_alloc(&cdev_sysref_class);
1998 	sysref_activate(&dev->si_sysref);
1999 	reference_dev(dev);
2000 	devfs_debug(DEVFS_DEBUG_DEBUG, "new_cdev: clearing first %d bytes\n", offsetof(struct cdev, si_sysref));
2001 	memset(dev, 0, offsetof(struct cdev, si_sysref));
2002 
2003 	dev->si_uid = 0;
2004 	dev->si_gid = 0;
2005 	dev->si_perms = 0;
2006 	dev->si_drv1 = NULL;
2007 	dev->si_drv2 = NULL;
2008 	dev->si_lastread = 0;		/* time_second */
2009 	dev->si_lastwrite = 0;		/* time_second */
2010 
2011 	dev->si_ops = ops;
2012 	dev->si_flags = SI_HASHED | SI_ADHOC; //XXX: any real use?
2013 	dev->si_umajor = 0;
2014 	dev->si_uminor = minor;
2015 	dev->si_inode = devfs_fetch_ino();
2016 
2017 	return dev;
2018 }
2019 
2020 
2021 static void devfs_cdev_terminate(cdev_t dev)
2022 {
2023 	int locked = 0;
2024 
2025 	/* Check if it is locked already. if not, we acquire the devfs lock */
2026 	if (!(lockstatus(&devfs_lock, curthread)) == LK_EXCLUSIVE) {
2027 		lockmgr(&devfs_lock, LK_EXCLUSIVE);
2028 		locked = 1;
2029 	}
2030 
2031 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_cdev_terminate: Taking care of dev->si_name=%s\n", dev->si_name);
2032 
2033 	/* Propagate destruction, just in case */
2034 	devfs_propagate_dev(dev, 0);
2035 
2036 	/* If we acquired the lock, we also get rid of it */
2037 	if (locked)
2038 		lockmgr(&devfs_lock, LK_RELEASE);
2039 
2040 	/* Finally destroy the device */
2041 	sysref_put(&dev->si_sysref);
2042 }
2043 
2044 /*
2045  * Frees a given cdev
2046  */
2047 int
2048 devfs_destroy_cdev(cdev_t dev)
2049 {
2050 	release_dev(dev);
2051 	//objcache_put(devfs_dev_cache, dev);
2052 	return 0;
2053 }
2054 
2055 /*
2056  * Links a given cdev into the dev list.
2057  */
2058 int
2059 devfs_link_dev(cdev_t dev)
2060 {
2061 	dev->si_flags |= SI_DEVFS_LINKED;
2062 	TAILQ_INSERT_TAIL(&devfs_dev_list, dev, link);
2063 
2064 	return 0;
2065 }
2066 
2067 /*
2068  * Removes a given cdev from the dev list.
2069  */
2070 int
2071 devfs_unlink_dev(cdev_t dev)
2072 {
2073 	if ((dev->si_flags & SI_DEVFS_LINKED)) {
2074 		TAILQ_REMOVE(&devfs_dev_list, dev, link);
2075 		dev->si_flags &= ~SI_DEVFS_LINKED;
2076 	}
2077 
2078 	return 0;
2079 }
2080 
2081 void
2082 devfs_config(void *arg)
2083 {
2084 	devfs_msg_t msg;
2085 
2086 	msg = devfs_msg_get();
2087 
2088 	kprintf("devfs_config: sync'ing up\n");
2089 	msg = devfs_msg_send_sync(DEVFS_SYNC, msg);
2090 	devfs_msg_put(msg);
2091 }
2092 
2093 /*
2094  * Called on init of devfs; creates the objcaches and
2095  * spawns off the devfs core thread. Also initializes
2096  * locks.
2097  */
2098 static void
2099 devfs_init(void)
2100 {
2101 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_init() called\n");
2102 	/* Create objcaches for nodes, msgs and devs */
2103     devfs_node_cache = objcache_create("devfs-node-cache", 0, 0,
2104 			NULL, NULL, NULL,
2105 			objcache_malloc_alloc,
2106 			objcache_malloc_free,
2107 			&devfs_node_malloc_args );
2108 
2109     devfs_msg_cache = objcache_create("devfs-msg-cache", 0, 0,
2110 			NULL, NULL, NULL,
2111 			objcache_malloc_alloc,
2112 			objcache_malloc_free,
2113 			&devfs_msg_malloc_args );
2114 
2115     devfs_dev_cache = objcache_create("devfs-dev-cache", 0, 0,
2116 			NULL, NULL, NULL,
2117 			objcache_malloc_alloc,
2118 			objcache_malloc_free,
2119 			&devfs_dev_malloc_args );
2120 
2121 	/* Initialize the reply-only port which acts as a message drain */
2122 	lwkt_initport_replyonly(&devfs_dispose_port, devfs_msg_autofree_reply);
2123 
2124 	/* Initialize *THE* devfs lock */
2125 	lockinit(&devfs_lock, "devfs_core lock", 0, 0);
2126 
2127 
2128 	lwkt_create(devfs_msg_core, /*args*/NULL, &td_core, NULL,
2129 		    0, 0, "devfs_msg_core");
2130 
2131 	tsleep(td_core/*devfs_id*/, 0, "devfsc", 0);
2132 
2133 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_init finished\n");
2134 }
2135 
2136 /*
2137  * Called on unload of devfs; takes care of destroying the core
2138  * and the objcaches. Also removes aliases that are no longer needed.
2139  */
2140 static void
2141 devfs_uninit(void)
2142 {
2143 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_uninit() called\n");
2144 
2145 	devfs_msg_send(DEVFS_TERMINATE_CORE, NULL);
2146 
2147 	tsleep(td_core/*devfs_id*/, 0, "devfsc", 0);
2148 	tsleep(td_core/*devfs_id*/, 0, "devfsc", 10000);
2149 
2150 	/* Destroy the objcaches */
2151 	objcache_destroy(devfs_msg_cache);
2152 	objcache_destroy(devfs_node_cache);
2153 	objcache_destroy(devfs_dev_cache);
2154 
2155 	devfs_alias_reap();
2156 }
2157 
2158 /*
2159  * This is a sysctl handler to assist userland devname(3) to
2160  * find the device name for a given udev.
2161  */
2162 static int
2163 devfs_sysctl_devname_helper(SYSCTL_HANDLER_ARGS)
2164 {
2165 	udev_t 	udev;
2166 	cdev_t	found;
2167 	int		error;
2168 
2169 
2170 	if ((error = SYSCTL_IN(req, &udev, sizeof(udev_t))))
2171 		return (error);
2172 
2173 	devfs_debug(DEVFS_DEBUG_DEBUG, "devfs sysctl, received udev: %d\n", udev);
2174 
2175 	if (udev == NOUDEV)
2176 		return(EINVAL);
2177 
2178 	if ((found = devfs_find_device_by_udev(udev)) == NULL)
2179 		return(ENOENT);
2180 
2181 	return(SYSCTL_OUT(req, found->si_name, strlen(found->si_name) + 1));
2182 }
2183 
2184 
2185 SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY,
2186 			NULL, 0, devfs_sysctl_devname_helper, "", "helper for devname(3)");
2187 
2188 static SYSCTL_NODE(_vfs, OID_AUTO, devfs, CTLFLAG_RW, 0, "devfs");
2189 TUNABLE_INT("vfs.devfs.debug", &devfs_debug_enable);
2190 SYSCTL_INT(_vfs_devfs, OID_AUTO, debug, CTLFLAG_RW, &devfs_debug_enable, 0, "Enable DevFS debugging");
2191 
2192 SYSINIT(vfs_devfs_register, SI_SUB_PRE_DRIVERS, SI_ORDER_FIRST, devfs_init, NULL);
2193 SYSUNINIT(vfs_devfs_register, SI_SUB_PRE_DRIVERS, SI_ORDER_ANY, devfs_uninit, NULL);
2194