]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
smb: client: make use of smbdirect_connection_recvmsg()
authorStefan Metzmacher <metze@samba.org>
Mon, 13 Oct 2025 16:42:08 +0000 (18:42 +0200)
committerSteve French <stfrench@microsoft.com>
Thu, 16 Apr 2026 02:58:21 +0000 (21:58 -0500)
This is basically the same as it was copied before...

Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smbdirect.c

index bd93aee5155782e7e038792a4c3a52665f141a10..ffdb87d24b47f35fe712622d6b8ecace268d3e12 100644 (file)
@@ -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);
 }
 
 /*