Print this page
Spencer's first if/else try


 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 /*