Loading drivers/char/diag/diagfwd_socket.c +34 −3 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include <linux/slab.h> Loading Loading @@ -511,9 +511,10 @@ static void __socket_close_channel(struct diag_socket_info *info) info->hdl->sk->sk_data_ready = NULL; info->hdl->sk->sk_error_report = NULL; write_unlock_bh(&info->hdl->sk->sk_callback_lock); mutex_lock(&info->socket_info_mutex); sock_release(info->hdl); info->hdl = NULL; mutex_unlock(&info->socket_info_mutex); cancel_work_sync(&info->read_work); wake_up_interruptible(&info->read_wait_q); Loading Loading @@ -714,13 +715,28 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) read_msg.msg_name = &src_addr; read_msg.msg_namelen = sizeof(src_addr); if (info->port_type != PORT_TYPE_SERVER) { mutex_lock(&info->socket_info_mutex); if (!info->hdl) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s closing read thread\n", info->name); mutex_unlock(&info->socket_info_mutex); goto fail; } } err = info->hdl->ops->ioctl(info->hdl, TIOCINQ, (unsigned long)&pkt_len); if (err || pkt_len < 0) if (err || pkt_len < 0) { if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); break; } if (pkt_len > bytes_remaining) { buf_full = 1; if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); break; } Loading @@ -730,6 +746,8 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) read_len = kernel_recvmsg(info->hdl, &read_msg, &iov, 1, pkt_len, MSG_DONTWAIT); if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); if (unlikely(read_len == -ENETRESET)) { mutex_lock(channel_mutex); diagfwd_channel_read_done(info->fwd_ctxt, buf, 0); Loading Loading @@ -837,7 +855,16 @@ static int diag_socket_write(void *ctxt, unsigned char *buf, int len) write_msg.msg_name = &info->remote_addr; write_msg.msg_namelen = sizeof(info->remote_addr); write_msg.msg_flags |= MSG_DONTWAIT; if (info->port_type != PORT_TYPE_SERVER) { mutex_lock(&info->socket_info_mutex); if (!info->hdl) { mutex_unlock(&info->socket_info_mutex); return -ENODEV; } } write_len = kernel_sendmsg(info->hdl, &write_msg, &iov, 1, len); if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); if (write_len < 0) { err = write_len; /* Loading Loading @@ -935,6 +962,8 @@ static void __diag_socket_init(struct diag_socket_info *info) break; } if (info->port_type == PORT_TYPE_CLIENT) mutex_init(&info->socket_info_mutex); info->svc_id = DIAG_SVC_ID; info->ins_id = ins_base + ins_offset; info->inited = 1; Loading Loading @@ -1092,6 +1121,8 @@ static void __diag_socket_exit(struct diag_socket_info *info) if (info->hdl) sock_release(info->hdl); info->hdl = NULL; if (info->port_type == PORT_TYPE_CLIENT) mutex_destroy(&info->socket_info_mutex); if (info->wq) destroy_workqueue(info->wq); } Loading drivers/char/diag/diagfwd_socket.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef DIAGFWD_SOCKET_H Loading Loading @@ -49,6 +49,7 @@ struct diag_socket_info { struct work_struct read_work; struct diagfwd_info *fwd_ctxt; wait_queue_head_t read_wait_q; struct mutex socket_info_mutex; }; Loading Loading
drivers/char/diag/diagfwd_socket.c +34 −3 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include <linux/slab.h> Loading Loading @@ -511,9 +511,10 @@ static void __socket_close_channel(struct diag_socket_info *info) info->hdl->sk->sk_data_ready = NULL; info->hdl->sk->sk_error_report = NULL; write_unlock_bh(&info->hdl->sk->sk_callback_lock); mutex_lock(&info->socket_info_mutex); sock_release(info->hdl); info->hdl = NULL; mutex_unlock(&info->socket_info_mutex); cancel_work_sync(&info->read_work); wake_up_interruptible(&info->read_wait_q); Loading Loading @@ -714,13 +715,28 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) read_msg.msg_name = &src_addr; read_msg.msg_namelen = sizeof(src_addr); if (info->port_type != PORT_TYPE_SERVER) { mutex_lock(&info->socket_info_mutex); if (!info->hdl) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s closing read thread\n", info->name); mutex_unlock(&info->socket_info_mutex); goto fail; } } err = info->hdl->ops->ioctl(info->hdl, TIOCINQ, (unsigned long)&pkt_len); if (err || pkt_len < 0) if (err || pkt_len < 0) { if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); break; } if (pkt_len > bytes_remaining) { buf_full = 1; if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); break; } Loading @@ -730,6 +746,8 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len) read_len = kernel_recvmsg(info->hdl, &read_msg, &iov, 1, pkt_len, MSG_DONTWAIT); if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); if (unlikely(read_len == -ENETRESET)) { mutex_lock(channel_mutex); diagfwd_channel_read_done(info->fwd_ctxt, buf, 0); Loading Loading @@ -837,7 +855,16 @@ static int diag_socket_write(void *ctxt, unsigned char *buf, int len) write_msg.msg_name = &info->remote_addr; write_msg.msg_namelen = sizeof(info->remote_addr); write_msg.msg_flags |= MSG_DONTWAIT; if (info->port_type != PORT_TYPE_SERVER) { mutex_lock(&info->socket_info_mutex); if (!info->hdl) { mutex_unlock(&info->socket_info_mutex); return -ENODEV; } } write_len = kernel_sendmsg(info->hdl, &write_msg, &iov, 1, len); if (info->port_type != PORT_TYPE_SERVER) mutex_unlock(&info->socket_info_mutex); if (write_len < 0) { err = write_len; /* Loading Loading @@ -935,6 +962,8 @@ static void __diag_socket_init(struct diag_socket_info *info) break; } if (info->port_type == PORT_TYPE_CLIENT) mutex_init(&info->socket_info_mutex); info->svc_id = DIAG_SVC_ID; info->ins_id = ins_base + ins_offset; info->inited = 1; Loading Loading @@ -1092,6 +1121,8 @@ static void __diag_socket_exit(struct diag_socket_info *info) if (info->hdl) sock_release(info->hdl); info->hdl = NULL; if (info->port_type == PORT_TYPE_CLIENT) mutex_destroy(&info->socket_info_mutex); if (info->wq) destroy_workqueue(info->wq); } Loading
drivers/char/diag/diagfwd_socket.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef DIAGFWD_SOCKET_H Loading Loading @@ -49,6 +49,7 @@ struct diag_socket_info { struct work_struct read_work; struct diagfwd_info *fwd_ctxt; wait_queue_head_t read_wait_q; struct mutex socket_info_mutex; }; Loading