Print this page
12276 smatch-clean sockfs


4794         /*
4795          * For UDP we don't break up the copyin into smaller pieces
4796          * as in the TCP case.  That means if ENOMEM is returned by
4797          * mcopyinuio() then the uio vector has not been modified at
4798          * all and we fallback to either strwrite() or kstrputmsg()
4799          * below.  Note also that we never generate priority messages
4800          * from here.
4801          */
4802         udp_wq = stp->sd_wrq->q_next;
4803         if (canput(udp_wq) &&
4804             (mpdata = mcopyinuio(stp, uiop, -1, -1, &error)) != NULL) {
4805                 ASSERT(DB_TYPE(mpdata) == M_DATA);
4806                 ASSERT(uiop->uio_resid == 0);
4807                 if (!connected)
4808                         linkb(mp, mpdata);
4809                 else
4810                         mp = mpdata;
4811                 if (auditing)
4812                         audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
4813 
4814                 udp_wput(udp_wq, mp);
4815                 return (0);
4816         }
4817 
4818         ASSERT(mpdata == NULL);
4819         if (error != 0 && error != ENOMEM) {
4820                 freemsg(mp);
4821                 return (error);
4822         }
4823 
4824         /*
4825          * For connected, let strwrite() handle the blocking case.
4826          * Otherwise we fall thru and use kstrputmsg().
4827          */
4828         if (connected)
4829                 return (strwrite(SOTOV(so), uiop, CRED()));
4830 
4831         if (auditing)
4832                 audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
4833 
4834         error = kstrputmsg(SOTOV(so), mp, uiop, len, 0, MSG_BAND, 0);
4835 done:


4857             (error = straccess(stp, JCWRITE)) != 0)
4858                 return (error);
4859 
4860         if (uiop == NULL) {
4861                 /*
4862                  * kstrwritemp() should have checked sd_flag and
4863                  * flow-control before coming here.  If we end up
4864                  * here it means that we can simply pass down the
4865                  * data to tcp.
4866                  */
4867                 ASSERT(mp != NULL);
4868                 if (stp->sd_wputdatafunc != NULL) {
4869                         newmp = (stp->sd_wputdatafunc)(SOTOV(so), mp, NULL,
4870                             NULL, NULL, NULL);
4871                         if (newmp == NULL) {
4872                                 /* The caller will free mp */
4873                                 return (ECOMM);
4874                         }
4875                         mp = newmp;
4876                 }
4877                 tcp_wput(tcp_wq, mp);
4878                 return (0);
4879         }
4880 
4881         /* Fallback to strwrite() to do proper error handling */
4882         if (stp->sd_flag & (STWRERR|STRHUP|STPLEX|STRDELIM|OLDNDELAY))
4883                 return (strwrite(SOTOV(so), uiop, cr));
4884 
4885         rmax = stp->sd_qn_maxpsz;
4886         ASSERT(rmax >= 0 || rmax == INFPSZ);
4887         if (rmax == 0 || uiop->uio_resid <= 0)
4888                 return (0);
4889 
4890         if (rmax == INFPSZ)
4891                 rmax = uiop->uio_resid;
4892 
4893         maxblk = stp->sd_maxblk;
4894 
4895         for (;;) {
4896                 iosize = MIN(uiop->uio_resid, rmax);
4897 
4898                 mp = mcopyinuio(stp, uiop, iosize, maxblk, &error);


4908                         else
4909                                 return (error);
4910                 }
4911                 ASSERT(uiop->uio_resid >= 0);
4912                 /*
4913                  * If mp is non-NULL and ENOMEM is set, it means that
4914                  * mcopyinuio() was able to break down some of the user
4915                  * data into one or more mblks.  Send the partial data
4916                  * to tcp and let the rest be handled in strwrite().
4917                  */
4918                 ASSERT(error == 0 || error == ENOMEM);
4919                 if (stp->sd_wputdatafunc != NULL) {
4920                         newmp = (stp->sd_wputdatafunc)(SOTOV(so), mp, NULL,
4921                             NULL, NULL, NULL);
4922                         if (newmp == NULL) {
4923                                 /* The caller will free mp */
4924                                 return (ECOMM);
4925                         }
4926                         mp = newmp;
4927                 }
4928                 tcp_wput(tcp_wq, mp);
4929 
4930                 wflag |= NOINTR;
4931 
4932                 if (uiop->uio_resid == 0) {  /* No more data; we're done */
4933                         ASSERT(error == 0);
4934                         break;
4935                 } else if (error == ENOMEM || !canput(tcp_wq) || (stp->sd_flag &
4936                     (STWRERR|STRHUP|STPLEX|STRDELIM|OLDNDELAY))) {
4937 slow_send:
4938                         /*
4939                          * We were able to send down partial data using
4940                          * the direct call interface, but are now relying
4941                          * on strwrite() to handle the non-fastpath cases.
4942                          * If the socket is blocking we will sleep in
4943                          * strwaitq() until write is permitted, otherwise,
4944                          * we will need to return the amount of bytes
4945                          * written so far back to the app.  This is the
4946                          * reason why we pass NOINTR flag to strwrite()
4947                          * for non-blocking socket, because we don't want
4948                          * to return EAGAIN when portion of the user data




4794         /*
4795          * For UDP we don't break up the copyin into smaller pieces
4796          * as in the TCP case.  That means if ENOMEM is returned by
4797          * mcopyinuio() then the uio vector has not been modified at
4798          * all and we fallback to either strwrite() or kstrputmsg()
4799          * below.  Note also that we never generate priority messages
4800          * from here.
4801          */
4802         udp_wq = stp->sd_wrq->q_next;
4803         if (canput(udp_wq) &&
4804             (mpdata = mcopyinuio(stp, uiop, -1, -1, &error)) != NULL) {
4805                 ASSERT(DB_TYPE(mpdata) == M_DATA);
4806                 ASSERT(uiop->uio_resid == 0);
4807                 if (!connected)
4808                         linkb(mp, mpdata);
4809                 else
4810                         mp = mpdata;
4811                 if (auditing)
4812                         audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
4813 
4814                 /* Always returns 0... */
4815                 return (udp_wput(udp_wq, mp));
4816         }
4817 
4818         ASSERT(mpdata == NULL);
4819         if (error != 0 && error != ENOMEM) {
4820                 freemsg(mp);
4821                 return (error);
4822         }
4823 
4824         /*
4825          * For connected, let strwrite() handle the blocking case.
4826          * Otherwise we fall thru and use kstrputmsg().
4827          */
4828         if (connected)
4829                 return (strwrite(SOTOV(so), uiop, CRED()));
4830 
4831         if (auditing)
4832                 audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
4833 
4834         error = kstrputmsg(SOTOV(so), mp, uiop, len, 0, MSG_BAND, 0);
4835 done:


4857             (error = straccess(stp, JCWRITE)) != 0)
4858                 return (error);
4859 
4860         if (uiop == NULL) {
4861                 /*
4862                  * kstrwritemp() should have checked sd_flag and
4863                  * flow-control before coming here.  If we end up
4864                  * here it means that we can simply pass down the
4865                  * data to tcp.
4866                  */
4867                 ASSERT(mp != NULL);
4868                 if (stp->sd_wputdatafunc != NULL) {
4869                         newmp = (stp->sd_wputdatafunc)(SOTOV(so), mp, NULL,
4870                             NULL, NULL, NULL);
4871                         if (newmp == NULL) {
4872                                 /* The caller will free mp */
4873                                 return (ECOMM);
4874                         }
4875                         mp = newmp;
4876                 }
4877                 /* Always returns 0... */
4878                 return (tcp_wput(tcp_wq, mp));
4879         }
4880 
4881         /* Fallback to strwrite() to do proper error handling */
4882         if (stp->sd_flag & (STWRERR|STRHUP|STPLEX|STRDELIM|OLDNDELAY))
4883                 return (strwrite(SOTOV(so), uiop, cr));
4884 
4885         rmax = stp->sd_qn_maxpsz;
4886         ASSERT(rmax >= 0 || rmax == INFPSZ);
4887         if (rmax == 0 || uiop->uio_resid <= 0)
4888                 return (0);
4889 
4890         if (rmax == INFPSZ)
4891                 rmax = uiop->uio_resid;
4892 
4893         maxblk = stp->sd_maxblk;
4894 
4895         for (;;) {
4896                 iosize = MIN(uiop->uio_resid, rmax);
4897 
4898                 mp = mcopyinuio(stp, uiop, iosize, maxblk, &error);


4908                         else
4909                                 return (error);
4910                 }
4911                 ASSERT(uiop->uio_resid >= 0);
4912                 /*
4913                  * If mp is non-NULL and ENOMEM is set, it means that
4914                  * mcopyinuio() was able to break down some of the user
4915                  * data into one or more mblks.  Send the partial data
4916                  * to tcp and let the rest be handled in strwrite().
4917                  */
4918                 ASSERT(error == 0 || error == ENOMEM);
4919                 if (stp->sd_wputdatafunc != NULL) {
4920                         newmp = (stp->sd_wputdatafunc)(SOTOV(so), mp, NULL,
4921                             NULL, NULL, NULL);
4922                         if (newmp == NULL) {
4923                                 /* The caller will free mp */
4924                                 return (ECOMM);
4925                         }
4926                         mp = newmp;
4927                 }
4928                 (void) tcp_wput(tcp_wq, mp);    /* Always returns 0 anyway. */
4929 
4930                 wflag |= NOINTR;
4931 
4932                 if (uiop->uio_resid == 0) {  /* No more data; we're done */
4933                         ASSERT(error == 0);
4934                         break;
4935                 } else if (error == ENOMEM || !canput(tcp_wq) || (stp->sd_flag &
4936                     (STWRERR|STRHUP|STPLEX|STRDELIM|OLDNDELAY))) {
4937 slow_send:
4938                         /*
4939                          * We were able to send down partial data using
4940                          * the direct call interface, but are now relying
4941                          * on strwrite() to handle the non-fastpath cases.
4942                          * If the socket is blocking we will sleep in
4943                          * strwaitq() until write is permitted, otherwise,
4944                          * we will need to return the amount of bytes
4945                          * written so far back to the app.  This is the
4946                          * reason why we pass NOINTR flag to strwrite()
4947                          * for non-blocking socket, because we don't want
4948                          * to return EAGAIN when portion of the user data