826 done:
827 if (in_crit)
828 nbl_end_crit(vp);
829 return (error);
830 }
831
832 /*
833 * Release a vnode. Call VOP_INACTIVE on last reference or
834 * decrement reference count.
835 *
836 * To avoid race conditions, the v_count is left at 1 for
837 * the call to VOP_INACTIVE. This prevents another thread
838 * from reclaiming and releasing the vnode *before* the
839 * VOP_INACTIVE routine has a chance to destroy the vnode.
840 * We can't have more than 1 thread calling VOP_INACTIVE
841 * on a vnode.
842 */
843 void
844 vn_rele(vnode_t *vp)
845 {
846 VERIFY(vp->v_count > 0);
847 mutex_enter(&vp->v_lock);
848 if (vp->v_count == 1) {
849 mutex_exit(&vp->v_lock);
850 VOP_INACTIVE(vp, CRED(), NULL);
851 return;
852 }
853 VN_RELE_LOCKED(vp);
854 mutex_exit(&vp->v_lock);
855 }
856
857 void
858 vn_phantom_rele(vnode_t *vp)
859 {
860 VERIFY(vp->v_count > 0);
861
862 mutex_enter(&vp->v_lock);
863 VERIFY3U(vp->v_count, >=, vp->v_phantom_count);
864 vp->v_phantom_count--;
865 DTRACE_PROBE1(vn__phantom_rele, vnode_t *, vp);
866 if (vp->v_count == 1) {
867 ASSERT0(vp->v_phantom_count);
868 mutex_exit(&vp->v_lock);
869 VOP_INACTIVE(vp, CRED(), NULL);
870 return;
871 }
872 VN_RELE_LOCKED(vp);
873 mutex_exit(&vp->v_lock);
874 }
875
876 /*
877 * Return the number of non-phantom holds. Things such as portfs will use
878 * phantom holds to prevent it from blocking filesystems from mounting over
879 * watched directories.
880 */
881 uint_t
882 vn_count(vnode_t *vp)
883 {
884 ASSERT(MUTEX_HELD(&vp->v_lock));
885 return (vp->v_count - vp->v_phantom_count);
886 }
887
888 /*
889 * Release a vnode referenced by the DNLC. Multiple DNLC references are treated
890 * as a single reference, so v_count is not decremented until the last DNLC hold
891 * is released. This makes it possible to distinguish vnodes that are referenced
892 * only by the DNLC.
893 */
894 void
895 vn_rele_dnlc(vnode_t *vp)
896 {
897 VERIFY((vp->v_count > 0) && (vp->v_count_dnlc > 0));
898 mutex_enter(&vp->v_lock);
899 if (--vp->v_count_dnlc == 0) {
900 if (vp->v_count == 1) {
901 mutex_exit(&vp->v_lock);
902 VOP_INACTIVE(vp, CRED(), NULL);
903 return;
904 }
905 VN_RELE_LOCKED(vp);
906 }
907 mutex_exit(&vp->v_lock);
908 }
909
910 /*
911 * Like vn_rele() except that it clears v_stream under v_lock.
912 * This is used by sockfs when it dismantles the association between
913 * the sockfs node and the vnode in the underlying file system.
914 * v_lock has to be held to prevent a thread coming through the lookupname
915 * path from accessing a stream head that is going away.
916 */
917 void
918 vn_rele_stream(vnode_t *vp)
919 {
920 VERIFY(vp->v_count > 0);
921 mutex_enter(&vp->v_lock);
922 vp->v_stream = NULL;
923 if (vp->v_count == 1) {
924 mutex_exit(&vp->v_lock);
925 VOP_INACTIVE(vp, CRED(), NULL);
926 return;
927 }
928 VN_RELE_LOCKED(vp);
929 mutex_exit(&vp->v_lock);
930 }
931
932 static void
933 vn_rele_inactive(vnode_t *vp)
934 {
935 VOP_INACTIVE(vp, CRED(), NULL);
936 }
937
938 /*
939 * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it
940 * asynchronously using a taskq. This can avoid deadlocks caused by re-entering
941 * the file system as a result of releasing the vnode. Note, file systems
942 * already have to handle the race where the vnode is incremented before the
943 * inactive routine is called and does its locking.
944 *
945 * Warning: Excessive use of this routine can lead to performance problems.
946 * This is because taskqs throttle back allocation if too many are created.
947 */
948 void
949 vn_rele_async(vnode_t *vp, taskq_t *taskq)
950 {
951 VERIFY(vp->v_count > 0);
952 mutex_enter(&vp->v_lock);
953 if (vp->v_count == 1) {
954 mutex_exit(&vp->v_lock);
955 VERIFY(taskq_dispatch(taskq, (task_func_t *)vn_rele_inactive,
956 vp, TQ_SLEEP) != TASKQID_INVALID);
957 return;
958 }
959 VN_RELE_LOCKED(vp);
960 mutex_exit(&vp->v_lock);
961 }
962
963 int
964 vn_open(
965 char *pnamep,
966 enum uio_seg seg,
967 int filemode,
968 int createmode,
969 struct vnode **vpp,
970 enum create crwhy,
971 mode_t umask)
972 {
973 return (vn_openat(pnamep, seg, filemode, createmode, vpp, crwhy,
974 umask, NULL, -1));
975 }
976
977
978 /*
|
826 done:
827 if (in_crit)
828 nbl_end_crit(vp);
829 return (error);
830 }
831
832 /*
833 * Release a vnode. Call VOP_INACTIVE on last reference or
834 * decrement reference count.
835 *
836 * To avoid race conditions, the v_count is left at 1 for
837 * the call to VOP_INACTIVE. This prevents another thread
838 * from reclaiming and releasing the vnode *before* the
839 * VOP_INACTIVE routine has a chance to destroy the vnode.
840 * We can't have more than 1 thread calling VOP_INACTIVE
841 * on a vnode.
842 */
843 void
844 vn_rele(vnode_t *vp)
845 {
846 mutex_enter(&vp->v_lock);
847 if (vp->v_count == 1) {
848 mutex_exit(&vp->v_lock);
849 VOP_INACTIVE(vp, CRED(), NULL);
850 return;
851 }
852 else{
853 VERIFY(vp->v_count > 0);
854 }
855 VN_RELE_LOCKED(vp);
856 mutex_exit(&vp->v_lock);
857 }
858
859 void
860 vn_phantom_rele(vnode_t *vp)
861 {
862 mutex_enter(&vp->v_lock);
863
864 vp->v_phantom_count--;
865 DTRACE_PROBE1(vn__phantom_rele, vnode_t *, vp);
866 if (vp->v_count == 1) {
867 ASSERT0(vp->v_phantom_count);
868 mutex_exit(&vp->v_lock);
869 VOP_INACTIVE(vp, CRED(), NULL);
870 return;
871 }else{
872 VERIFY(vp->v_count > 0);
873 VERIFY3U(vp->v_count, >=, vp->v_phantom_count);
874 }
875 VN_RELE_LOCKED(vp);
876 mutex_exit(&vp->v_lock);
877 }
878
879 /*
880 * Return the number of non-phantom holds. Things such as portfs will use
881 * phantom holds to prevent it from blocking filesystems from mounting over
882 * watched directories.
883 */
884 uint_t
885 vn_count(vnode_t *vp)
886 {
887 ASSERT(MUTEX_HELD(&vp->v_lock));
888 return (vp->v_count - vp->v_phantom_count);
889 }
890
891 /*
892 * Release a vnode referenced by the DNLC. Multiple DNLC references are treated
893 * as a single reference, so v_count is not decremented until the last DNLC hold
894 * is released. This makes it possible to distinguish vnodes that are referenced
895 * only by the DNLC.
896 */
897 void
898 vn_rele_dnlc(vnode_t *vp)
899 {
900 mutex_enter(&vp->v_lock);
901
902 if (--vp->v_count_dnlc == 0) {
903 if (vp->v_count == 1) {
904 mutex_exit(&vp->v_lock);
905 VOP_INACTIVE(vp, CRED(), NULL);
906 return;
907 }
908 VN_RELE_LOCKED(vp);
909 }else{
910 VERIFY((vp->v_count > 0) && (vp->v_count_dnlc > 0));
911 }
912 mutex_exit(&vp->v_lock);
913 }
914
915 /*
916 * Like vn_rele() except that it clears v_stream under v_lock.
917 * This is used by sockfs when it dismantles the association between
918 * the sockfs node and the vnode in the underlying file system.
919 * v_lock has to be held to prevent a thread coming through the lookupname
920 * path from accessing a stream head that is going away.
921 */
922 void
923 vn_rele_stream(vnode_t *vp)
924 {
925 mutex_enter(&vp->v_lock);
926
927 vp->v_stream = NULL;
928 if (vp->v_count == 1) {
929 mutex_exit(&vp->v_lock);
930 VOP_INACTIVE(vp, CRED(), NULL);
931 return;
932 }
933 else{
934 VERIFY(vp->v_count > 0);
935 }
936 VN_RELE_LOCKED(vp);
937 mutex_exit(&vp->v_lock);
938 }
939
940 static void
941 vn_rele_inactive(vnode_t *vp)
942 {
943 VOP_INACTIVE(vp, CRED(), NULL);
944 }
945
946 /*
947 * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it
948 * asynchronously using a taskq. This can avoid deadlocks caused by re-entering
949 * the file system as a result of releasing the vnode. Note, file systems
950 * already have to handle the race where the vnode is incremented before the
951 * inactive routine is called and does its locking.
952 *
953 * Warning: Excessive use of this routine can lead to performance problems.
954 * This is because taskqs throttle back allocation if too many are created.
955 */
956 void
957 vn_rele_async(vnode_t *vp, taskq_t *taskq)
958 {
959 mutex_enter(&vp->v_lock);
960 if (vp->v_count == 1) {
961 mutex_exit(&vp->v_lock);
962 VERIFY(taskq_dispatch(taskq, (task_func_t *)vn_rele_inactive,
963 vp, TQ_SLEEP) != TASKQID_INVALID);
964 return;
965 }
966 else{
967 VERIFY(vp->v_count > 0);
968 }
969 VN_RELE_LOCKED(vp);
970 mutex_exit(&vp->v_lock);
971 }
972
973 int
974 vn_open(
975 char *pnamep,
976 enum uio_seg seg,
977 int filemode,
978 int createmode,
979 struct vnode **vpp,
980 enum create crwhy,
981 mode_t umask)
982 {
983 return (vn_openat(pnamep, seg, filemode, createmode, vpp, crwhy,
984 umask, NULL, -1));
985 }
986
987
988 /*
|