usr/src/uts/common/os/streamio.c
changeset 741 40027a3621ac
parent 577 65796fd3c2db
child 898 64b2a371a6bd
equal deleted inserted replaced
740:70e4862c9a1a 741:40027a3621ac
  2640  */
  2640  */
  2641 /* ARGSUSED2 */
  2641 /* ARGSUSED2 */
  2642 int
  2642 int
  2643 strwrite(struct vnode *vp, struct uio *uiop, cred_t *crp)
  2643 strwrite(struct vnode *vp, struct uio *uiop, cred_t *crp)
  2644 {
  2644 {
       
  2645 	return (strwrite_common(vp, uiop, crp, 0));
       
  2646 }
       
  2647 
       
  2648 /* ARGSUSED2 */
       
  2649 int
       
  2650 strwrite_common(struct vnode *vp, struct uio *uiop, cred_t *crp, int wflag)
       
  2651 {
  2645 	struct stdata *stp;
  2652 	struct stdata *stp;
  2646 	struct queue *wqp;
  2653 	struct queue *wqp;
  2647 	ssize_t rmin, rmax;
  2654 	ssize_t rmin, rmax;
  2648 	ssize_t iosize;
  2655 	ssize_t iosize;
  2649 	char waitflag;
  2656 	int waitflag;
  2650 	int tempmode;
  2657 	int tempmode;
  2651 	int error = 0;
  2658 	int error = 0;
  2652 	int b_flag;
  2659 	int b_flag;
  2653 
  2660 
  2654 	ASSERT(vp->v_stream);
  2661 	ASSERT(vp->v_stream);
  2699 	}
  2706 	}
  2700 
  2707 
  2701 	/*
  2708 	/*
  2702 	 * Do until count satisfied or error.
  2709 	 * Do until count satisfied or error.
  2703 	 */
  2710 	 */
  2704 	waitflag = WRITEWAIT;
  2711 	waitflag = WRITEWAIT | wflag;
  2705 	if (stp->sd_flag & OLDNDELAY)
  2712 	if (stp->sd_flag & OLDNDELAY)
  2706 		tempmode = uiop->uio_fmode & ~FNDELAY;
  2713 		tempmode = uiop->uio_fmode & ~FNDELAY;
  2707 	else
  2714 	else
  2708 		tempmode = uiop->uio_fmode;
  2715 		tempmode = uiop->uio_fmode;
  2709 
  2716 
  2797 	 */
  2804 	 */
  2798 	if (error == ENOMEM)
  2805 	if (error == ENOMEM)
  2799 		error = EAGAIN;
  2806 		error = EAGAIN;
  2800 	TRACE_3(TR_FAC_STREAMS_FR, TR_STRWRITE_OUT,
  2807 	TRACE_3(TR_FAC_STREAMS_FR, TR_STRWRITE_OUT,
  2801 		"strwrite out:q %p out %d error %d", wqp, 2, error);
  2808 		"strwrite out:q %p out %d error %d", wqp, 2, error);
  2802 	return (error);
       
  2803 }
       
  2804 
       
  2805 /*
       
  2806  * kstrwritemp() has very similar semantics as that of strwrite().
       
  2807  * The main difference is it obtains mblks from the caller and also
       
  2808  * does not do any copy as done in strwrite() from user buffers to
       
  2809  * kernel buffers.
       
  2810  *
       
  2811  *
       
  2812  * Currently, this routine is used by sendfile to send data allocated
       
  2813  * within the kernel without any copying. This interface does not use the
       
  2814  * synchronous stream interface as synch. stream interface implies
       
  2815  * copying.
       
  2816  */
       
  2817 int
       
  2818 kstrwritemp(struct vnode *vp, mblk_t *mp, ushort_t fmode)
       
  2819 {
       
  2820 	struct stdata *stp;
       
  2821 	struct queue *wqp;
       
  2822 	char waitflag;
       
  2823 	int tempmode;
       
  2824 	int error;
       
  2825 	int done = 0;
       
  2826 
       
  2827 	ASSERT(vp->v_stream);
       
  2828 	stp = vp->v_stream;
       
  2829 
       
  2830 	if (stp->sd_flag & (STWRERR|STRHUP|STPLEX)) {
       
  2831 		mutex_enter(&stp->sd_lock);
       
  2832 		error = strwriteable(stp, B_FALSE, B_TRUE);
       
  2833 		mutex_exit(&stp->sd_lock);
       
  2834 		if (error != 0)
       
  2835 			return (error);
       
  2836 	}
       
  2837 
       
  2838 	/*
       
  2839 	 * First, check for flow control without grabbing the sd_lock.
       
  2840 	 * If we would block, re-check with the lock. This is similar
       
  2841 	 * to the logic used by strwrite().
       
  2842 	 */
       
  2843 	wqp = stp->sd_wrq;
       
  2844 	if (canputnext(wqp)) {
       
  2845 		putnext(wqp, mp);
       
  2846 		return (0);
       
  2847 	}
       
  2848 
       
  2849 	waitflag = WRITEWAIT;
       
  2850 	if (stp->sd_flag & OLDNDELAY)
       
  2851 		tempmode = fmode & ~FNDELAY;
       
  2852 	else
       
  2853 		tempmode = fmode;
       
  2854 
       
  2855 	mutex_enter(&stp->sd_lock);
       
  2856 	do {
       
  2857 		if (canputnext(wqp)) {
       
  2858 			mutex_exit(&stp->sd_lock);
       
  2859 			putnext(wqp, mp);
       
  2860 			return (0);
       
  2861 		}
       
  2862 		error = strwaitq(stp, waitflag, (ssize_t)0, tempmode, -1,
       
  2863 		    &done);
       
  2864 	} while (error == 0 && !done);
       
  2865 
       
  2866 	mutex_exit(&stp->sd_lock);
       
  2867 	/*
       
  2868 	 * EAGAIN tells the application to try again. ENOMEM
       
  2869 	 * is returned only if the memory allocation size
       
  2870 	 * exceeds the physical limits of the system. ENOMEM
       
  2871 	 * can't be true here.
       
  2872 	 */
       
  2873 	if (error == ENOMEM)
       
  2874 		error = EAGAIN;
       
  2875 	return (error);
  2809 	return (error);
  2876 }
  2810 }
  2877 
  2811 
  2878 /*
  2812 /*
  2879  * Stream head write service routine.
  2813  * Stream head write service routine.