From: Stefan Metzmacher Date: Mon, 13 Oct 2025 16:42:08 +0000 (+0200) Subject: smb: client: make use of smbdirect_connection_recvmsg() X-Git-Tag: v7.1-rc1~128^2~62 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=edb9e514f0e058a924a169795fb0e34286da9572;p=thirdparty%2Flinux.git smb: client: make use of smbdirect_connection_recvmsg() This is basically the same as it was copied before... Cc: Steve French Cc: Tom Talpey Cc: Long Li Cc: Namjae Jeon Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher Acked-by: Namjae Jeon Signed-off-by: Steve French --- diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index bd93aee515578..ffdb87d24b47f 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -1580,137 +1580,8 @@ try_again: int smbd_recv(struct smbd_connection *info, struct msghdr *msg) { struct smbdirect_socket *sc = &info->socket; - struct smbdirect_recv_io *response; - struct smbdirect_data_transfer *data_transfer; - size_t size = iov_iter_count(&msg->msg_iter); - int to_copy, to_read, data_read, offset; - u32 data_length, remaining_data_length, data_offset; - int rc; - - if (WARN_ON_ONCE(iov_iter_rw(&msg->msg_iter) == WRITE)) - return -EINVAL; /* It's a bug in upper layer to get there */ - -again: - /* - * No need to hold the reassembly queue lock all the time as we are - * the only one reading from the front of the queue. The transport - * may add more entries to the back of the queue at the same time - */ - log_read(INFO, "size=%zd sc->recv_io.reassembly.data_length=%d\n", size, - sc->recv_io.reassembly.data_length); - if (sc->recv_io.reassembly.data_length >= size) { - int queue_length; - int queue_removed = 0; - unsigned long flags; - - /* - * Need to make sure reassembly_data_length is read before - * reading reassembly_queue_length and calling - * smbdirect_connection_reassembly_first_recv_io. This call is lock free - * as we never read at the end of the queue which are being - * updated in SOFTIRQ as more data is received - */ - virt_rmb(); - queue_length = sc->recv_io.reassembly.queue_length; - data_read = 0; - to_read = size; - offset = sc->recv_io.reassembly.first_entry_offset; - while (data_read < size) { - response = smbdirect_connection_reassembly_first_recv_io(sc); - data_transfer = smbdirect_recv_io_payload(response); - data_length = le32_to_cpu(data_transfer->data_length); - remaining_data_length = - le32_to_cpu( - data_transfer->remaining_data_length); - data_offset = le32_to_cpu(data_transfer->data_offset); - - /* - * The upper layer expects RFC1002 length at the - * beginning of the payload. Return it to indicate - * the total length of the packet. This minimize the - * change to upper layer packet processing logic. This - * will be eventually remove when an intermediate - * transport layer is added - */ - if (response->first_segment && size == 4) { - unsigned int rfc1002_len = - data_length + remaining_data_length; - __be32 rfc1002_hdr = cpu_to_be32(rfc1002_len); - if (copy_to_iter(&rfc1002_hdr, sizeof(rfc1002_hdr), - &msg->msg_iter) != sizeof(rfc1002_hdr)) - return -EFAULT; - data_read = 4; - response->first_segment = false; - log_read(INFO, "returning rfc1002 length %d\n", - rfc1002_len); - goto read_rfc1002_done; - } - - to_copy = min_t(int, data_length - offset, to_read); - if (copy_to_iter((char *)data_transfer + data_offset + offset, - to_copy, &msg->msg_iter) != to_copy) - return -EFAULT; - - /* move on to the next buffer? */ - if (to_copy == data_length - offset) { - queue_length--; - /* - * No need to lock if we are not at the - * end of the queue - */ - if (queue_length) - list_del(&response->list); - else { - spin_lock_irqsave( - &sc->recv_io.reassembly.lock, flags); - list_del(&response->list); - spin_unlock_irqrestore( - &sc->recv_io.reassembly.lock, flags); - } - queue_removed++; - sc->statistics.dequeue_reassembly_queue++; - smbdirect_connection_put_recv_io(response); - offset = 0; - log_read(INFO, "smbdirect_connection_put_recv_io offset=0\n"); - } else - offset += to_copy; - - to_read -= to_copy; - data_read += to_copy; - - log_read(INFO, "_get_first_reassembly memcpy %d bytes data_transfer_length-offset=%d after that to_read=%d data_read=%d offset=%d\n", - to_copy, data_length - offset, - to_read, data_read, offset); - } - - spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags); - sc->recv_io.reassembly.data_length -= data_read; - sc->recv_io.reassembly.queue_length -= queue_removed; - spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags); - - sc->recv_io.reassembly.first_entry_offset = offset; - log_read(INFO, "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n", - data_read, sc->recv_io.reassembly.data_length, - sc->recv_io.reassembly.first_entry_offset); -read_rfc1002_done: - return data_read; - } - - log_read(INFO, "wait_event on more data\n"); - rc = wait_event_interruptible( - sc->recv_io.reassembly.wait_queue, - sc->recv_io.reassembly.data_length >= size || - sc->status != SMBDIRECT_SOCKET_CONNECTED); - /* Don't return any data if interrupted */ - if (rc) - return rc; - - if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { - log_read(ERR, "disconnected\n"); - return -ECONNABORTED; - } - goto again; + return smbdirect_connection_recvmsg(sc, msg, 0); } /*