summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/sys_socket.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-07 14:56:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:37 +0200
commitc37f9fba70085fedc8eede7559489d2321393005 (patch)
tree042455ebf1fa89a277a825f72e1ed805d0b4d296 /freebsd/sys/kern/sys_socket.c
parentUpdate to FreeBSD head 2017-06-01 (diff)
downloadrtems-libbsd-c37f9fba70085fedc8eede7559489d2321393005.tar.bz2
Update to FreeBSD head 2017-08-01
Git mirror commit f5002f5e5f78cae9f0269d812dc0aedb0339312c. Update #3472.
Diffstat (limited to 'freebsd/sys/kern/sys_socket.c')
-rw-r--r--freebsd/sys/kern/sys_socket.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c
index 8d87c51b..9dd458f1 100644
--- a/freebsd/sys/kern/sys_socket.c
+++ b/freebsd/sys/kern/sys_socket.c
@@ -318,32 +318,36 @@ soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred,
break;
case FIOASYNC:
- /*
- * XXXRW: This code separately acquires SOCK_LOCK(so) and
- * SOCKBUF_LOCK(&so->so_rcv) even though they are the same
- * mutex to avoid introducing the assumption that they are
- * the same.
- */
if (*(int *)data) {
SOCK_LOCK(so);
so->so_state |= SS_ASYNC;
+ if (SOLISTENING(so)) {
+ so->sol_sbrcv_flags |= SB_ASYNC;
+ so->sol_sbsnd_flags |= SB_ASYNC;
+ } else {
+ SOCKBUF_LOCK(&so->so_rcv);
+ so->so_rcv.sb_flags |= SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
+ so->so_snd.sb_flags |= SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_snd);
+ }
SOCK_UNLOCK(so);
- SOCKBUF_LOCK(&so->so_rcv);
- so->so_rcv.sb_flags |= SB_ASYNC;
- SOCKBUF_UNLOCK(&so->so_rcv);
- SOCKBUF_LOCK(&so->so_snd);
- so->so_snd.sb_flags |= SB_ASYNC;
- SOCKBUF_UNLOCK(&so->so_snd);
} else {
SOCK_LOCK(so);
so->so_state &= ~SS_ASYNC;
+ if (SOLISTENING(so)) {
+ so->sol_sbrcv_flags &= ~SB_ASYNC;
+ so->sol_sbsnd_flags &= ~SB_ASYNC;
+ } else {
+ SOCKBUF_LOCK(&so->so_rcv);
+ so->so_rcv.sb_flags &= ~SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
+ so->so_snd.sb_flags &= ~SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_snd);
+ }
SOCK_UNLOCK(so);
- SOCKBUF_LOCK(&so->so_rcv);
- so->so_rcv.sb_flags &= ~SB_ASYNC;
- SOCKBUF_UNLOCK(&so->so_rcv);
- SOCKBUF_LOCK(&so->so_snd);
- so->so_snd.sb_flags &= ~SB_ASYNC;
- SOCKBUF_UNLOCK(&so->so_snd);
}
break;
@@ -477,7 +481,6 @@ static int
soo_stat(struct socket *so, struct stat *ub)
{
#endif /* __rtems__ */
- struct sockbuf *sb;
#ifdef MAC
int error;
#endif
@@ -491,22 +494,26 @@ soo_stat(struct socket *so, struct stat *ub)
if (error)
return (error);
#endif
- /*
- * If SBS_CANTRCVMORE is set, but there's still data left in the
- * receive buffer, the socket is still readable.
- */
- sb = &so->so_rcv;
- SOCKBUF_LOCK(sb);
- if ((sb->sb_state & SBS_CANTRCVMORE) == 0 || sbavail(sb))
- ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
- ub->st_size = sbavail(sb) - sb->sb_ctl;
- SOCKBUF_UNLOCK(sb);
+ if (!SOLISTENING(so)) {
+ struct sockbuf *sb;
- sb = &so->so_snd;
- SOCKBUF_LOCK(sb);
- if ((sb->sb_state & SBS_CANTSENDMORE) == 0)
- ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- SOCKBUF_UNLOCK(sb);
+ /*
+ * If SBS_CANTRCVMORE is set, but there's still data left
+ * in the receive buffer, the socket is still readable.
+ */
+ sb = &so->so_rcv;
+ SOCKBUF_LOCK(sb);
+ if ((sb->sb_state & SBS_CANTRCVMORE) == 0 || sbavail(sb))
+ ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
+ ub->st_size = sbavail(sb) - sb->sb_ctl;
+ SOCKBUF_UNLOCK(sb);
+
+ sb = &so->so_snd;
+ SOCKBUF_LOCK(sb);
+ if ((sb->sb_state & SBS_CANTSENDMORE) == 0)
+ ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ SOCKBUF_UNLOCK(sb);
+ }
#ifndef __rtems__
ub->st_uid = so->so_cred->cr_uid;
ub->st_gid = so->so_cred->cr_gid;
@@ -916,6 +923,7 @@ soaio_process_sb(struct socket *so, struct sockbuf *sb)
{
struct kaiocb *job;
+ CURVNET_SET(so->so_vnet);
SOCKBUF_LOCK(sb);
while (!TAILQ_EMPTY(&sb->sb_aiojobq) && soaio_ready(so, sb)) {
job = TAILQ_FIRST(&sb->sb_aiojobq);
@@ -936,9 +944,9 @@ soaio_process_sb(struct socket *so, struct sockbuf *sb)
sb->sb_flags &= ~SB_AIO_RUNNING;
SOCKBUF_UNLOCK(sb);
- ACCEPT_LOCK();
SOCK_LOCK(so);
sorele(so);
+ CURVNET_RESTORE();
}
void