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); |
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. |