Lines Matching +full:de +full:- +full:active

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
5 * Poul-Henning Kamp. All rights reserved.
52 * The one true (but secret) list of active devices in the system.
90 if (req->newlen == sizeof(ud_compat)) { in sysctl_devname()
104 if (cdp->cdp_inode == ud) { in sysctl_devname()
105 dev = &cdp->cdp_c; in sysctl_devname()
112 error = SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1); in sysctl_devname()
139 mtx_init(&cdp->cdp_threadlock, "devthrd", NULL, MTX_DEF); in devfs_alloc()
141 cdp->cdp_dirents = &cdp->cdp_dirent0; in devfs_alloc()
143 cdev = &cdp->cdp_c; in devfs_alloc()
144 LIST_INIT(&cdev->si_children); in devfs_alloc()
146 cdev->si_atime = cdev->si_mtime = cdev->si_ctime = ts; in devfs_alloc()
159 if ((cdp->cdp_flags & CDP_ACTIVE) == 0) in devfs_dev_exists()
161 if (devfs_pathpath(cdp->cdp_c.si_name, name) != 0) in devfs_dev_exists()
163 if (devfs_pathpath(name, cdp->cdp_c.si_name) != 0) in devfs_dev_exists()
178 KASSERT((cdp->cdp_flags & (CDP_ACTIVE | CDP_ON_ACTIVE_LIST)) == 0, in devfs_free()
179 ("%s: cdp %p (%s) still on active list", in devfs_free()
180 __func__, cdp, cdev->si_name)); in devfs_free()
181 if (cdev->si_cred != NULL) in devfs_free()
182 crfree(cdev->si_cred); in devfs_free()
183 devfs_free_cdp_inode(cdp->cdp_inode); in devfs_free()
184 if (cdp->cdp_maxdirent > 0) in devfs_free()
185 free(cdp->cdp_dirents, M_DEVFS2); in devfs_free()
186 mtx_destroy(&cdp->cdp_threadlock); in devfs_free()
193 struct devfs_dirent *de; in devfs_find() local
195 TAILQ_FOREACH(de, &dd->de_dlist, de_list) { in devfs_find()
196 if (namelen != de->de_dirent->d_namlen) in devfs_find()
198 if (type != 0 && type != de->de_dirent->d_type) in devfs_find()
202 * The race with finding non-active name is not in devfs_find()
206 if (de->de_dirent->d_type == DT_CHR && in devfs_find()
207 (de->de_cdp->cdp_flags & CDP_ACTIVE) == 0) in devfs_find()
210 if (bcmp(name, de->de_dirent->d_name, namelen) != 0) in devfs_find()
214 KASSERT(de == NULL || (de->de_flags & DE_DOOMED) == 0, in devfs_find()
216 return (de); in devfs_find()
223 struct devfs_dirent *de; in devfs_newdirent() local
227 i = sizeof(*de) + GENERIC_DIRSIZ(&d); in devfs_newdirent()
228 de = malloc(i, M_DEVFS3, M_WAITOK | M_ZERO); in devfs_newdirent()
229 de->de_dirent = (struct dirent *)(de + 1); in devfs_newdirent()
230 de->de_dirent->d_namlen = namelen; in devfs_newdirent()
231 de->de_dirent->d_reclen = GENERIC_DIRSIZ(&d); in devfs_newdirent()
232 bcopy(name, de->de_dirent->d_name, namelen); in devfs_newdirent()
233 dirent_terminate(de->de_dirent); in devfs_newdirent()
234 vfs_timestamp(&de->de_ctime); in devfs_newdirent()
235 de->de_mtime = de->de_atime = de->de_ctime; in devfs_newdirent()
236 de->de_links = 1; in devfs_newdirent()
237 de->de_holdcnt = 1; in devfs_newdirent()
239 mac_devfs_init(de); in devfs_newdirent()
241 return (de); in devfs_newdirent()
245 devfs_parent_dirent(struct devfs_dirent *de) in devfs_parent_dirent() argument
248 if (de->de_dirent->d_type != DT_DIR) in devfs_parent_dirent()
249 return (de->de_dir); in devfs_parent_dirent()
251 if (de->de_flags & (DE_DOT | DE_DOTDOT)) in devfs_parent_dirent()
254 de = TAILQ_FIRST(&de->de_dlist); /* "." */ in devfs_parent_dirent()
255 if (de == NULL) in devfs_parent_dirent()
257 de = TAILQ_NEXT(de, de_list); /* ".." */ in devfs_parent_dirent()
258 if (de == NULL) in devfs_parent_dirent()
261 return (de->de_dir); in devfs_parent_dirent()
269 struct devfs_dirent *de; in devfs_vmkdir() local
273 TAILQ_INIT(&dd->de_dlist); in devfs_vmkdir()
274 dd->de_dirent->d_type = DT_DIR; in devfs_vmkdir()
275 dd->de_mode = 0555; in devfs_vmkdir()
276 dd->de_links = 2; in devfs_vmkdir()
277 dd->de_dir = dd; in devfs_vmkdir()
279 dd->de_inode = inode; in devfs_vmkdir()
281 dd->de_inode = alloc_unr(devfs_inos); in devfs_vmkdir()
289 de = devfs_newdirent(".", 1); in devfs_vmkdir()
290 de->de_dirent->d_type = DT_DIR; in devfs_vmkdir()
291 de->de_flags |= DE_DOT; in devfs_vmkdir()
292 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); in devfs_vmkdir()
293 de->de_dir = dd; in devfs_vmkdir()
296 de = devfs_newdirent("..", 2); in devfs_vmkdir()
297 de->de_dirent->d_type = DT_DIR; in devfs_vmkdir()
298 de->de_flags |= DE_DOTDOT; in devfs_vmkdir()
299 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); in devfs_vmkdir()
301 de->de_dir = dd; in devfs_vmkdir()
303 de->de_dir = dotdot; in devfs_vmkdir()
304 sx_assert(&dmp->dm_lock, SX_XLOCKED); in devfs_vmkdir()
305 TAILQ_INSERT_TAIL(&dotdot->de_dlist, dd, de_list); in devfs_vmkdir()
306 dotdot->de_links++; in devfs_vmkdir()
311 mac_devfs_create_directory(dmp->dm_mount, name, namelen, dd); in devfs_vmkdir()
317 devfs_dirent_free(struct devfs_dirent *de) in devfs_dirent_free() argument
321 vp = de->de_vnode; in devfs_dirent_free()
323 if (vp != NULL && vp->v_data == de) in devfs_dirent_free()
324 vp->v_data = NULL; in devfs_dirent_free()
326 free(de, M_DEVFS3); in devfs_dirent_free()
334 devfs_rmdir_empty(struct devfs_mount *dm, struct devfs_dirent *de) in devfs_rmdir_empty() argument
338 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_rmdir_empty()
341 KASSERT(de->de_dirent->d_type == DT_DIR, in devfs_rmdir_empty()
342 ("devfs_rmdir_empty: de is not a directory")); in devfs_rmdir_empty()
344 if ((de->de_flags & DE_DOOMED) != 0 || de == dm->dm_rootdir) in devfs_rmdir_empty()
347 de_dot = TAILQ_FIRST(&de->de_dlist); in devfs_rmdir_empty()
355 dd = devfs_parent_dirent(de); in devfs_rmdir_empty()
357 TAILQ_REMOVE(&de->de_dlist, de_dot, de_list); in devfs_rmdir_empty()
358 TAILQ_REMOVE(&de->de_dlist, de_dotdot, de_list); in devfs_rmdir_empty()
359 TAILQ_REMOVE(&dd->de_dlist, de, de_list); in devfs_rmdir_empty()
361 devfs_delete(dm, de, DEVFS_DEL_NORECURSE); in devfs_rmdir_empty()
369 de = dd; in devfs_rmdir_empty()
375 * dm->dm_lock may be temporary dropped.
378 devfs_delete(struct devfs_mount *dm, struct devfs_dirent *de, int flags) in devfs_delete() argument
383 KASSERT((de->de_flags & DE_DOOMED) == 0, in devfs_delete()
385 de->de_flags |= DE_DOOMED; in devfs_delete()
388 dd = devfs_parent_dirent(de); in devfs_delete()
391 if (de->de_flags & DE_USER) { in devfs_delete()
399 vp = de->de_vnode; in devfs_delete()
403 sx_unlock(&dm->dm_lock); in devfs_delete()
408 sx_xlock(&dm->dm_lock); in devfs_delete()
411 if (de->de_symlink) { in devfs_delete()
412 free(de->de_symlink, M_DEVFS); in devfs_delete()
413 de->de_symlink = NULL; in devfs_delete()
416 mac_devfs_destroy(de); in devfs_delete()
418 if (de->de_inode > DEVFS_ROOTINO) { in devfs_delete()
419 devfs_free_cdp_inode(de->de_inode); in devfs_delete()
420 de->de_inode = 0; in devfs_delete()
422 if (DEVFS_DE_DROP(de)) in devfs_delete()
423 devfs_dirent_free(de); in devfs_delete()
442 struct devfs_dirent *de; in devfs_purge() local
444 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_purge()
453 de = TAILQ_LAST(&dd->de_dlist, devfs_dlist_head); in devfs_purge()
454 if (de == NULL) in devfs_purge()
456 TAILQ_REMOVE(&dd->de_dlist, de, de_list); in devfs_purge()
457 if (de->de_flags & DE_USER) in devfs_purge()
459 if (de->de_flags & (DE_DOT | DE_DOTDOT)) in devfs_purge()
460 devfs_delete(dm, de, DEVFS_DEL_NORECURSE); in devfs_purge()
461 else if (de->de_dirent->d_type == DT_DIR) in devfs_purge()
462 devfs_purge(dm, de); in devfs_purge()
464 devfs_delete(dm, de, DEVFS_DEL_NORECURSE); in devfs_purge()
468 else if ((dd->de_flags & DE_DOOMED) == 0) in devfs_purge()
484 siz = (dm->dm_idx + 1) * sizeof *dep; in devfs_metoo()
487 if (dm->dm_idx <= cdp->cdp_maxdirent) { in devfs_metoo()
493 memcpy(dep, cdp->cdp_dirents, (cdp->cdp_maxdirent + 1) * sizeof *dep); in devfs_metoo()
494 olddep = cdp->cdp_maxdirent > 0 ? cdp->cdp_dirents : NULL; in devfs_metoo()
495 cdp->cdp_dirents = dep; in devfs_metoo()
500 cdp->cdp_maxdirent = dm->dm_idx; in devfs_metoo()
512 struct devfs_dirent *de; in devfs_populate_loop() local
518 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_populate_loop()
521 KASSERT(cdp->cdp_dirents != NULL, ("NULL cdp_dirents")); in devfs_populate_loop()
522 KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) != 0, in devfs_populate_loop()
523 ("%s: cdp %p (%s) should not be on active list", in devfs_populate_loop()
524 __func__, cdp, cdp->cdp_c.si_name)); in devfs_populate_loop()
530 if ((cleanup || !(cdp->cdp_flags & CDP_ACTIVE)) && in devfs_populate_loop()
531 dm->dm_idx <= cdp->cdp_maxdirent && in devfs_populate_loop()
532 cdp->cdp_dirents[dm->dm_idx] != NULL) { in devfs_populate_loop()
533 de = cdp->cdp_dirents[dm->dm_idx]; in devfs_populate_loop()
534 cdp->cdp_dirents[dm->dm_idx] = NULL; in devfs_populate_loop()
535 KASSERT(cdp == de->de_cdp, in devfs_populate_loop()
537 cdp->cdp_c.si_name, cdp, de->de_cdp)); in devfs_populate_loop()
538 KASSERT(de->de_dir != NULL, ("Null de->de_dir")); in devfs_populate_loop()
541 TAILQ_REMOVE(&de->de_dir->de_dlist, de, de_list); in devfs_populate_loop()
542 de->de_cdp = NULL; in devfs_populate_loop()
543 de->de_inode = 0; in devfs_populate_loop()
544 devfs_delete(dm, de, 0); in devfs_populate_loop()
546 cdp->cdp_inuse--; in devfs_populate_loop()
553 if (!(cdp->cdp_flags & CDP_ACTIVE)) { in devfs_populate_loop()
554 if (cdp->cdp_inuse > 0) in devfs_populate_loop()
556 cdp->cdp_flags &= ~CDP_ON_ACTIVE_LIST; in devfs_populate_loop()
559 dev_rel(&cdp->cdp_c); in devfs_populate_loop()
567 KASSERT((cdp->cdp_flags & CDP_ACTIVE), ("Bogons, I tell ya'!")); in devfs_populate_loop()
569 if (dm->dm_idx <= cdp->cdp_maxdirent && in devfs_populate_loop()
570 cdp->cdp_dirents[dm->dm_idx] != NULL) { in devfs_populate_loop()
571 de = cdp->cdp_dirents[dm->dm_idx]; in devfs_populate_loop()
572 KASSERT(cdp == de->de_cdp, ("inconsistent cdp")); in devfs_populate_loop()
576 cdp->cdp_inuse++; in devfs_populate_loop()
579 if (dm->dm_idx > cdp->cdp_maxdirent) in devfs_populate_loop()
582 dd = dm->dm_rootdir; in devfs_populate_loop()
583 s = cdp->cdp_c.si_name; in devfs_populate_loop()
589 de = devfs_find(dd, s, q - s, 0); in devfs_populate_loop()
590 if (de == NULL) in devfs_populate_loop()
591 de = devfs_vmkdir(dm, s, q - s, dd, 0); in devfs_populate_loop()
592 else if (de->de_dirent->d_type == DT_LNK) { in devfs_populate_loop()
593 de = devfs_find(dd, s, q - s, DT_DIR); in devfs_populate_loop()
594 if (de == NULL) in devfs_populate_loop()
595 de = devfs_vmkdir(dm, s, q - s, dd, 0); in devfs_populate_loop()
596 de->de_flags |= DE_COVERED; in devfs_populate_loop()
599 dd = de; in devfs_populate_loop()
600 KASSERT(dd->de_dirent->d_type == DT_DIR && in devfs_populate_loop()
601 (dd->de_flags & (DE_DOT | DE_DOTDOT)) == 0, in devfs_populate_loop()
603 __func__, cdp->cdp_c.si_name)); in devfs_populate_loop()
606 de = devfs_find(dd, s, q - s, DT_LNK); in devfs_populate_loop()
607 if (de != NULL) in devfs_populate_loop()
610 de = devfs_newdirent(s, q - s); in devfs_populate_loop()
611 if (cdp->cdp_c.si_flags & SI_ALIAS) { in devfs_populate_loop()
612 de->de_uid = 0; in devfs_populate_loop()
613 de->de_gid = 0; in devfs_populate_loop()
614 de->de_mode = 0755; in devfs_populate_loop()
615 de->de_dirent->d_type = DT_LNK; in devfs_populate_loop()
616 pdev = cdp->cdp_c.si_parent; in devfs_populate_loop()
619 while (dt != dm->dm_rootdir && in devfs_populate_loop()
622 j = depth * 3 + strlen(pdev->si_name) + 1; in devfs_populate_loop()
623 de->de_symlink = malloc(j, M_DEVFS, M_WAITOK); in devfs_populate_loop()
624 de->de_symlink[0] = 0; in devfs_populate_loop()
625 while (depth-- > 0) in devfs_populate_loop()
626 strcat(de->de_symlink, "../"); in devfs_populate_loop()
627 strcat(de->de_symlink, pdev->si_name); in devfs_populate_loop()
629 de->de_uid = cdp->cdp_c.si_uid; in devfs_populate_loop()
630 de->de_gid = cdp->cdp_c.si_gid; in devfs_populate_loop()
631 de->de_mode = cdp->cdp_c.si_mode; in devfs_populate_loop()
632 de->de_dirent->d_type = DT_CHR; in devfs_populate_loop()
634 de->de_flags |= de_flags; in devfs_populate_loop()
635 de->de_inode = cdp->cdp_inode; in devfs_populate_loop()
636 de->de_cdp = cdp; in devfs_populate_loop()
638 mac_devfs_create_device(cdp->cdp_c.si_cred, dm->dm_mount, in devfs_populate_loop()
639 &cdp->cdp_c, de); in devfs_populate_loop()
641 de->de_dir = dd; in devfs_populate_loop()
642 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); in devfs_populate_loop()
643 devfs_rules_apply(dm, de); in devfs_populate_loop()
645 /* XXX: could check that cdp is still active here */ in devfs_populate_loop()
646 KASSERT(cdp->cdp_dirents[dm->dm_idx] == NULL, in devfs_populate_loop()
648 cdp->cdp_dirents[dm->dm_idx] = de; in devfs_populate_loop()
649 KASSERT(de->de_cdp != (void *)0xdeadc0de, in devfs_populate_loop()
662 return (dm->dm_generation != devfs_generation); in devfs_populate_needed()
673 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_populate()
679 dm->dm_generation = gen; in devfs_populate()
689 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_cleanup()
692 devfs_purge(dm, dm->dm_rootdir); in devfs_cleanup()
708 KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) == 0, in devfs_create()
709 ("%s: cdp %p (%s) already on active list", in devfs_create()
710 __func__, cdp, dev->si_name)); in devfs_create()
711 cdp->cdp_flags |= (CDP_ACTIVE | CDP_ON_ACTIVE_LIST); in devfs_create()
712 cdp->cdp_inode = alloc_unrl(devfs_inos); in devfs_create()
725 cdp->cdp_flags &= ~CDP_ACTIVE; in devfs_destroy()