This time, socket's buffer lock requires solock() to be held. I'm working on standalone socket's buffer locking, and I want to commit some bits. I mean SS_CANTSENDMORE and SS_CANTRCVMORE socket's state bits, which I want to turn into per buffer state. The diff below introduces per buffer `sb_state' and turns SS_CANTSENDMORE into SBS_CANTSENDMORE. This bit will be processed on `so_snd' buffer only.
I want to move SS_CANTRCVMORE and SS_RCVATMARK bits with separate diff to make the review easier and exclude possible so_rcv/so_snd mistypes. Also, I don't want to adjust the remaining SS_* bits right now. Index: sys/kern/sys_socket.c =================================================================== RCS file: /cvs/src/sys/kern/sys_socket.c,v retrieving revision 1.56 diff -u -p -r1.56 sys_socket.c --- sys/kern/sys_socket.c 19 Nov 2022 14:26:39 -0000 1.56 +++ sys/kern/sys_socket.c 9 Dec 2022 16:39:25 -0000 @@ -151,7 +151,7 @@ soo_stat(struct file *fp, struct stat *u solock(so); if ((so->so_state & SS_CANTRCVMORE) == 0 || so->so_rcv.sb_cc != 0) ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; - if ((so->so_state & SS_CANTSENDMORE) == 0) + if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0) ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; ub->st_uid = so->so_euid; ub->st_gid = so->so_egid; Index: sys/kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.291 diff -u -p -r1.291 uipc_socket.c --- sys/kern/uipc_socket.c 28 Nov 2022 21:39:28 -0000 1.291 +++ sys/kern/uipc_socket.c 9 Dec 2022 16:39:26 -0000 @@ -580,7 +580,7 @@ restart: goto out; so->so_state |= SS_ISSENDING; do { - if (so->so_state & SS_CANTSENDMORE) + if (so->so_snd.sb_state & SBS_CANTSENDMORE) snderr(EPIPE); if (so->so_error) { error = so->so_error; @@ -1465,7 +1465,7 @@ somove(struct socket *so, int wait) error = so->so_error; goto release; } - if (sosp->so_state & SS_CANTSENDMORE) { + if (sosp->so_snd.sb_state & SBS_CANTSENDMORE) { error = EPIPE; goto release; } @@ -1659,7 +1659,8 @@ somove(struct socket *so, int wait) if (o) { error = pru_send(sosp, m, NULL, NULL); if (error) { - if (sosp->so_state & SS_CANTSENDMORE) + if (sosp->so_snd.sb_state & + SBS_CANTSENDMORE) error = EPIPE; m_freem(o); goto release; @@ -1676,7 +1677,7 @@ somove(struct socket *so, int wait) *mtod(o, caddr_t) = *mtod(m, caddr_t); error = pru_sendoob(sosp, o, NULL, NULL); if (error) { - if (sosp->so_state & SS_CANTSENDMORE) + if (sosp->so_snd.sb_state & SBS_CANTSENDMORE) error = EPIPE; m_freem(m); goto release; @@ -1697,7 +1698,7 @@ somove(struct socket *so, int wait) sosp->so_state &= ~SS_ISSENDING; error = pru_send(sosp, m, NULL, NULL); if (error) { - if (sosp->so_state & SS_CANTSENDMORE) + if (sosp->so_snd.sb_state & SBS_CANTSENDMORE) error = EPIPE; goto release; } @@ -1714,7 +1715,8 @@ somove(struct socket *so, int wait) if (error) so->so_error = error; if (((so->so_state & SS_CANTRCVMORE) && so->so_rcv.sb_cc == 0) || - (sosp->so_state & SS_CANTSENDMORE) || maxreached || error) { + (sosp->so_snd.sb_state & SBS_CANTSENDMORE) || + maxreached || error) { sounsplice(so, sosp, 0); return (0); } @@ -1839,7 +1841,7 @@ sosetopt(struct socket *so, int level, i switch (optname) { case SO_SNDBUF: - if (so->so_state & SS_CANTSENDMORE) + if (so->so_snd.sb_state & SBS_CANTSENDMORE) return (EINVAL); if (sbcheckreserve(cnt, so->so_snd.sb_wat) || sbreserve(so, &so->so_snd, cnt)) @@ -2185,7 +2187,7 @@ filt_sowrite(struct knote *kn, long hint soassertlocked(so); kn->kn_data = sbspace(so, &so->so_snd); - if (so->so_state & SS_CANTSENDMORE) { + if (so->so_snd.sb_state & SBS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; if (kn->kn_flags & __EV_POLL) { if (so->so_state & SS_ISDISCONNECTED) Index: sys/kern/uipc_socket2.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket2.c,v retrieving revision 1.129 diff -u -p -r1.129 uipc_socket2.c --- sys/kern/uipc_socket2.c 3 Oct 2022 16:43:52 -0000 1.129 +++ sys/kern/uipc_socket2.c 9 Dec 2022 16:39:26 -0000 @@ -142,7 +142,8 @@ soisdisconnecting(struct socket *so) { soassertlocked(so); so->so_state &= ~SS_ISCONNECTING; - so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); + so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE); + so->so_snd.sb_state |= SBS_CANTSENDMORE; wakeup(&so->so_timeo); sowwakeup(so); sorwakeup(so); @@ -153,7 +154,8 @@ soisdisconnected(struct socket *so) { soassertlocked(so); so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); - so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED); + so->so_state |= (SS_CANTRCVMORE|SS_ISDISCONNECTED); + so->so_snd.sb_state |= SBS_CANTSENDMORE; wakeup(&so->so_timeo); sowwakeup(so); sorwakeup(so); @@ -334,7 +336,7 @@ void socantsendmore(struct socket *so) { soassertlocked(so); - so->so_state |= SS_CANTSENDMORE; + so->so_snd.sb_state |= SBS_CANTSENDMORE; sowwakeup(so); } Index: sys/kern/uipc_usrreq.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.195 diff -u -p -r1.195 uipc_usrreq.c --- sys/kern/uipc_usrreq.c 5 Dec 2022 23:18:37 -0000 1.195 +++ sys/kern/uipc_usrreq.c 9 Dec 2022 16:39:26 -0000 @@ -509,7 +509,7 @@ uipc_send(struct socket *so, struct mbuf goto out; } - if (so->so_state & SS_CANTSENDMORE) { + if (so->so_snd.sb_state & SBS_CANTSENDMORE) { error = EPIPE; goto dispose; } Index: sys/miscfs/fifofs/fifo_vnops.c =================================================================== RCS file: /cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v retrieving revision 1.96 diff -u -p -r1.96 fifo_vnops.c --- sys/miscfs/fifofs/fifo_vnops.c 1 Jul 2022 09:56:17 -0000 1.96 +++ sys/miscfs/fifofs/fifo_vnops.c 9 Dec 2022 16:39:26 -0000 @@ -174,7 +174,7 @@ fifo_open(void *v) } fip->fi_readers = fip->fi_writers = 0; solock(wso); - wso->so_state |= SS_CANTSENDMORE; + wso->so_snd.sb_state |= SBS_CANTSENDMORE; wso->so_snd.sb_lowat = PIPE_BUF; sounlock(wso); } else { @@ -185,7 +185,7 @@ fifo_open(void *v) fip->fi_readers++; if (fip->fi_readers == 1) { solock(wso); - wso->so_state &= ~SS_CANTSENDMORE; + wso->so_snd.sb_state &= ~SBS_CANTSENDMORE; sounlock(wso); if (fip->fi_writers > 0) wakeup(&fip->fi_writers); @@ -559,7 +559,7 @@ filt_fifowrite(struct knote *kn, long hi soassertlocked(so); kn->kn_data = sbspace(so, &so->so_snd); - if (so->so_state & SS_CANTSENDMORE) { + if (so->so_snd.sb_state & SBS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; rv = 1; } else { Index: sys/netinet/tcp_usrreq.c =================================================================== RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.212 diff -u -p -r1.212 tcp_usrreq.c --- sys/netinet/tcp_usrreq.c 9 Nov 2022 15:01:24 -0000 1.212 +++ sys/netinet/tcp_usrreq.c 9 Dec 2022 16:39:27 -0000 @@ -773,7 +773,7 @@ tcp_shutdown(struct socket *so) ostate = tp->t_state; } - if (so->so_state & SS_CANTSENDMORE) + if (so->so_snd.sb_state & SBS_CANTSENDMORE) goto out; socantsendmore(so); Index: sys/sys/socketvar.h =================================================================== RCS file: /cvs/src/sys/sys/socketvar.h,v retrieving revision 1.112 diff -u -p -r1.112 socketvar.h --- sys/sys/socketvar.h 26 Nov 2022 17:52:35 -0000 1.112 +++ sys/sys/socketvar.h 9 Dec 2022 16:39:27 -0000 @@ -121,6 +121,7 @@ struct socket { short sb_flags; /* flags, see below */ /* End area that is zeroed on flush. */ #define sb_endzero sb_flags + short sb_state; /* state, see below */ uint64_t sb_timeo_nsecs;/* timeout for read/write */ struct selinfo sb_sel; /* process selecting read/write */ } so_rcv, so_snd; @@ -132,6 +133,8 @@ struct socket { #define SB_SPLICE 0x20 /* buffer is splice source or drain */ #define SB_NOINTR 0x40 /* operations not interruptible */ +#define SBS_CANTSENDMORE 0x01 /* can't send more data to peer */ + void (*so_upcall)(struct socket *so, caddr_t arg, int waitf); caddr_t so_upcallarg; /* Arg for above */ uid_t so_euid, so_ruid; /* who opened the socket */ @@ -146,7 +149,6 @@ struct socket { #define SS_ISCONNECTED 0x002 /* socket connected to a peer */ #define SS_ISCONNECTING 0x004 /* in process of connecting to peer */ #define SS_ISDISCONNECTING 0x008 /* in process of disconnecting */ -#define SS_CANTSENDMORE 0x010 /* can't send more data to peer */ #define SS_CANTRCVMORE 0x020 /* can't receive more data from peer */ #define SS_RCVATMARK 0x040 /* at mark on input */ #define SS_ISDISCONNECTED 0x800 /* socket disconnected from peer */ @@ -237,7 +239,7 @@ sowriteable(struct socket *so) return ((sbspace(so, &so->so_snd) >= so->so_snd.sb_lowat && ((so->so_state & SS_ISCONNECTED) || (so->so_proto->pr_flags & PR_CONNREQUIRED)==0)) || - (so->so_state & SS_CANTSENDMORE) || so->so_error); + (so->so_snd.sb_state & SBS_CANTSENDMORE) || so->so_error); } /* adjust counters in sb reflecting allocation of m */