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