mirror of
https://github.com/torvalds/linux.git
synced 2025-08-15 22:21:42 +02:00
smb: client: make use of struct smbdirect_recv_io
This is the shared structure that will be used in the server too and will allow us to move helper functions into common code soon. Cc: Steve French <smfrench@gmail.com> Cc: Tom Talpey <tom@talpey.com> Cc: Long Li <longli@microsoft.com> Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
60812d20da
commit
5dddf04974
2 changed files with 41 additions and 54 deletions
|
@ -13,23 +13,23 @@
|
||||||
#include "cifsproto.h"
|
#include "cifsproto.h"
|
||||||
#include "smb2proto.h"
|
#include "smb2proto.h"
|
||||||
|
|
||||||
static struct smbd_response *get_receive_buffer(
|
static struct smbdirect_recv_io *get_receive_buffer(
|
||||||
struct smbd_connection *info);
|
struct smbd_connection *info);
|
||||||
static void put_receive_buffer(
|
static void put_receive_buffer(
|
||||||
struct smbd_connection *info,
|
struct smbd_connection *info,
|
||||||
struct smbd_response *response);
|
struct smbdirect_recv_io *response);
|
||||||
static int allocate_receive_buffers(struct smbd_connection *info, int num_buf);
|
static int allocate_receive_buffers(struct smbd_connection *info, int num_buf);
|
||||||
static void destroy_receive_buffers(struct smbd_connection *info);
|
static void destroy_receive_buffers(struct smbd_connection *info);
|
||||||
|
|
||||||
static void enqueue_reassembly(
|
static void enqueue_reassembly(
|
||||||
struct smbd_connection *info,
|
struct smbd_connection *info,
|
||||||
struct smbd_response *response, int data_length);
|
struct smbdirect_recv_io *response, int data_length);
|
||||||
static struct smbd_response *_get_first_reassembly(
|
static struct smbdirect_recv_io *_get_first_reassembly(
|
||||||
struct smbd_connection *info);
|
struct smbd_connection *info);
|
||||||
|
|
||||||
static int smbd_post_recv(
|
static int smbd_post_recv(
|
||||||
struct smbd_connection *info,
|
struct smbd_connection *info,
|
||||||
struct smbd_response *response);
|
struct smbdirect_recv_io *response);
|
||||||
|
|
||||||
static int smbd_post_send_empty(struct smbd_connection *info);
|
static int smbd_post_send_empty(struct smbd_connection *info);
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ static inline void *smbd_request_payload(struct smbd_request *request)
|
||||||
return (void *)request->packet;
|
return (void *)request->packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *smbd_response_payload(struct smbd_response *response)
|
static inline void *smbdirect_recv_io_payload(struct smbdirect_recv_io *response)
|
||||||
{
|
{
|
||||||
return (void *)response->packet;
|
return (void *)response->packet;
|
||||||
}
|
}
|
||||||
|
@ -315,12 +315,13 @@ static void dump_smbdirect_negotiate_resp(struct smbdirect_negotiate_resp *resp)
|
||||||
* return value: true if negotiation is a success, false if failed
|
* return value: true if negotiation is a success, false if failed
|
||||||
*/
|
*/
|
||||||
static bool process_negotiation_response(
|
static bool process_negotiation_response(
|
||||||
struct smbd_response *response, int packet_length)
|
struct smbdirect_recv_io *response, int packet_length)
|
||||||
{
|
{
|
||||||
struct smbd_connection *info = response->info;
|
struct smbdirect_socket *sc = response->socket;
|
||||||
struct smbdirect_socket *sc = &info->socket;
|
struct smbd_connection *info =
|
||||||
|
container_of(sc, struct smbd_connection, socket);
|
||||||
struct smbdirect_socket_parameters *sp = &sc->parameters;
|
struct smbdirect_socket_parameters *sp = &sc->parameters;
|
||||||
struct smbdirect_negotiate_resp *packet = smbd_response_payload(response);
|
struct smbdirect_negotiate_resp *packet = smbdirect_recv_io_payload(response);
|
||||||
|
|
||||||
if (packet_length < sizeof(struct smbdirect_negotiate_resp)) {
|
if (packet_length < sizeof(struct smbdirect_negotiate_resp)) {
|
||||||
log_rdma_event(ERR,
|
log_rdma_event(ERR,
|
||||||
|
@ -391,7 +392,7 @@ static void smbd_post_send_credits(struct work_struct *work)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rc;
|
int rc;
|
||||||
struct smbd_response *response;
|
struct smbdirect_recv_io *response;
|
||||||
struct smbd_connection *info =
|
struct smbd_connection *info =
|
||||||
container_of(work, struct smbd_connection,
|
container_of(work, struct smbd_connection,
|
||||||
post_send_credits_work);
|
post_send_credits_work);
|
||||||
|
@ -442,10 +443,11 @@ static void smbd_post_send_credits(struct work_struct *work)
|
||||||
static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||||
{
|
{
|
||||||
struct smbdirect_data_transfer *data_transfer;
|
struct smbdirect_data_transfer *data_transfer;
|
||||||
struct smbd_response *response =
|
struct smbdirect_recv_io *response =
|
||||||
container_of(wc->wr_cqe, struct smbd_response, cqe);
|
container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe);
|
||||||
struct smbd_connection *info = response->info;
|
struct smbdirect_socket *sc = response->socket;
|
||||||
struct smbdirect_socket *sc = &info->socket;
|
struct smbd_connection *info =
|
||||||
|
container_of(sc, struct smbd_connection, socket);
|
||||||
int data_length = 0;
|
int data_length = 0;
|
||||||
|
|
||||||
log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
|
log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
|
||||||
|
@ -467,7 +469,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||||
switch (sc->recv_io.expected) {
|
switch (sc->recv_io.expected) {
|
||||||
/* SMBD negotiation response */
|
/* SMBD negotiation response */
|
||||||
case SMBDIRECT_EXPECT_NEGOTIATE_REP:
|
case SMBDIRECT_EXPECT_NEGOTIATE_REP:
|
||||||
dump_smbdirect_negotiate_resp(smbd_response_payload(response));
|
dump_smbdirect_negotiate_resp(smbdirect_recv_io_payload(response));
|
||||||
info->full_packet_received = true;
|
info->full_packet_received = true;
|
||||||
info->negotiate_done =
|
info->negotiate_done =
|
||||||
process_negotiation_response(response, wc->byte_len);
|
process_negotiation_response(response, wc->byte_len);
|
||||||
|
@ -477,7 +479,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||||
|
|
||||||
/* SMBD data transfer packet */
|
/* SMBD data transfer packet */
|
||||||
case SMBDIRECT_EXPECT_DATA_TRANSFER:
|
case SMBDIRECT_EXPECT_DATA_TRANSFER:
|
||||||
data_transfer = smbd_response_payload(response);
|
data_transfer = smbdirect_recv_io_payload(response);
|
||||||
data_length = le32_to_cpu(data_transfer->data_length);
|
data_length = le32_to_cpu(data_transfer->data_length);
|
||||||
|
|
||||||
if (data_length) {
|
if (data_length) {
|
||||||
|
@ -1034,7 +1036,7 @@ static int smbd_post_send_full_iter(struct smbd_connection *info,
|
||||||
* The interaction is controlled by send/receive credit system
|
* The interaction is controlled by send/receive credit system
|
||||||
*/
|
*/
|
||||||
static int smbd_post_recv(
|
static int smbd_post_recv(
|
||||||
struct smbd_connection *info, struct smbd_response *response)
|
struct smbd_connection *info, struct smbdirect_recv_io *response)
|
||||||
{
|
{
|
||||||
struct smbdirect_socket *sc = &info->socket;
|
struct smbdirect_socket *sc = &info->socket;
|
||||||
struct smbdirect_socket_parameters *sp = &sc->parameters;
|
struct smbdirect_socket_parameters *sp = &sc->parameters;
|
||||||
|
@ -1074,7 +1076,7 @@ static int smbd_negotiate(struct smbd_connection *info)
|
||||||
{
|
{
|
||||||
struct smbdirect_socket *sc = &info->socket;
|
struct smbdirect_socket *sc = &info->socket;
|
||||||
int rc;
|
int rc;
|
||||||
struct smbd_response *response = get_receive_buffer(info);
|
struct smbdirect_recv_io *response = get_receive_buffer(info);
|
||||||
|
|
||||||
sc->recv_io.expected = SMBDIRECT_EXPECT_NEGOTIATE_REP;
|
sc->recv_io.expected = SMBDIRECT_EXPECT_NEGOTIATE_REP;
|
||||||
rc = smbd_post_recv(info, response);
|
rc = smbd_post_recv(info, response);
|
||||||
|
@ -1119,7 +1121,7 @@ static int smbd_negotiate(struct smbd_connection *info)
|
||||||
*/
|
*/
|
||||||
static void enqueue_reassembly(
|
static void enqueue_reassembly(
|
||||||
struct smbd_connection *info,
|
struct smbd_connection *info,
|
||||||
struct smbd_response *response,
|
struct smbdirect_recv_io *response,
|
||||||
int data_length)
|
int data_length)
|
||||||
{
|
{
|
||||||
spin_lock(&info->reassembly_queue_lock);
|
spin_lock(&info->reassembly_queue_lock);
|
||||||
|
@ -1143,14 +1145,14 @@ static void enqueue_reassembly(
|
||||||
* Caller is responsible for locking
|
* Caller is responsible for locking
|
||||||
* return value: the first entry if any, NULL if queue is empty
|
* return value: the first entry if any, NULL if queue is empty
|
||||||
*/
|
*/
|
||||||
static struct smbd_response *_get_first_reassembly(struct smbd_connection *info)
|
static struct smbdirect_recv_io *_get_first_reassembly(struct smbd_connection *info)
|
||||||
{
|
{
|
||||||
struct smbd_response *ret = NULL;
|
struct smbdirect_recv_io *ret = NULL;
|
||||||
|
|
||||||
if (!list_empty(&info->reassembly_queue)) {
|
if (!list_empty(&info->reassembly_queue)) {
|
||||||
ret = list_first_entry(
|
ret = list_first_entry(
|
||||||
&info->reassembly_queue,
|
&info->reassembly_queue,
|
||||||
struct smbd_response, list);
|
struct smbdirect_recv_io, list);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1161,16 +1163,16 @@ static struct smbd_response *_get_first_reassembly(struct smbd_connection *info)
|
||||||
* pre-allocated in advance.
|
* pre-allocated in advance.
|
||||||
* return value: the receive buffer, NULL if none is available
|
* return value: the receive buffer, NULL if none is available
|
||||||
*/
|
*/
|
||||||
static struct smbd_response *get_receive_buffer(struct smbd_connection *info)
|
static struct smbdirect_recv_io *get_receive_buffer(struct smbd_connection *info)
|
||||||
{
|
{
|
||||||
struct smbd_response *ret = NULL;
|
struct smbdirect_recv_io *ret = NULL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&info->receive_queue_lock, flags);
|
spin_lock_irqsave(&info->receive_queue_lock, flags);
|
||||||
if (!list_empty(&info->receive_queue)) {
|
if (!list_empty(&info->receive_queue)) {
|
||||||
ret = list_first_entry(
|
ret = list_first_entry(
|
||||||
&info->receive_queue,
|
&info->receive_queue,
|
||||||
struct smbd_response, list);
|
struct smbdirect_recv_io, list);
|
||||||
list_del(&ret->list);
|
list_del(&ret->list);
|
||||||
info->count_receive_queue--;
|
info->count_receive_queue--;
|
||||||
info->count_get_receive_buffer++;
|
info->count_get_receive_buffer++;
|
||||||
|
@ -1187,7 +1189,7 @@ static struct smbd_response *get_receive_buffer(struct smbd_connection *info)
|
||||||
* receive buffer is returned.
|
* receive buffer is returned.
|
||||||
*/
|
*/
|
||||||
static void put_receive_buffer(
|
static void put_receive_buffer(
|
||||||
struct smbd_connection *info, struct smbd_response *response)
|
struct smbd_connection *info, struct smbdirect_recv_io *response)
|
||||||
{
|
{
|
||||||
struct smbdirect_socket *sc = &info->socket;
|
struct smbdirect_socket *sc = &info->socket;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1212,8 +1214,9 @@ static void put_receive_buffer(
|
||||||
/* Preallocate all receive buffer on transport establishment */
|
/* Preallocate all receive buffer on transport establishment */
|
||||||
static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
|
static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
|
||||||
{
|
{
|
||||||
|
struct smbdirect_socket *sc = &info->socket;
|
||||||
|
struct smbdirect_recv_io *response;
|
||||||
int i;
|
int i;
|
||||||
struct smbd_response *response;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&info->reassembly_queue);
|
INIT_LIST_HEAD(&info->reassembly_queue);
|
||||||
spin_lock_init(&info->reassembly_queue_lock);
|
spin_lock_init(&info->reassembly_queue_lock);
|
||||||
|
@ -1231,7 +1234,7 @@ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
|
||||||
if (!response)
|
if (!response)
|
||||||
goto allocate_failed;
|
goto allocate_failed;
|
||||||
|
|
||||||
response->info = info;
|
response->socket = sc;
|
||||||
response->sge.length = 0;
|
response->sge.length = 0;
|
||||||
list_add_tail(&response->list, &info->receive_queue);
|
list_add_tail(&response->list, &info->receive_queue);
|
||||||
info->count_receive_queue++;
|
info->count_receive_queue++;
|
||||||
|
@ -1243,7 +1246,7 @@ allocate_failed:
|
||||||
while (!list_empty(&info->receive_queue)) {
|
while (!list_empty(&info->receive_queue)) {
|
||||||
response = list_first_entry(
|
response = list_first_entry(
|
||||||
&info->receive_queue,
|
&info->receive_queue,
|
||||||
struct smbd_response, list);
|
struct smbdirect_recv_io, list);
|
||||||
list_del(&response->list);
|
list_del(&response->list);
|
||||||
info->count_receive_queue--;
|
info->count_receive_queue--;
|
||||||
|
|
||||||
|
@ -1254,7 +1257,7 @@ allocate_failed:
|
||||||
|
|
||||||
static void destroy_receive_buffers(struct smbd_connection *info)
|
static void destroy_receive_buffers(struct smbd_connection *info)
|
||||||
{
|
{
|
||||||
struct smbd_response *response;
|
struct smbdirect_recv_io *response;
|
||||||
|
|
||||||
while ((response = get_receive_buffer(info)))
|
while ((response = get_receive_buffer(info)))
|
||||||
mempool_free(response, info->response_mempool);
|
mempool_free(response, info->response_mempool);
|
||||||
|
@ -1295,7 +1298,7 @@ void smbd_destroy(struct TCP_Server_Info *server)
|
||||||
struct smbd_connection *info = server->smbd_conn;
|
struct smbd_connection *info = server->smbd_conn;
|
||||||
struct smbdirect_socket *sc;
|
struct smbdirect_socket *sc;
|
||||||
struct smbdirect_socket_parameters *sp;
|
struct smbdirect_socket_parameters *sp;
|
||||||
struct smbd_response *response;
|
struct smbdirect_recv_io *response;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
|
@ -1456,17 +1459,17 @@ static int allocate_caches_and_workqueue(struct smbd_connection *info)
|
||||||
if (!info->request_mempool)
|
if (!info->request_mempool)
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
scnprintf(name, MAX_NAME_LEN, "smbd_response_%p", info);
|
scnprintf(name, MAX_NAME_LEN, "smbdirect_recv_io_%p", info);
|
||||||
|
|
||||||
struct kmem_cache_args response_args = {
|
struct kmem_cache_args response_args = {
|
||||||
.align = __alignof__(struct smbd_response),
|
.align = __alignof__(struct smbdirect_recv_io),
|
||||||
.useroffset = (offsetof(struct smbd_response, packet) +
|
.useroffset = (offsetof(struct smbdirect_recv_io, packet) +
|
||||||
sizeof(struct smbdirect_data_transfer)),
|
sizeof(struct smbdirect_data_transfer)),
|
||||||
.usersize = sp->max_recv_size - sizeof(struct smbdirect_data_transfer),
|
.usersize = sp->max_recv_size - sizeof(struct smbdirect_data_transfer),
|
||||||
};
|
};
|
||||||
info->response_cache =
|
info->response_cache =
|
||||||
kmem_cache_create(name,
|
kmem_cache_create(name,
|
||||||
sizeof(struct smbd_response) + sp->max_recv_size,
|
sizeof(struct smbdirect_recv_io) + sp->max_recv_size,
|
||||||
&response_args, SLAB_HWCACHE_ALIGN);
|
&response_args, SLAB_HWCACHE_ALIGN);
|
||||||
if (!info->response_cache)
|
if (!info->response_cache)
|
||||||
goto out2;
|
goto out2;
|
||||||
|
@ -1756,7 +1759,7 @@ try_again:
|
||||||
int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
|
int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
|
||||||
{
|
{
|
||||||
struct smbdirect_socket *sc = &info->socket;
|
struct smbdirect_socket *sc = &info->socket;
|
||||||
struct smbd_response *response;
|
struct smbdirect_recv_io *response;
|
||||||
struct smbdirect_data_transfer *data_transfer;
|
struct smbdirect_data_transfer *data_transfer;
|
||||||
size_t size = iov_iter_count(&msg->msg_iter);
|
size_t size = iov_iter_count(&msg->msg_iter);
|
||||||
int to_copy, to_read, data_read, offset;
|
int to_copy, to_read, data_read, offset;
|
||||||
|
@ -1792,7 +1795,7 @@ again:
|
||||||
offset = info->first_entry_offset;
|
offset = info->first_entry_offset;
|
||||||
while (data_read < size) {
|
while (data_read < size) {
|
||||||
response = _get_first_reassembly(info);
|
response = _get_first_reassembly(info);
|
||||||
data_transfer = smbd_response_payload(response);
|
data_transfer = smbdirect_recv_io_payload(response);
|
||||||
data_length = le32_to_cpu(data_transfer->data_length);
|
data_length = le32_to_cpu(data_transfer->data_length);
|
||||||
remaining_data_length =
|
remaining_data_length =
|
||||||
le32_to_cpu(
|
le32_to_cpu(
|
||||||
|
|
|
@ -175,22 +175,6 @@ struct smbd_request {
|
||||||
/* Maximum number of SGEs used by smbdirect.c in any receive work request */
|
/* Maximum number of SGEs used by smbdirect.c in any receive work request */
|
||||||
#define SMBDIRECT_MAX_RECV_SGE 1
|
#define SMBDIRECT_MAX_RECV_SGE 1
|
||||||
|
|
||||||
/* The context for a SMBD response */
|
|
||||||
struct smbd_response {
|
|
||||||
struct smbd_connection *info;
|
|
||||||
struct ib_cqe cqe;
|
|
||||||
struct ib_sge sge;
|
|
||||||
|
|
||||||
/* Link to receive queue or reassembly queue */
|
|
||||||
struct list_head list;
|
|
||||||
|
|
||||||
/* Indicate if this is the 1st packet of a payload */
|
|
||||||
bool first_segment;
|
|
||||||
|
|
||||||
/* SMBD packet header and payload follows this structure */
|
|
||||||
u8 packet[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create a SMBDirect session */
|
/* Create a SMBDirect session */
|
||||||
struct smbd_connection *smbd_get_connection(
|
struct smbd_connection *smbd_get_connection(
|
||||||
struct TCP_Server_Info *server, struct sockaddr *dstaddr);
|
struct TCP_Server_Info *server, struct sockaddr *dstaddr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue