more
authorStefan Metzmacher <metze@samba.org>
Thu, 6 Oct 2016 06:25:05 +0000 (08:25 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 1 Jun 2018 12:35:19 +0000 (14:35 +0200)
libcli/smb/smb_direct.c

index c5c2dff771853e27734395f0ae328ac5e3140eeb..4b309a3b9551a2ac60ad24edbc353dd5f4d992e6 100644 (file)
@@ -81,6 +81,7 @@ struct smb_direct_connection {
                uint16_t receive_credit_target;
                uint16_t receive_credits;
                uint32_t keep_alive_internal;
+               bool send_immediate;
        } state;
        struct {
                int tmp_fd; /* given to the caller end */
@@ -646,7 +647,7 @@ smb_direct_connection_debug_credits(c, "POST_SEND", io, __location__, __func__);
 
        return 0;
 }
-
+#if 0
 static int smb_direct_connection_post_io(struct smb_direct_connection *c)
 {
        int ret;
@@ -673,14 +674,19 @@ static int smb_direct_connection_post_io(struct smb_direct_connection *c)
 
        return 0;
 }
-
-static int smb_direct_connection_post_keep(struct smb_direct_connection *c)
+#endif
+static int smb_direct_connection_post_io(struct smb_direct_connection *c)
 {
        struct smb_direct_io *io = NULL;
        int ret;
+       bool need_keepalive = false;
 
-DEBUG(0,("%s:%s: KEEP posted[%p] ready[%p] idle[%p]\n",
-       __location__, __func__, c->s2r.posted, c->s2r.ready, c->s2r.idle));
+DEBUG(0,("%s:%s: IO "
+       "s2r posted[%p] ready[%p] idle[%p] in[%p] remaining[%u] "
+       "r2s posted[%p] ready[%p] idle[%p] out[%p] remaining[%u]\n",
+       __location__, __func__,
+       c->s2r.posted, c->s2r.ready, c->s2r.idle, c->s2r.in, c->s2r.remaining_length,
+       c->r2s.posted, c->r2s.ready, c->r2s.idle, c->r2s.out, c->r2s.remaining_length));
 
        errno = 0;
        ret = smb_direct_connection_post_recv(c);
@@ -692,38 +698,46 @@ DEBUG(0,("%s:%s: KEEP posted[%p] ready[%p] idle[%p]\n",
                return ret;
        }
 
-smb_direct_connection_debug_credits(c, "post_keep", NULL, __location__, __func__);
+       if (c->state.send_immediate) {
+               need_keepalive = true;
+       }
 
-       if (c->s2r.posted != NULL) {
+       if (need_keepalive && c->s2r.posted != NULL) {
 DEBUG(0,("%s:%s: KEEP skip...(posted)\n", __location__, __func__));
-               return 0;
+               need_keepalive = false;
+       }
+
+       if (c->state.receive_credits == 0) {
+               need_keepalive = true;
        }
 
-       if (c->state.receive_posted == 0) {
+       if (need_keepalive && c->state.receive_posted == 0) {
 DEBUG(0,("%s:%s: KEEP skip...(no RECV posted)\n", __location__, __func__));
-               return 0;
+               need_keepalive = false;
        }
 
-       if (c->s2r.ready != NULL) {
+       if (need_keepalive && c->s2r.ready != NULL) {
 DEBUG(0,("%s:%s: KEEP skip...(ready)\n", __location__, __func__));
-               return 0;
+               need_keepalive = false;
        }
 
-       if (c->s2r.idle == NULL) {
+       if (need_keepalive && c->s2r.idle == NULL) {
 DEBUG(0,("%s:%s: KEEP skip...(no idle)\n", __location__, __func__));
-               return 0;
+               need_keepalive = false;
        }
 
 //DEBUG(0,("%s:%s: here...\n", __location__, __func__));
-       io = c->s2r.idle;
-       DLIST_REMOVE(c->s2r.idle, io);
+       if (need_keepalive) {
+               io = c->s2r.idle;
+               DLIST_REMOVE(c->s2r.idle, io);
 
-       io->data_length = 0;
-       io->remaining_length = 0;
+               io->data_length = 0;
+               io->remaining_length = 0;
 
-       DLIST_ADD_END(c->s2r.ready, io);
+               DLIST_ADD_END(c->s2r.ready, io);
+       }
 
-smb_direct_connection_debug_credits(c, "POST_KEEP", io, __location__, __func__);
+//smb_direct_connection_debug_credits(c, "POST_KEEP", io, __location__, __func__);
        ret = smb_direct_connection_post_send(c);
        if (ret != 0) {
                NTSTATUS status;
@@ -734,6 +748,12 @@ smb_direct_connection_debug_credits(c, "POST_KEEP", io, __location__, __func__);
        }
 //DEBUG(0,("%s:%s: here...\n", __location__, __func__));
 
+       if (c->state.send_immediate) {
+               if (c->s2r.posted != NULL) {
+                       c->state.send_immediate = false;
+               }
+       }
+
        return 0;
 }
 static int smb_direct_connection_setup_readv(struct smb_direct_connection *c)
@@ -2371,7 +2391,8 @@ try_again:
                }
 
                if (flags & SMB_DIRECT_RESPONSE_REQUESTED) {
-                       ret = smb_direct_connection_post_keep(c);
+                       c->state.send_immediate = true;
+                       ret = smb_direct_connection_post_io(c);
                        if (ret != 0) {
                                status = map_nt_error_from_unix_common(errno);
                                DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -2382,7 +2403,7 @@ try_again:
                }
 
                if (c->state.receive_credits == 0) {
-                       ret = smb_direct_connection_post_keep(c);
+                       ret = smb_direct_connection_post_io(c);
                        if (ret != 0) {
                                status = map_nt_error_from_unix_common(errno);
                                DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -2426,6 +2447,12 @@ static bool smb_direct_connection_sock_handler_writable(
 more:
        if (c->r2s.out != NULL) {
                io = c->r2s.out;
+                               DEBUG(0,("%s:%s: CONTINUE[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
        } else {
                io = c->r2s.ready;
                if (io != NULL) {
@@ -2435,13 +2462,27 @@ more:
        }
 
        if (io == NULL) {
+               DBG_DEBUG("TEVENT_FD_NOT_READABLE\n");
                TEVENT_FD_NOT_WRITEABLE(c->sock.fde);
                return true;
        }
 
+                               DEBUG(0,("%s:%s: WRITEV[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
        sret = writev(c->sock.fd, io->iov, io->iov_count);
        if (sret == -1) {
                if (errno == EAGAIN) {
+                               DEBUG(0,("%s:%s: EAGAIN WRITEV[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
+                       DBG_DEBUG("readv returned EAGAIN\n");
                        TEVENT_FD_WRITEABLE(c->sock.fde);
                        return true;
                }
@@ -2458,11 +2499,23 @@ more:
        }
 
        if (io->iov_count == 0) {
+                               DEBUG(0,("%s:%s: done WRITEV[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
                c->r2s.out = NULL;
                DLIST_ADD_END(c->r2s.idle, io);
                goto more;
        }
 
+                               DEBUG(0,("%s:%s: remain WRITEV[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
        return true;
 }
 
@@ -2528,7 +2581,14 @@ next_read:
        sret = readv(c->sock.fd, io->iov, io->iov_count);
        if (sret == -1) {
                if (errno == EAGAIN) {
+                               DEBUG(0,("%s:%s: EAGAIN READV[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
                        DBG_DEBUG("readv returned EAGAIN\n");
+                       TEVENT_FD_READABLE(c->sock.fde);
                        return true;
                }
                return false;
@@ -2547,6 +2607,13 @@ next_read:
 
        if (io->iov_count != 0) {
                /* Wait for more data */
+                               DEBUG(0,("%s:%s: more READV[%p] io->data_length[%u] io->remaining_length[%u] io->iov_count[%u] io->iov[0].iov_len[%u]\n",
+                                        __location__, __func__, io,
+                                        (unsigned)io->data_length,
+                                        (unsigned)io->remaining_length,
+                                        (unsigned)io->iov_count,
+                                        (unsigned)io->iov[0].iov_len));
+                       TEVENT_FD_READABLE(c->sock.fde);
                return true;
        }