uipc_mqueue.c (b042e9760c883141a393d0346334e2b24e439776) uipc_mqueue.c (fbc48e974efbca2b6b3eb52b581b97df5707e0d6)
1/*-
2 * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
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

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

368mqnode_addref(struct mqfs_node *node)
369{
370 atomic_fetchadd_int(&node->mn_refcount, 1);
371}
372
373static __inline void
374mqnode_release(struct mqfs_node *node)
375{
1/*-
2 * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
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

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

368mqnode_addref(struct mqfs_node *node)
369{
370 atomic_fetchadd_int(&node->mn_refcount, 1);
371}
372
373static __inline void
374mqnode_release(struct mqfs_node *node)
375{
376 struct mqfs_info *mqfs;
376 int old, exp;
377
377 int old, exp;
378
379 mqfs = node->mn_info;
378 old = atomic_fetchadd_int(&node->mn_refcount, -1);
379 if (node->mn_type == mqfstype_dir ||
380 node->mn_type == mqfstype_root)
381 exp = 3; /* include . and .. */
382 else
383 exp = 1;
380 old = atomic_fetchadd_int(&node->mn_refcount, -1);
381 if (node->mn_type == mqfstype_dir ||
382 node->mn_type == mqfstype_root)
383 exp = 3; /* include . and .. */
384 else
385 exp = 1;
384 if (old == exp)
386 if (old == exp) {
387 int locked = sx_xlocked(&mqfs->mi_lock);
388 if (!locked)
389 sx_xlock(&mqfs->mi_lock);
385 mqfs_destroy(node);
390 mqfs_destroy(node);
391 if (!locked)
392 sx_xunlock(&mqfs->mi_lock);
393 }
386}
387
388/*
389 * Add a node to a directory
390 */
391static int
392mqfs_add_node(struct mqfs_node *parent, struct mqfs_node *node)
393{

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

412 int nodetype)
413{
414 struct mqfs_node *node;
415
416 node = mqnode_alloc();
417 strncpy(node->mn_name, name, namelen);
418 node->mn_type = nodetype;
419 node->mn_refcount = 1;
394}
395
396/*
397 * Add a node to a directory
398 */
399static int
400mqfs_add_node(struct mqfs_node *parent, struct mqfs_node *node)
401{

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

420 int nodetype)
421{
422 struct mqfs_node *node;
423
424 node = mqnode_alloc();
425 strncpy(node->mn_name, name, namelen);
426 node->mn_type = nodetype;
427 node->mn_refcount = 1;
420 getnanotime(&node->mn_birth);
428 vfs_timestamp(&node->mn_birth);
421 node->mn_ctime = node->mn_atime = node->mn_mtime
422 = node->mn_birth;
423 node->mn_uid = cred->cr_uid;
424 node->mn_gid = cred->cr_gid;
425 node->mn_mode = mode;
426 return (node);
427}
428

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

596 */
597static int
598mqfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
599{
600 struct mqfs_info *mqfs;
601 int ret;
602
603 mqfs = VFSTOMQFS(mp);
429 node->mn_ctime = node->mn_atime = node->mn_mtime
430 = node->mn_birth;
431 node->mn_uid = cred->cr_uid;
432 node->mn_gid = cred->cr_gid;
433 node->mn_mode = mode;
434 return (node);
435}
436

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

604 */
605static int
606mqfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
607{
608 struct mqfs_info *mqfs;
609 int ret;
610
611 mqfs = VFSTOMQFS(mp);
604 sx_xlock(&mqfs->mi_lock);
605 ret = mqfs_allocv(mp, vpp, mqfs->mi_root);
612 ret = mqfs_allocv(mp, vpp, mqfs->mi_root);
606 sx_xunlock(&mqfs->mi_lock);
607 return (ret);
608}
609
610/*
611 * Return filesystem stats
612 */
613static int
614mqfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)

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

691
692/*
693 * Allocate a vnode
694 */
695static int
696mqfs_allocv(struct mount *mp, struct vnode **vpp, struct mqfs_node *pn)
697{
698 struct mqfs_vdata *vd;
613 return (ret);
614}
615
616/*
617 * Return filesystem stats
618 */
619static int
620mqfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)

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

697
698/*
699 * Allocate a vnode
700 */
701static int
702mqfs_allocv(struct mount *mp, struct vnode **vpp, struct mqfs_node *pn)
703{
704 struct mqfs_vdata *vd;
705 struct mqfs_info *mqfs;
706 struct vnode *newvpp;
699 int error;
700
707 int error;
708
709 mqfs = pn->mn_info;
710 *vpp = NULL;
711 sx_xlock(&mqfs->mi_lock);
701 LIST_FOREACH(vd, &pn->mn_vnodes, mv_link) {
712 LIST_FOREACH(vd, &pn->mn_vnodes, mv_link) {
702 if (vd->mv_vnode->v_mount == mp)
713 if (vd->mv_vnode->v_mount == mp) {
714 vhold(vd->mv_vnode);
703 break;
715 break;
716 }
704 }
705
706 if (vd != NULL) {
717 }
718
719 if (vd != NULL) {
720found:
707 *vpp = vd->mv_vnode;
721 *vpp = vd->mv_vnode;
708 vget(*vpp, LK_RETRY | LK_EXCLUSIVE, curthread);
709 return (0);
722 sx_xunlock(&mqfs->mi_lock);
723 error = vget(*vpp, LK_RETRY | LK_EXCLUSIVE, curthread);
724 vdrop(*vpp);
725 return (error);
710 }
726 }
727 sx_xunlock(&mqfs->mi_lock);
711
728
712 error = getnewvnode("mqueue", mp, &mqfs_vnodeops, vpp);
729 error = getnewvnode("mqueue", mp, &mqfs_vnodeops, &newvpp);
713 if (error)
714 return (error);
730 if (error)
731 return (error);
715 vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
716 error = insmntque(*vpp, mp);
717 if (error != 0) {
718 *vpp = NULLVP;
732 vn_lock(newvpp, LK_EXCLUSIVE | LK_RETRY);
733 error = insmntque(newvpp, mp);
734 if (error != 0)
719 return (error);
735 return (error);
736
737 sx_xlock(&mqfs->mi_lock);
738 /*
739 * Check if it has already been allocated
740 * while we were blocked.
741 */
742 LIST_FOREACH(vd, &pn->mn_vnodes, mv_link) {
743 if (vd->mv_vnode->v_mount == mp) {
744 vhold(vd->mv_vnode);
745 sx_xunlock(&mqfs->mi_lock);
746
747 vgone(newvpp);
748 vput(newvpp);
749 goto found;
750 }
720 }
751 }
752
753 *vpp = newvpp;
754
721 vd = uma_zalloc(mvdata_zone, M_WAITOK);
722 (*vpp)->v_data = vd;
723 vd->mv_vnode = *vpp;
724 vd->mv_node = pn;
725 TASK_INIT(&vd->mv_task, 0, do_recycle, *vpp);
726 LIST_INSERT_HEAD(&pn->mn_vnodes, vd, mv_link);
727 mqnode_addref(pn);
728 switch (pn->mn_type) {

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

740 case mqfstype_symlink:
741 (*vpp)->v_type = VLNK;
742 break;
743 case mqfstype_none:
744 KASSERT(0, ("mqfs_allocf called for null node\n"));
745 default:
746 panic("%s has unexpected type: %d", pn->mn_name, pn->mn_type);
747 }
755 vd = uma_zalloc(mvdata_zone, M_WAITOK);
756 (*vpp)->v_data = vd;
757 vd->mv_vnode = *vpp;
758 vd->mv_node = pn;
759 TASK_INIT(&vd->mv_task, 0, do_recycle, *vpp);
760 LIST_INSERT_HEAD(&pn->mn_vnodes, vd, mv_link);
761 mqnode_addref(pn);
762 switch (pn->mn_type) {

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

774 case mqfstype_symlink:
775 (*vpp)->v_type = VLNK;
776 break;
777 case mqfstype_none:
778 KASSERT(0, ("mqfs_allocf called for null node\n"));
779 default:
780 panic("%s has unexpected type: %d", pn->mn_name, pn->mn_type);
781 }
782 sx_xunlock(&mqfs->mi_lock);
748 return (0);
749}
750
751/*
752 * Search a directory entry
753 */
754static struct mqfs_node *
755mqfs_search(struct mqfs_node *pd, const char *name, int len)
756{
757 struct mqfs_node *pn;
758
783 return (0);
784}
785
786/*
787 * Search a directory entry
788 */
789static struct mqfs_node *
790mqfs_search(struct mqfs_node *pd, const char *name, int len)
791{
792 struct mqfs_node *pn;
793
794 sx_assert(&pd->mn_info->mi_lock, SX_LOCKED);
759 LIST_FOREACH(pn, &pd->mn_children, mn_sibling) {
760 if (strncmp(pn->mn_name, name, len) == 0)
761 return (pn);
762 }
763 return (NULL);
764}
765
766/*
767 * Look up a file or directory.
768 */
769static int
770mqfs_lookupx(struct vop_cachedlookup_args *ap)
771{
772 struct componentname *cnp;
773 struct vnode *dvp, **vpp;
774 struct mqfs_node *pd;
775 struct mqfs_node *pn;
795 LIST_FOREACH(pn, &pd->mn_children, mn_sibling) {
796 if (strncmp(pn->mn_name, name, len) == 0)
797 return (pn);
798 }
799 return (NULL);
800}
801
802/*
803 * Look up a file or directory.
804 */
805static int
806mqfs_lookupx(struct vop_cachedlookup_args *ap)
807{
808 struct componentname *cnp;
809 struct vnode *dvp, **vpp;
810 struct mqfs_node *pd;
811 struct mqfs_node *pn;
812 struct mqfs_info *mqfs;
776 int nameiop, flags, error, namelen;
777 char *pname;
778 struct thread *td;
779
780 cnp = ap->a_cnp;
781 vpp = ap->a_vpp;
782 dvp = ap->a_dvp;
783 pname = cnp->cn_nameptr;
784 namelen = cnp->cn_namelen;
785 td = cnp->cn_thread;
786 flags = cnp->cn_flags;
787 nameiop = cnp->cn_nameiop;
788 pd = VTON(dvp);
789 pn = NULL;
813 int nameiop, flags, error, namelen;
814 char *pname;
815 struct thread *td;
816
817 cnp = ap->a_cnp;
818 vpp = ap->a_vpp;
819 dvp = ap->a_dvp;
820 pname = cnp->cn_nameptr;
821 namelen = cnp->cn_namelen;
822 td = cnp->cn_thread;
823 flags = cnp->cn_flags;
824 nameiop = cnp->cn_nameiop;
825 pd = VTON(dvp);
826 pn = NULL;
827 mqfs = pd->mn_info;
790 *vpp = NULLVP;
791
792 if (dvp->v_type != VDIR)
793 return (ENOTDIR);
794
795 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_thread);
796 if (error)
797 return (error);

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

820 KASSERT(pd->mn_parent, ("non-root directory has no parent"));
821 pn = pd->mn_parent;
822 error = mqfs_allocv(dvp->v_mount, vpp, pn);
823 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
824 return (error);
825 }
826
827 /* named node */
828 *vpp = NULLVP;
829
830 if (dvp->v_type != VDIR)
831 return (ENOTDIR);
832
833 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_thread);
834 if (error)
835 return (error);

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

858 KASSERT(pd->mn_parent, ("non-root directory has no parent"));
859 pn = pd->mn_parent;
860 error = mqfs_allocv(dvp->v_mount, vpp, pn);
861 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
862 return (error);
863 }
864
865 /* named node */
866 sx_xlock(&mqfs->mi_lock);
828 pn = mqfs_search(pd, pname, namelen);
867 pn = mqfs_search(pd, pname, namelen);
868 if (pn != NULL)
869 mqnode_addref(pn);
870 sx_xunlock(&mqfs->mi_lock);
829
830 /* found */
831 if (pn != NULL) {
832 /* DELETE */
833 if (nameiop == DELETE && (flags & ISLASTCN)) {
834 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
871
872 /* found */
873 if (pn != NULL) {
874 /* DELETE */
875 if (nameiop == DELETE && (flags & ISLASTCN)) {
876 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
835 if (error)
877 if (error) {
878 mqnode_release(pn);
836 return (error);
879 return (error);
880 }
837 if (*vpp == dvp) {
838 VREF(dvp);
839 *vpp = dvp;
881 if (*vpp == dvp) {
882 VREF(dvp);
883 *vpp = dvp;
884 mqnode_release(pn);
840 return (0);
841 }
842 }
843
844 /* allocate vnode */
845 error = mqfs_allocv(dvp->v_mount, vpp, pn);
885 return (0);
886 }
887 }
888
889 /* allocate vnode */
890 error = mqfs_allocv(dvp->v_mount, vpp, pn);
891 mqnode_release(pn);
846 if (error == 0 && cnp->cn_flags & MAKEENTRY)
847 cache_enter(dvp, *vpp, cnp);
848 return (error);
849 }
850
851 /* not found */
852
853 /* will create a new entry in the directory ? */

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

872#endif
873
874/*
875 * vnode lookup operation
876 */
877static int
878mqfs_lookup(struct vop_cachedlookup_args *ap)
879{
892 if (error == 0 && cnp->cn_flags & MAKEENTRY)
893 cache_enter(dvp, *vpp, cnp);
894 return (error);
895 }
896
897 /* not found */
898
899 /* will create a new entry in the directory ? */

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

918#endif
919
920/*
921 * vnode lookup operation
922 */
923static int
924mqfs_lookup(struct vop_cachedlookup_args *ap)
925{
880 struct mqfs_info *mqfs = VFSTOMQFS(ap->a_dvp->v_mount);
881 int rc;
882
926 int rc;
927
883 sx_xlock(&mqfs->mi_lock);
884 rc = mqfs_lookupx(ap);
928 rc = mqfs_lookupx(ap);
885 sx_xunlock(&mqfs->mi_lock);
886 return (rc);
887}
888
889#if 0
890struct vop_create_args {
891 struct vnode *a_dvp;
892 struct vnode **a_vpp;
893 struct componentname *a_cnp;

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

910
911 pd = VTON(ap->a_dvp);
912 if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
913 return (ENOTDIR);
914 mq = mqueue_alloc(NULL);
915 if (mq == NULL)
916 return (EAGAIN);
917 sx_xlock(&mqfs->mi_lock);
929 return (rc);
930}
931
932#if 0
933struct vop_create_args {
934 struct vnode *a_dvp;
935 struct vnode **a_vpp;
936 struct componentname *a_cnp;

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

953
954 pd = VTON(ap->a_dvp);
955 if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
956 return (ENOTDIR);
957 mq = mqueue_alloc(NULL);
958 if (mq == NULL)
959 return (EAGAIN);
960 sx_xlock(&mqfs->mi_lock);
918#if 0
919 /* named node */
920 pn = mqfs_search(pd, cnp->cn_nameptr, cnp->cn_namelen);
921 if (pn != NULL) {
922 mqueue_free(mq);
923 sx_xunlock(&mqfs->mi_lock);
924 return (EEXIST);
925 }
926#else
927 if ((cnp->cn_flags & HASBUF) == 0)
928 panic("%s: no name", __func__);
961 if ((cnp->cn_flags & HASBUF) == 0)
962 panic("%s: no name", __func__);
929#endif
930 pn = mqfs_create_file(pd, cnp->cn_nameptr, cnp->cn_namelen,
931 cnp->cn_cred, ap->a_vap->va_mode);
963 pn = mqfs_create_file(pd, cnp->cn_nameptr, cnp->cn_namelen,
964 cnp->cn_cred, ap->a_vap->va_mode);
932 if (pn == NULL)
965 if (pn == NULL) {
966 sx_xunlock(&mqfs->mi_lock);
933 error = ENOSPC;
967 error = ENOSPC;
934 else {
968 } else {
969 mqnode_addref(pn);
970 sx_xunlock(&mqfs->mi_lock);
935 error = mqfs_allocv(ap->a_dvp->v_mount, ap->a_vpp, pn);
971 error = mqfs_allocv(ap->a_dvp->v_mount, ap->a_vpp, pn);
972 mqnode_release(pn);
936 if (error)
937 mqfs_destroy(pn);
938 else
939 pn->mn_data = mq;
940 }
973 if (error)
974 mqfs_destroy(pn);
975 else
976 pn->mn_data = mq;
977 }
941 sx_xunlock(&mqfs->mi_lock);
942 if (error)
943 mqueue_free(mq);
944 return (error);
945}
946
947/*
948 * Remove an entry
949 */

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

1407 struct componentname *cnp = ap->a_cnp;
1408 struct mqfs_node *pd = VTON(ap->a_dvp);
1409 struct mqfs_node *pn;
1410 int error;
1411
1412 if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
1413 return (ENOTDIR);
1414 sx_xlock(&mqfs->mi_lock);
978 if (error)
979 mqueue_free(mq);
980 return (error);
981}
982
983/*
984 * Remove an entry
985 */

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

1443 struct componentname *cnp = ap->a_cnp;
1444 struct mqfs_node *pd = VTON(ap->a_dvp);
1445 struct mqfs_node *pn;
1446 int error;
1447
1448 if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
1449 return (ENOTDIR);
1450 sx_xlock(&mqfs->mi_lock);
1415#if 0
1416 /* named node */
1417 pn = mqfs_search(pd, cnp->cn_nameptr, cnp->cn_namelen);
1418 if (pn != NULL) {
1419 sx_xunlock(&mqfs->mi_lock);
1420 return (EEXIST);
1421 }
1422#else
1423 if ((cnp->cn_flags & HASBUF) == 0)
1424 panic("%s: no name", __func__);
1451 if ((cnp->cn_flags & HASBUF) == 0)
1452 panic("%s: no name", __func__);
1425#endif
1426 pn = mqfs_create_dir(pd, cnp->cn_nameptr, cnp->cn_namelen,
1427 ap->a_vap->cn_cred, ap->a_vap->va_mode);
1453 pn = mqfs_create_dir(pd, cnp->cn_nameptr, cnp->cn_namelen,
1454 ap->a_vap->cn_cred, ap->a_vap->va_mode);
1428 if (pn == NULL)
1455 if (pn != NULL)
1456 mqnode_addref(pn);
1457 sx_xunlock(&mqfs->mi_lock);
1458 if (pn == NULL) {
1429 error = ENOSPC;
1459 error = ENOSPC;
1430 else
1460 } else {
1431 error = mqfs_allocv(ap->a_dvp->v_mount, ap->a_vpp, pn);
1461 error = mqfs_allocv(ap->a_dvp->v_mount, ap->a_vpp, pn);
1432 sx_xunlock(&mqfs->mi_lock);
1462 mqnode_release(pn);
1463 }
1433 return (error);
1434}
1435
1436#if 0
1437struct vop_rmdir_args {
1438 struct vnode *a_dvp;
1439 struct vnode *a_vp;
1440 struct componentname *a_cnp;

--- 1045 unchanged lines hidden ---
1464 return (error);
1465}
1466
1467#if 0
1468struct vop_rmdir_args {
1469 struct vnode *a_dvp;
1470 struct vnode *a_vp;
1471 struct componentname *a_cnp;

--- 1045 unchanged lines hidden ---