820
821 /*
822 * Identical to releasef() but can be called from another process.
823 */
824 void
825 areleasef(int fd, uf_info_t *fip)
826 {
827 uf_entry_t *ufp;
828
829 UF_ENTER(ufp, fip, fd);
830 ASSERT(ufp->uf_refcnt > 0);
831 if (--ufp->uf_refcnt == 0)
832 cv_broadcast(&ufp->uf_closing_cv);
833 UF_EXIT(ufp);
834 }
835
836 /*
837 * Duplicate all file descriptors across a fork.
838 */
839 void
840 flist_fork(uf_info_t *pfip, uf_info_t *cfip)
841 {
842 int fd, nfiles;
843 uf_entry_t *pufp, *cufp;
844
845 mutex_init(&cfip->fi_lock, NULL, MUTEX_DEFAULT, NULL);
846 cfip->fi_rlist = NULL;
847
848 /*
849 * We don't need to hold fi_lock because all other lwp's in the
850 * parent have been held.
851 */
852 cfip->fi_nfiles = nfiles = flist_minsize(pfip);
853
854 cfip->fi_list = kmem_zalloc(nfiles * sizeof (uf_entry_t), KM_SLEEP);
855
856 for (fd = 0, pufp = pfip->fi_list, cufp = cfip->fi_list; fd < nfiles;
857 fd++, pufp++, cufp++) {
858 cufp->uf_file = pufp->uf_file;
859 cufp->uf_alloc = pufp->uf_alloc;
860 cufp->uf_flag = pufp->uf_flag;
861 cufp->uf_busy = pufp->uf_busy;
862 if (pufp->uf_file == NULL) {
863 ASSERT(pufp->uf_flag == 0);
864 if (pufp->uf_busy) {
865 /*
866 * Grab locks to appease ASSERTs in fd_reserve
867 */
868 mutex_enter(&cfip->fi_lock);
869 mutex_enter(&cufp->uf_lock);
870 fd_reserve(cfip, fd, -1);
871 mutex_exit(&cufp->uf_lock);
872 mutex_exit(&cfip->fi_lock);
873 }
874 }
875 }
876 }
877
878 /*
879 * Close all open file descriptors for the current process.
880 * This is only called from exit(), which is single-threaded,
881 * so we don't need any locking.
927 int count;
928 int flag;
929 offset_t offset;
930
931 /*
932 * audit close of file (may be exit)
933 */
934 if (AU_AUDITING())
935 audit_closef(fp);
936 ASSERT(MUTEX_NOT_HELD(&P_FINFO(curproc)->fi_lock));
937
938 mutex_enter(&fp->f_tlock);
939
940 ASSERT(fp->f_count > 0);
941
942 count = fp->f_count--;
943 flag = fp->f_flag;
944 offset = fp->f_offset;
945
946 vp = fp->f_vnode;
947
948 error = VOP_CLOSE(vp, flag, count, offset, fp->f_cred, NULL);
949
950 if (count > 1) {
951 mutex_exit(&fp->f_tlock);
952 return (error);
953 }
954 ASSERT(fp->f_count == 0);
955 mutex_exit(&fp->f_tlock);
956
957 /*
958 * If DTrace has getf() subroutines active, it will set dtrace_closef
959 * to point to code that implements a barrier with respect to probe
960 * context. This must be called before the file_t is freed (and the
961 * vnode that it refers to is released) -- but it must be after the
962 * file_t has been removed from the uf_entry_t. That is, there must
963 * be no way for a racing getf() in probe context to yield the fp that
964 * we're operating upon.
965 */
966 if (dtrace_closef != NULL)
|
820
821 /*
822 * Identical to releasef() but can be called from another process.
823 */
824 void
825 areleasef(int fd, uf_info_t *fip)
826 {
827 uf_entry_t *ufp;
828
829 UF_ENTER(ufp, fip, fd);
830 ASSERT(ufp->uf_refcnt > 0);
831 if (--ufp->uf_refcnt == 0)
832 cv_broadcast(&ufp->uf_closing_cv);
833 UF_EXIT(ufp);
834 }
835
836 /*
837 * Duplicate all file descriptors across a fork.
838 */
839 void
840 flist_fork(proc_t *pp, proc_t *cp)
841 {
842 int fd, nfiles;
843 uf_entry_t *pufp, *cufp;
844
845 uf_info_t *pfip = P_FINFO(pp);
846 uf_info_t *cfip = P_FINFO(cp);
847
848 mutex_init(&cfip->fi_lock, NULL, MUTEX_DEFAULT, NULL);
849 cfip->fi_rlist = NULL;
850
851 /*
852 * We don't need to hold fi_lock because all other lwp's in the
853 * parent have been held.
854 */
855 cfip->fi_nfiles = nfiles = flist_minsize(pfip);
856
857 cfip->fi_list = kmem_zalloc(nfiles * sizeof (uf_entry_t), KM_SLEEP);
858
859 for (fd = 0, pufp = pfip->fi_list, cufp = cfip->fi_list; fd < nfiles;
860 fd++, pufp++, cufp++) {
861 cufp->uf_file = pufp->uf_file;
862 cufp->uf_alloc = pufp->uf_alloc;
863 cufp->uf_flag = pufp->uf_flag;
864 cufp->uf_busy = pufp->uf_busy;
865
866 if (cufp->uf_file != NULL && cufp->uf_file->f_vnode != NULL) {
867 VOP_IOCTL(cufp->uf_file->f_vnode, F_FORKED,
868 (intptr_t)cp,
869 FKIOCTL,
870 kcred, NULL, NULL);
871 }
872
873 if (pufp->uf_file == NULL) {
874 ASSERT(pufp->uf_flag == 0);
875 if (pufp->uf_busy) {
876 /*
877 * Grab locks to appease ASSERTs in fd_reserve
878 */
879 mutex_enter(&cfip->fi_lock);
880 mutex_enter(&cufp->uf_lock);
881 fd_reserve(cfip, fd, -1);
882 mutex_exit(&cufp->uf_lock);
883 mutex_exit(&cfip->fi_lock);
884 }
885 }
886 }
887 }
888
889 /*
890 * Close all open file descriptors for the current process.
891 * This is only called from exit(), which is single-threaded,
892 * so we don't need any locking.
938 int count;
939 int flag;
940 offset_t offset;
941
942 /*
943 * audit close of file (may be exit)
944 */
945 if (AU_AUDITING())
946 audit_closef(fp);
947 ASSERT(MUTEX_NOT_HELD(&P_FINFO(curproc)->fi_lock));
948
949 mutex_enter(&fp->f_tlock);
950
951 ASSERT(fp->f_count > 0);
952
953 count = fp->f_count--;
954 flag = fp->f_flag;
955 offset = fp->f_offset;
956
957 vp = fp->f_vnode;
958 if (vp != NULL)
959 VOP_IOCTL(vp, F_CLOSED, (intptr_t)ttoproc(curthread),
960 FKIOCTL, kcred, NULL, NULL);
961
962 error = VOP_CLOSE(vp, flag, count, offset, fp->f_cred, NULL);
963
964 if (count > 1) {
965 mutex_exit(&fp->f_tlock);
966 return (error);
967 }
968 ASSERT(fp->f_count == 0);
969 mutex_exit(&fp->f_tlock);
970
971 /*
972 * If DTrace has getf() subroutines active, it will set dtrace_closef
973 * to point to code that implements a barrier with respect to probe
974 * context. This must be called before the file_t is freed (and the
975 * vnode that it refers to is released) -- but it must be after the
976 * file_t has been removed from the uf_entry_t. That is, there must
977 * be no way for a racing getf() in probe context to yield the fp that
978 * we're operating upon.
979 */
980 if (dtrace_closef != NULL)
|