Lines Matching +full:de +full:- +full:be
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36 * A note on locking: Only foreign entry points (non-static functions)
40 * A note on namespace: devfs_rules_* are the non-static functions for
47 * ruleset; it cannot be deleted or changed in any way. This may be
48 * assumed inside the code; e.g., a ruleset of 0 may be interpreted to
50 * command-dependent, but in no case is there a real rule with number
55 * appropriate for the error but that would be less ambiguous than the
59 * list", and the userland expects ENOENT to be this indicator); this
60 * way, when an operation fails, it's clear that what couldn't be
104 struct devfs_mount *dm, struct devfs_dirent *de);
109 static struct cdev *devfs_rule_getdev(struct devfs_dirent *de);
113 struct devfs_dirent *de);
115 struct devfs_dirent *de);
117 struct devfs_dirent *de, unsigned depth);
120 struct devfs_mount *dm, struct devfs_dirent *de,
136 * Called to apply the proper rules for 'de' before it can be
137 * exposed to the userland. This should be called with an exclusive
141 devfs_rules_apply(struct devfs_mount *dm, struct devfs_dirent *de) in devfs_rules_apply() argument
145 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_rules_apply()
147 if (dm->dm_ruleset == 0) in devfs_rules_apply()
150 ds = devfs_ruleset_bynum(dm->dm_ruleset); in devfs_rules_apply()
151 KASSERT(ds != NULL, ("mount-point has NULL ruleset")); in devfs_rules_apply()
152 devfs_ruleset_applyde(ds, dm, de, devfs_rule_depth); in devfs_rules_apply()
170 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_rules_ioctl()
190 dk = devfs_rule_byid(dr->dr_id); in devfs_rules_ioctl()
195 if (rid2rsn(dr->dr_id) == 0) { in devfs_rules_ioctl()
214 * applied in the normal way. This can be done in the in devfs_rules_ioctl()
221 if (dr->dr_iacts & DRA_INCSET && in devfs_rules_ioctl()
222 devfs_ruleset_bynum(dr->dr_incset) == NULL) { in devfs_rules_ioctl()
227 memcpy(&dk->dk_rule, dr, sizeof(*dr)); in devfs_rules_ioctl()
249 ds = dk->dk_ruleset; in devfs_rules_ioctl()
263 * interprets 0 to mean "auto-number"). in devfs_rules_ioctl()
265 ds = devfs_ruleset_bynum(rid2rsn(dr->dr_id)); in devfs_rules_ioctl()
270 rnum = rid2rn(dr->dr_id); in devfs_rules_ioctl()
271 TAILQ_FOREACH(dk, &ds->ds_rules, dk_list) { in devfs_rules_ioctl()
272 if (rid2rn(dk->dk_rule.dr_id) > rnum) in devfs_rules_ioctl()
279 memcpy(dr, &dk->dk_rule, sizeof(*dr)); in devfs_rules_ioctl()
298 if (ds->ds_number > rsnum) in devfs_rules_ioctl()
305 *(devfs_rsnum *)data = ds->ds_number; in devfs_rules_ioctl()
320 * Note that after this operation, rid2rsn(rid) might still be 0, and
322 * from the userland, it means "current ruleset for this mount-point".
329 return (mkrid(dm->dm_ruleset, rid2rn(rid))); in devfs_rid_input()
335 * Apply dk to de and everything under de.
340 * XXX: a linear search could be done through the cdev list instead.
344 struct devfs_dirent *de) in devfs_rule_applyde_recursive() argument
348 TAILQ_FOREACH(de2, &de->de_dlist, de_list) in devfs_rule_applyde_recursive()
350 devfs_rule_run(dk, dm, de, devfs_rule_depth); in devfs_rule_applyde_recursive()
360 devfs_rule_applyde_recursive(dk, dm, dm->dm_rootdir); in devfs_rule_applydm()
373 dk = TAILQ_LAST(&ds->ds_rules, rulehead); in devfs_rule_autonumber()
377 *rnump = rid2rn(dk->dk_rule.dr_id) + 100; in devfs_rule_autonumber()
379 if (*rnump < rid2rn(dk->dk_rule.dr_id)) in devfs_rule_autonumber()
382 KASSERT(devfs_rule_byid(mkrid(ds->ds_number, *rnump)) == NULL, in devfs_rule_autonumber()
401 TAILQ_FOREACH(dk, &ds->ds_rules, dk_list) { in devfs_rule_byid()
402 if (rid2rn(dk->dk_rule.dr_id) == rn) in devfs_rule_byid()
404 else if (rid2rn(dk->dk_rule.dr_id) > rn) in devfs_rule_byid()
411 * Remove dkp from any lists it may be on and remove memory associated
419 if (dk->dk_rule.dr_iacts & DRA_INCSET) { in devfs_rule_delete()
420 ds = devfs_ruleset_bynum(dk->dk_rule.dr_incset); in devfs_rule_delete()
422 --ds->ds_refcount; in devfs_rule_delete()
425 ds = dk->dk_ruleset; in devfs_rule_delete()
426 TAILQ_REMOVE(&ds->ds_rules, dk, dk_list); in devfs_rule_delete()
433 * Get a struct cdev *corresponding to de so we can try to match rules based
440 devfs_rule_getdev(struct devfs_dirent *de) in devfs_rule_getdev() argument
443 if (de->de_cdp == NULL) in devfs_rule_getdev()
445 if (de->de_cdp->cdp_flags & CDP_ACTIVE) in devfs_rule_getdev()
446 return (&de->de_cdp->cdp_c); in devfs_rule_getdev()
460 if (dr->dr_magic != DEVFS_MAGIC) in devfs_rule_input()
462 dr->dr_id = devfs_rid_input(dr->dr_id, dm); in devfs_rule_input()
468 * krule). The value of dr is copied, so the pointer may be destroyed
486 if (dr->dr_iacts & DRA_INCSET) { in devfs_rule_insert()
487 dsi = devfs_ruleset_bynum(dr->dr_incset); in devfs_rule_insert()
493 rsnum = rid2rsn(dr->dr_id); in devfs_rule_insert()
499 dkrn = rid2rn(dr->dr_id); in devfs_rule_insert()
509 dk->dk_ruleset = ds; in devfs_rule_insert()
511 ++dsi->ds_refcount; in devfs_rule_insert()
513 memcpy(&dk->dk_rule, dr, sizeof(*dr)); in devfs_rule_insert()
514 dk->dk_rule.dr_id = mkrid(rid2rsn(dk->dk_rule.dr_id), dkrn); in devfs_rule_insert()
516 TAILQ_FOREACH(k1, &ds->ds_rules, dk_list) { in devfs_rule_insert()
517 if (rid2rn(k1->dk_rule.dr_id) > dkrn) { in devfs_rule_insert()
523 TAILQ_INSERT_TAIL(&ds->ds_rules, dk, dk_list); in devfs_rule_insert()
528 * Determine whether dk matches de. Returns 1 if dk should be run on
529 * de; 0, otherwise.
533 struct devfs_dirent *de) in devfs_rule_match() argument
535 struct devfs_rule *dr = &dk->dk_rule; in devfs_rule_match()
540 dev = devfs_rule_getdev(de); in devfs_rule_match()
551 * be run (such as if there are no conditions). in devfs_rule_match()
553 if (dr->dr_icond & DRC_DSWFLAGS) { in devfs_rule_match()
559 if ((dsw->d_flags & dr->dr_dswflags) == 0) { in devfs_rule_match()
565 if (dr->dr_icond & DRC_PATHPTRN) in devfs_rule_match()
566 if (!devfs_rule_matchpath(dk, dm, de)) in devfs_rule_match()
573 * Determine whether dk matches de on account of dr_pathptrn.
577 struct devfs_dirent *de) in devfs_rule_matchpath() argument
579 struct devfs_rule *dr = &dk->dk_rule; in devfs_rule_matchpath()
585 dev = devfs_rule_getdev(de); in devfs_rule_matchpath()
587 pname = dev->si_name; in devfs_rule_matchpath()
588 else if (de->de_dirent->d_type == DT_LNK || in devfs_rule_matchpath()
589 (de->de_dirent->d_type == DT_DIR && de != dm->dm_rootdir && in devfs_rule_matchpath()
590 (de->de_flags & (DE_DOT | DE_DOTDOT)) == 0)) { in devfs_rule_matchpath()
592 pname = devfs_fqpn(specname, dm, de, NULL); in devfs_rule_matchpath()
597 match = fnmatch(dr->dr_pathptrn, pname, FNM_PATHNAME) == 0; in devfs_rule_matchpath()
603 * Run dk on de.
607 struct devfs_dirent *de, unsigned depth) in devfs_rule_run() argument
609 struct devfs_rule *dr = &dk->dk_rule; in devfs_rule_run()
612 if (!devfs_rule_match(dk, dm, de)) in devfs_rule_run()
614 if (dr->dr_iacts & DRA_BACTS) { in devfs_rule_run()
615 if (dr->dr_bacts & DRB_HIDE) in devfs_rule_run()
616 de->de_flags |= DE_WHITEOUT; in devfs_rule_run()
617 if (dr->dr_bacts & DRB_UNHIDE) in devfs_rule_run()
618 de->de_flags &= ~DE_WHITEOUT; in devfs_rule_run()
620 if (dr->dr_iacts & DRA_UID) in devfs_rule_run()
621 de->de_uid = dr->dr_uid; in devfs_rule_run()
622 if (dr->dr_iacts & DRA_GID) in devfs_rule_run()
623 de->de_gid = dr->dr_gid; in devfs_rule_run()
624 if (dr->dr_iacts & DRA_MODE) in devfs_rule_run()
625 de->de_mode = dr->dr_mode; in devfs_rule_run()
626 if (dr->dr_iacts & DRA_INCSET) { in devfs_rule_run()
633 * XXX: DoS the machine. I guess a rate-limited message in devfs_rule_run()
637 ds = devfs_ruleset_bynum(dk->dk_rule.dr_incset); in devfs_rule_run()
639 devfs_ruleset_applyde(ds, dm, de, depth - 1); in devfs_rule_run()
645 * Apply all the rules in ds to de.
649 struct devfs_dirent *de, unsigned depth) in devfs_ruleset_applyde() argument
653 TAILQ_FOREACH(dk, &ds->ds_rules, dk_list) in devfs_ruleset_applyde()
654 devfs_rule_run(dk, dm, de, depth); in devfs_ruleset_applyde()
669 * foreach(de in dm) in devfs_ruleset_applydm()
670 * apply(dk to de) in devfs_ruleset_applydm()
674 * foreach(de in dm) in devfs_ruleset_applydm()
676 * apply(dk to de) in devfs_ruleset_applydm()
681 TAILQ_FOREACH(dk, &ds->ds_rules, dk_list) in devfs_ruleset_applydm()
694 if (ds->ds_number == rsnum) in devfs_ruleset_bynum()
715 ds->ds_number = rsnum; in devfs_ruleset_create()
716 TAILQ_INIT(&ds->ds_rules); in devfs_ruleset_create()
719 if (s1->ds_number > rsnum) { in devfs_ruleset_create()
731 * anywhere. This should be called after every time a rule is deleted
738 KASSERT(ds->ds_number != 0, ("reaping ruleset zero ")); in devfs_ruleset_reap()
740 if (!TAILQ_EMPTY(&ds->ds_rules) || ds->ds_refcount != 0) in devfs_ruleset_reap()
755 if (dm->dm_ruleset != 0) { in devfs_ruleset_use()
756 cds = devfs_ruleset_bynum(dm->dm_ruleset); in devfs_ruleset_use()
757 --cds->ds_refcount; in devfs_ruleset_use()
762 dm->dm_ruleset = 0; in devfs_ruleset_use()
769 /* These should probably be made atomic somehow. */ in devfs_ruleset_use()
770 ++ds->ds_refcount; in devfs_ruleset_use()
771 dm->dm_ruleset = rsnum; in devfs_ruleset_use()
781 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_rules_cleanup()
782 if (dm->dm_ruleset != 0) { in devfs_rules_cleanup()
783 ds = devfs_ruleset_bynum(dm->dm_ruleset); in devfs_rules_cleanup()
784 --ds->ds_refcount; in devfs_rules_cleanup()
796 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_ruleset_set()
811 sx_assert(&dm->dm_lock, SX_XLOCKED); in devfs_ruleset_apply()
814 if (dm->dm_ruleset == 0) { in devfs_ruleset_apply()
818 ds = devfs_ruleset_bynum(dm->dm_ruleset); in devfs_ruleset_apply()