#include <rdma/rdma_cma.h>
#include <infiniband/verbs.h>
+#define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
+
struct smb_direct_io;
struct smb_direct_connection {
- struct tevent_context *last_ev;
+ const void *last_ev;
struct {
uint32_t max_send_size;
uint32_t max_receive_size;
io = smb_direct_io_create(c);
if (io == NULL) {
TALLOC_FREE(c);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: SETUP r2s here...\n", __location__, __func__));
return NULL;
}
DLIST_ADD_END(c->r2s.idle, io);
+DEBUG(0,("%s:%s: SETUP r2s here...\n", __location__, __func__));
}
for (i = 0; i < c->state.send_credit_target; i++) {
io = smb_direct_io_create(c);
if (io == NULL) {
TALLOC_FREE(c);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: SETUP s2r here...\n", __location__, __func__));
return NULL;
}
DLIST_ADD_END(c->s2r.idle, io);
+DEBUG(0,("%s:%s: SETUP s2r here...\n", __location__, __func__));
}
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
if (c->r2s.idle == NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return 0;
}
struct ibv_send_wr *bad_send_wr = NULL;
int ret;
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
if (c->s2r.ready == NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return 0;
}
if (c->state.send_credits == 0) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return 0;
}
+#if 0
if (1) {
+DEBUG(0,("%s:%s: TODO: REMOVE me ...here...\n", __location__, __func__));
return 0;
}
+#endif
for (io = c->s2r.ready; io != NULL; io = next) {
uint16_t granted = 0;
c->state.send_credits -= 1;
if (c->state.send_credits == 0) {
- flags |= 0x0001;
+ flags |= SMB_DIRECT_RESPONSE_REQUESTED;
}
granted = c->state.receive_credit_max;
granted -= c->state.receive_credits;
granted = MIN(granted, c->state.receive_credit_target);
c->state.receive_credits += granted;
+// if (c->state.receive_credits == 0) {
+// granted = 1;
+// c->state.receive_credits += granted;
+// }
if (io->data_length > 0) {
data_offset = 0x18;
SIVAL(io->smbd_hdr, 0x10, io->data_length);
SIVAL(io->smbd_hdr, 0x14, 0x00000000);
- if (next == NULL) {
+ if (next != NULL) {
io->send_wr.next = &next->send_wr;
} else {
io->send_wr.next = NULL;
last->send_wr.next = NULL;
errno = 0;
- ret = ibv_post_send(c->ibv.qp, &c->s2r.ready->send_wr, &bad_send_wr);
+ ret = ibv_post_send(c->ibv.qp, &posted->send_wr, &bad_send_wr);
if (ret != 0) {
NTSTATUS status;
// DLIST_CONCATENATE(c->s2r.ready, posted); // TODO: check bad_send_wr
return 0;
}
+static int smb_direct_connection_post_keep(struct smb_direct_connection *c)
+{
+ struct smb_direct_io *io = NULL;
+ int ret;
+
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ if (c->s2r.posted != NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ return 0;
+ }
+
+ if (c->s2r.ready != NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ return 0;
+ }
+
+ if (c->s2r.idle == NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ return 0;
+ }
+
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ io = c->s2r.idle;
+ DLIST_REMOVE(c->s2r.idle, io);
+
+ io->data_length = 0;
+ io->remaining_length = 0;
+
+ DLIST_ADD_END(c->s2r.ready, io);
+
+ ret = smb_direct_connection_post_send(c);
+ if (ret != 0) {
+ NTSTATUS status;
+ status = map_nt_error_from_unix_common(errno);
+ DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
+ __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+ return ret;
+ }
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+
+ return 0;
+}
static int smb_direct_connection_setup_readv(struct smb_direct_connection *c)
{
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
TEVENT_FD_READABLE(c->sock.fde);
// TODO: immediate_event?? may skips a syscall.
return 0;
static int smb_direct_connection_setup_writev(struct smb_direct_connection *c)
{
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
TEVENT_FD_WRITEABLE(c->sock.fde);
// TODO: immediate_event?? may skips a syscall.
return 0;
c->r2s.remaining_length -= io->data_length;
- if (io->remaining_length != c->r2s.remaining_length) {
+ // Like this???
+ if (io->remaining_length > c->r2s.remaining_length) {
status = NT_STATUS_INVALID_NETWORK_RESPONSE;
DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
__location__, __FUNCTION__, ret, errno, nt_errstr(status)));
}
if (c->state.receive_credits == 0) {
- // TODO: send more credits
- status = map_nt_error_from_unix_common(errno);
- DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
- __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
- smb_direct_connection_disconnect(c, status);
- return;
+ ret = smb_direct_connection_post_keep(c);
+ if (ret != 0) {
+ status = map_nt_error_from_unix_common(errno);
+ DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
+ __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+ smb_direct_connection_disconnect(c, status);
+ return;
+ }
}
- if (flags & ~0x0001) {
+ if (flags & ~SMB_DIRECT_RESPONSE_REQUESTED) {
status = map_nt_error_from_unix_common(errno);
DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
__location__, __FUNCTION__, ret, errno, nt_errstr(status)));
return;
}
- if (flags & 0x0001) {
- // TODO: send more credits
- status = map_nt_error_from_unix_common(errno);
- DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
- __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
- smb_direct_connection_disconnect(c, status);
- return;
+ if (flags & SMB_DIRECT_RESPONSE_REQUESTED) {
+ ret = smb_direct_connection_post_keep(c);
+ if (ret != 0) {
+ status = map_nt_error_from_unix_common(errno);
+ DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
+ __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+ smb_direct_connection_disconnect(c, status);
+ return;
+ }
}
DLIST_ADD_END(c->r2s.ready, io);
int ret;
bool ok;
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
do_write:
if (fde_flags & TEVENT_FD_WRITE) {
if (c->r2s.out != NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->r2s.out;
} else {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->r2s.ready;
- DLIST_REMOVE(c->r2s.ready, io);
- c->r2s.out = io;
+ if (io != NULL) {
+ DLIST_REMOVE(c->r2s.ready, io);
+ c->r2s.out = io;
+ }
}
if (io != NULL) {
ssize_t sret;
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
sret = writev(c->sock.fd, io->iov, io->iov_count);
if (sret == -1) {
if (errno == EAGAIN) { // and more...
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
TEVENT_FD_WRITEABLE(c->sock.fde);
goto done_write;
}
if (io->iov_count == 0) {
c->r2s.out = NULL;
DLIST_ADD_END(c->r2s.idle, io);
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
goto do_write;
}
} else {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
TEVENT_FD_NOT_WRITEABLE(c->sock.fde);
}
}
done_write:
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
ret = smb_direct_connection_post_recv(c);
if (ret != 0) {
status = map_nt_error_from_unix_common(errno);
do_read:
if (fde_flags & TEVENT_FD_READ) {
if (c->s2r.in != NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->s2r.in;
} else {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->s2r.idle;
- DLIST_REMOVE(c->s2r.idle, io);
- c->s2r.in = io;
+ if (io != NULL) {
+ DLIST_REMOVE(c->s2r.idle, io);
+ c->s2r.in = io;
- if (c->s2r.remaining_length > 0) {
- /*
- * We need to continue to get
- * the incomplete packet.
- */
- io->data_length = MIN(sizeof(io->data),
- c->s2r.remaining_length);
- io->remaining_length = c->s2r.remaining_length;
- io->remaining_length -= io->data_length;
- c->s2r.remaining_length = io->remaining_length;
-
- io->iov = io->_iov_array;
- io->iov[0].iov_base = io->data;
- io->iov[0].iov_len = io->data_length;
- io->iov_count = 1;
- } else {
- /*
- * For a new packet we need to get the length
- * first.
- */
- io->data_length = 0;
- io->remaining_length = 0;
+ if (c->s2r.remaining_length > 0) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ /*
+ * We need to continue to get
+ * the incomplete packet.
+ */
+ io->data_length = MIN(sizeof(io->data),
+ c->s2r.remaining_length);
+ io->remaining_length = c->s2r.remaining_length;
+ io->remaining_length -= io->data_length;
+ c->s2r.remaining_length = io->remaining_length;
+
+ io->iov = io->_iov_array;
+ io->iov[0].iov_base = io->data;
+ io->iov[0].iov_len = io->data_length;
+ io->iov_count = 1;
+ } else {
+ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ /*
+ * For a new packet we need to get the length
+ * first.
+ */
+ io->data_length = 0;
+ io->remaining_length = 0;
- io->iov = io->_iov_array;
- io->iov[0].iov_base = io->nbt_hdr;
- io->iov[0].iov_len = sizeof(io->nbt_hdr);
- io->iov_count = 1;
+ io->iov = io->_iov_array;
+ io->iov[0].iov_base = io->nbt_hdr;
+ io->iov[0].iov_len = sizeof(io->nbt_hdr);
+ io->iov_count = 1;
+ }
}
}
if (io != NULL) {
ssize_t sret;
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
sret = readv(c->sock.fd, io->iov, io->iov_count);
if (sret == -1) {
if (errno == EAGAIN) { // and more...
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
TEVENT_FD_READABLE(c->sock.fde);
- goto do_read;
+ goto done_read;
}
status = map_nt_error_from_unix_common(errno);
if (io->iov_count == 0) {
if (io->data_length != 0) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
/*
* We managed to read the whole fragment
* which is ready to be posted into the
* send queue.
*/
c->s2r.in = NULL;
- DLIST_ADD_END(c->r2s.ready, io);
+ DLIST_ADD_END(c->s2r.ready, io);
goto do_read;
}
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
c->s2r.remaining_length = smb_len_tcp(io->nbt_hdr);
if (c->s2r.remaining_length > c->state.max_fragmented_size) { //correct direction
status = NT_STATUS_INVALID_BUFFER_SIZE;
/*
* try to read the reset immediately.
*/
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
goto do_read;
}
} else {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
TEVENT_FD_NOT_READABLE(c->sock.fde);
}
}
+ done_read:
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
ret = smb_direct_connection_post_send(c);
if (ret != 0) {
status = map_nt_error_from_unix_common(errno);
{
uint16_t sock_fde_flags = TEVENT_FD_READ;
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
if (c->r2s.out != NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
sock_fde_flags |= TEVENT_FD_WRITE;
}
TALLOC_FREE(c->sock.fde);
TALLOC_FREE(c->ibv.fde_channel);
TALLOC_FREE(c->rdma.fde_channel);
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
}
if (tevent_fd_get_flags(c->rdma.fde_channel) == 0) {
TALLOC_FREE(c->sock.fde);
TALLOC_FREE(c->ibv.fde_channel);
TALLOC_FREE(c->rdma.fde_channel);
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
}
if (ev == NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
c->last_ev = NULL;
TALLOC_FREE(c->sock.fde);
TALLOC_FREE(c->ibv.fde_channel);
TALLOC_FREE(c->rdma.fde_channel);
- } else if (ev == c->last_ev) {
return NT_STATUS_OK;
- } else if (c->last_ev == NULL) {
- /* fallthrough */
- } else {
+ }
+
+ if (ev == c->last_ev) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ return NT_STATUS_OK;
+ }
+
+ if (c->last_ev != NULL) {
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return NT_STATUS_INVALID_PARAMETER_MIX;
}
return NT_STATUS_NO_MEMORY;
}
+DEBUG(0,("%s:%s: here...\n", __location__, __func__));
c->last_ev = ev;
return NT_STATUS_OK;
}