kern_conf.c (b17f9ad2c9da34e8544d02c3d530fe9fb41fdbe2) kern_conf.c (68f7a0139232f7ab92e2b10edf578342a50e0c8a)
1/*-
2 * Copyright (c) 1999-2002 Poul-Henning Kamp
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 668 unchanged lines hidden (view full) ---

677 devsw->d_flags |= D_INIT;
678
679 if (dsw2 != NULL)
680 cdevsw_free_devlocked(dsw2);
681 return (0);
682}
683
684static int
1/*-
2 * Copyright (c) 1999-2002 Poul-Henning Kamp
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 668 unchanged lines hidden (view full) ---

677 devsw->d_flags |= D_INIT;
678
679 if (dsw2 != NULL)
680 cdevsw_free_devlocked(dsw2);
681 return (0);
682}
683
684static int
685prep_devname(struct cdev *dev, const char *fmt, va_list ap)
686{
687 int len;
688 char *from, *q, *s, *to;
689
690 mtx_assert(&devmtx, MA_OWNED);
691
692 len = vsnrprintf(dev->__si_namebuf, sizeof(dev->__si_namebuf), 32,
693 fmt, ap);
694 if (len > sizeof(dev->__si_namebuf) - 1)
695 return (ENAMETOOLONG);
696
697 /* Strip leading slashes. */
698 for (from = dev->__si_namebuf; *from == '/'; from++)
699 ;
700
701 for (to = dev->__si_namebuf; *from != '\0'; from++, to++) {
702 /* Treat multiple sequential slashes as single. */
703 while (from[0] == '/' && from[1] == '/')
704 from++;
705 /* Trailing slash is considered invalid. */
706 if (from[0] == '/' && from[1] == '\0')
707 return (EINVAL);
708 *to = *from;
709 }
710 *to = '\0';
711
712 if (dev->__si_namebuf[0] == '\0')
713 return (EINVAL);
714
715 /* Disallow "." and ".." components. */
716 for (s = dev->__si_namebuf;;) {
717 for (q = s; *q != '/' && *q != '\0'; q++)
718 ;
719 if (q - s == 1 && s[0] == '.')
720 return (EINVAL);
721 if (q - s == 2 && s[0] == '.' && s[1] == '.')
722 return (EINVAL);
723 if (*q != '/')
724 break;
725 s = q + 1;
726 }
727
728 if (devfs_dev_exists(dev->__si_namebuf) != 0)
729 return (EEXIST);
730
731 return (0);
732}
733
734static int
685make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit,
686 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
687 va_list ap)
688{
735make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit,
736 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
737 va_list ap)
738{
689 struct cdev *dev;
690 int i, res;
739 struct cdev *dev, *dev_new;
740 int res;
691
692 KASSERT((flags & MAKEDEV_WAITOK) == 0 || (flags & MAKEDEV_NOWAIT) == 0,
693 ("make_dev_credv: both WAITOK and NOWAIT specified"));
741
742 KASSERT((flags & MAKEDEV_WAITOK) == 0 || (flags & MAKEDEV_NOWAIT) == 0,
743 ("make_dev_credv: both WAITOK and NOWAIT specified"));
694 dev = devfs_alloc(flags);
695 if (dev == NULL)
744 dev_new = devfs_alloc(flags);
745 if (dev_new == NULL)
696 return (ENOMEM);
697 dev_lock();
698 res = prep_cdevsw(devsw, flags);
699 if (res != 0) {
700 dev_unlock();
746 return (ENOMEM);
747 dev_lock();
748 res = prep_cdevsw(devsw, flags);
749 if (res != 0) {
750 dev_unlock();
701 devfs_free(dev);
751 devfs_free(dev_new);
702 return (res);
703 }
752 return (res);
753 }
704 dev = newdev(devsw, unit, dev);
754 dev = newdev(devsw, unit, dev_new);
755 if ((dev->si_flags & SI_NAMED) == 0)
756 res = prep_devname(dev, fmt, ap);
757 if (res != 0) {
758 if ((flags & MAKEDEV_CHECKNAME) == 0) {
759 panic(
760 "make_dev_credv: bad si_name (error=%d, si_name=%s)",
761 res, dev->si_name);
762 }
763 if (dev == dev_new) {
764 LIST_REMOVE(dev, si_list);
765 dev_unlock();
766 devfs_free(dev);
767 }
768 return (res);
769 }
705 if (flags & MAKEDEV_REF)
706 dev_refl(dev);
707 if (flags & MAKEDEV_ETERNAL)
708 dev->si_flags |= SI_ETERNAL;
709 if (dev->si_flags & SI_CHEAPCLONE &&
710 dev->si_flags & SI_NAMED) {
711 /*
712 * This is allowed as it removes races and generally
713 * simplifies cloning devices.
714 * XXX: still ??
715 */
716 dev_unlock_and_free();
717 *dres = dev;
718 return (0);
719 }
720 KASSERT(!(dev->si_flags & SI_NAMED),
721 ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
722 devsw->d_name, dev2unit(dev), devtoname(dev)));
770 if (flags & MAKEDEV_REF)
771 dev_refl(dev);
772 if (flags & MAKEDEV_ETERNAL)
773 dev->si_flags |= SI_ETERNAL;
774 if (dev->si_flags & SI_CHEAPCLONE &&
775 dev->si_flags & SI_NAMED) {
776 /*
777 * This is allowed as it removes races and generally
778 * simplifies cloning devices.
779 * XXX: still ??
780 */
781 dev_unlock_and_free();
782 *dres = dev;
783 return (0);
784 }
785 KASSERT(!(dev->si_flags & SI_NAMED),
786 ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
787 devsw->d_name, dev2unit(dev), devtoname(dev)));
723
724 i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
725 if (i > (sizeof dev->__si_namebuf - 1)) {
726 printf("WARNING: Device name truncated! (%s)\n",
727 dev->__si_namebuf);
728 }
729
730 dev->si_flags |= SI_NAMED;
731 if (cr != NULL)
732 dev->si_cred = crhold(cr);
733 dev->si_uid = uid;
734 dev->si_gid = gid;
735 dev->si_mode = mode;
736
737 devfs_create(dev);

--- 13 unchanged lines hidden (view full) ---

751 struct cdev *dev;
752 va_list ap;
753 int res;
754
755 va_start(ap, fmt);
756 res = make_dev_credv(0, &dev, devsw, unit, NULL, uid, gid, mode, fmt,
757 ap);
758 va_end(ap);
788 dev->si_flags |= SI_NAMED;
789 if (cr != NULL)
790 dev->si_cred = crhold(cr);
791 dev->si_uid = uid;
792 dev->si_gid = gid;
793 dev->si_mode = mode;
794
795 devfs_create(dev);

--- 13 unchanged lines hidden (view full) ---

809 struct cdev *dev;
810 va_list ap;
811 int res;
812
813 va_start(ap, fmt);
814 res = make_dev_credv(0, &dev, devsw, unit, NULL, uid, gid, mode, fmt,
815 ap);
816 va_end(ap);
759 KASSERT(res == 0 && dev != NULL, ("make_dev: failed make_dev_credv"));
817 KASSERT(res == 0 && dev != NULL,
818 ("make_dev: failed make_dev_credv (error=%d)", res));
760 return (dev);
761}
762
763struct cdev *
764make_dev_cred(struct cdevsw *devsw, int unit, struct ucred *cr, uid_t uid,
765 gid_t gid, int mode, const char *fmt, ...)
766{
767 struct cdev *dev;
768 va_list ap;
769 int res;
770
771 va_start(ap, fmt);
772 res = make_dev_credv(0, &dev, devsw, unit, cr, uid, gid, mode, fmt, ap);
773 va_end(ap);
774
775 KASSERT(res == 0 && dev != NULL,
819 return (dev);
820}
821
822struct cdev *
823make_dev_cred(struct cdevsw *devsw, int unit, struct ucred *cr, uid_t uid,
824 gid_t gid, int mode, const char *fmt, ...)
825{
826 struct cdev *dev;
827 va_list ap;
828 int res;
829
830 va_start(ap, fmt);
831 res = make_dev_credv(0, &dev, devsw, unit, cr, uid, gid, mode, fmt, ap);
832 va_end(ap);
833
834 KASSERT(res == 0 && dev != NULL,
776 ("make_dev_cred: failed make_dev_credv"));
835 ("make_dev_cred: failed make_dev_credv (error=%d)", res));
777 return (dev);
778}
779
780struct cdev *
781make_dev_credf(int flags, struct cdevsw *devsw, int unit, struct ucred *cr,
782 uid_t uid, gid_t gid, int mode, const char *fmt, ...)
783{
784 struct cdev *dev;
785 va_list ap;
786 int res;
787
788 va_start(ap, fmt);
789 res = make_dev_credv(flags, &dev, devsw, unit, cr, uid, gid, mode,
790 fmt, ap);
791 va_end(ap);
792
836 return (dev);
837}
838
839struct cdev *
840make_dev_credf(int flags, struct cdevsw *devsw, int unit, struct ucred *cr,
841 uid_t uid, gid_t gid, int mode, const char *fmt, ...)
842{
843 struct cdev *dev;
844 va_list ap;
845 int res;
846
847 va_start(ap, fmt);
848 res = make_dev_credv(flags, &dev, devsw, unit, cr, uid, gid, mode,
849 fmt, ap);
850 va_end(ap);
851
793 KASSERT((flags & MAKEDEV_NOWAIT) != 0 || res == 0,
794 ("make_dev_credf: failed make_dev_credv"));
852 KASSERT(((flags & MAKEDEV_NOWAIT) != 0 && res == ENOMEM) ||
853 ((flags & MAKEDEV_CHECKNAME) != 0 && res != ENOMEM) || res == 0,
854 ("make_dev_credf: failed make_dev_credv (error=%d)", res));
795 return (res == 0 ? dev : NULL);
796}
797
798int
799make_dev_p(int flags, struct cdev **cdev, struct cdevsw *devsw,
800 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, ...)
801{
802 va_list ap;
803 int res;
804
805 va_start(ap, fmt);
806 res = make_dev_credv(flags, cdev, devsw, 0, cr, uid, gid, mode,
807 fmt, ap);
808 va_end(ap);
809
855 return (res == 0 ? dev : NULL);
856}
857
858int
859make_dev_p(int flags, struct cdev **cdev, struct cdevsw *devsw,
860 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, ...)
861{
862 va_list ap;
863 int res;
864
865 va_start(ap, fmt);
866 res = make_dev_credv(flags, cdev, devsw, 0, cr, uid, gid, mode,
867 fmt, ap);
868 va_end(ap);
869
810 KASSERT((flags & MAKEDEV_NOWAIT) != 0 || res == 0,
811 ("make_dev_p: failed make_dev_credv"));
870 KASSERT(((flags & MAKEDEV_NOWAIT) != 0 && res == ENOMEM) ||
871 ((flags & MAKEDEV_CHECKNAME) != 0 && res != ENOMEM) || res == 0,
872 ("make_dev_p: failed make_dev_credv (error=%d)", res));
812 return (res);
813}
814
815static void
816dev_dependsl(struct cdev *pdev, struct cdev *cdev)
817{
818
819 cdev->si_parent = pdev;

--- 11 unchanged lines hidden (view full) ---

831 dev_unlock();
832}
833
834struct cdev *
835make_dev_alias(struct cdev *pdev, const char *fmt, ...)
836{
837 struct cdev *dev;
838 va_list ap;
873 return (res);
874}
875
876static void
877dev_dependsl(struct cdev *pdev, struct cdev *cdev)
878{
879
880 cdev->si_parent = pdev;

--- 11 unchanged lines hidden (view full) ---

892 dev_unlock();
893}
894
895struct cdev *
896make_dev_alias(struct cdev *pdev, const char *fmt, ...)
897{
898 struct cdev *dev;
899 va_list ap;
839 int i;
900 int error;
840
841 KASSERT(pdev != NULL, ("NULL pdev"));
842 dev = devfs_alloc(MAKEDEV_WAITOK);
843 dev_lock();
844 dev->si_flags |= SI_ALIAS;
901
902 KASSERT(pdev != NULL, ("NULL pdev"));
903 dev = devfs_alloc(MAKEDEV_WAITOK);
904 dev_lock();
905 dev->si_flags |= SI_ALIAS;
845 dev->si_flags |= SI_NAMED;
846 va_start(ap, fmt);
906 va_start(ap, fmt);
847 i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
848 if (i > (sizeof dev->__si_namebuf - 1)) {
849 printf("WARNING: Device name truncated! (%s)\n",
850 dev->__si_namebuf);
851 }
907 error = prep_devname(dev, fmt, ap);
852 va_end(ap);
908 va_end(ap);
853
909 if (error != 0) {
910 panic("make_dev_alias: bad si_name (error=%d, si_name=%s)",
911 error, dev->si_name);
912 }
913 dev->si_flags |= SI_NAMED;
854 devfs_create(dev);
855 dev_dependsl(pdev, dev);
856 clean_unrhdrl(devfs_inos);
857 dev_unlock();
858
859 notify_create(dev, MAKEDEV_WAITOK);
860
861 return (dev);

--- 438 unchanged lines hidden ---
914 devfs_create(dev);
915 dev_dependsl(pdev, dev);
916 clean_unrhdrl(devfs_inos);
917 dev_unlock();
918
919 notify_create(dev, MAKEDEV_WAITOK);
920
921 return (dev);

--- 438 unchanged lines hidden ---