Whamcloud - gitweb
- landing of b_hd_cleanup_merge to HEAD.
[fs/lustre-release.git] / lnet / ulnds / tcplnd.c
index 1041d1d..6e9cca9 100644 (file)
  *
  * sends a packet to the peer, after insuring that a connection exists
  */
-int tcpnal_send(nal_cb_t *n,
-               void *private,
-               lib_msg_t *cookie,
-               ptl_hdr_t *hdr,
-               int type,
-               ptl_nid_t nid,
-               ptl_pid_t pid,
-                unsigned int niov,
-                struct iovec *iov,
-               size_t len)
+ptl_err_t tcpnal_send(lib_nal_t *n,
+                      void *private,
+                      lib_msg_t *cookie,
+                      ptl_hdr_t *hdr,
+                      int type,
+                      ptl_nid_t nid,
+                      ptl_pid_t pid,
+                      unsigned int niov,
+                      struct iovec *iov,
+                      size_t offset,
+                      size_t len)
 {
     connection c;
-    bridge b=(bridge)n->nal_data;
+    bridge b=(bridge)n->libnal_data;
     struct iovec tiov[257];
     static pthread_mutex_t send_lock = PTHREAD_MUTEX_INITIALIZER;
-    int   rc;
+    ptl_err_t rc = PTL_OK;
+    int   sysrc;
     int   total;
+    int   ntiov;
     int i;
 
     if (!(c=force_tcp_connection((manager)b->lower,
                                  PNAL_IP(nid,b),
-                                 PNAL_PORT(nid,pid)))) 
-        return(1);
+                                 PNAL_PORT(nid,pid),
+                                 b->local)))
+        return(PTL_FAIL);
 
-#if 0
     /* TODO: these results should be checked. furthermore, provision
        must be made for the SIGPIPE which is delivered when
        writing on a tcp socket which has closed underneath
        the application. there is a linux flag in the sendmsg
        call which turns off the signally behaviour, but its
        nonstandard */
-    syscall(SYS_write, c->fd,hdr,sizeof(ptl_hdr_t));
-    LASSERT (niov <= 1);
-    if (len) syscall(SYS_write, c->fd,iov[0].iov_base,len);
-#else
+
     LASSERT (niov <= 256);
 
     tiov[0].iov_base = hdr;
     tiov[0].iov_len = sizeof(ptl_hdr_t);
+    ntiov = 1 + lib_extract_iov(256, &tiov[1], niov, iov, offset, len);
 
-    if (niov > 0)
-            memcpy(&tiov[1], iov, niov * sizeof(struct iovec));
     pthread_mutex_lock(&send_lock);
 #if 1
-    for (i = total = 0; i <= niov; i++)
+    for (i = total = 0; i < ntiov; i++)
             total += tiov[i].iov_len;
     
-    rc = syscall(SYS_writev, c->fd, tiov, niov+1);
-    if (rc != total) {
+    sysrc = syscall(SYS_writev, c->fd, tiov, ntiov);
+    if (sysrc != total) {
             fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
                      rc, total, errno);
-            abort();
+            rc = PTL_FAIL;
     }
 #else
-    for (i = total = 0; i <= niov; i++) {
+    for (i = total = 0; i <= ntiov; i++) {
             rc = send(c->fd, tiov[i].iov_base, tiov[i].iov_len, 0);
             
             if (rc != tiov[i].iov_len) {
                     fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
                              rc, tiov[i].iov_len, errno);
-                    abort();
+                    rc = PTL_FAIL;
+                    break;
             }
-            total != rc;
+            total += rc;
     }
 #endif
 #if 0
@@ -130,15 +130,19 @@ int tcpnal_send(nal_cb_t *n,
              total, niov + 1);
 #endif
     pthread_mutex_unlock(&send_lock);
-#endif
-    lib_finalize(n, private, cookie);
-        
-    return(0);
+
+    if (rc == PTL_OK) {
+            /* NB the NAL only calls lib_finalize() if it returns PTL_OK
+             * from cb_send() */
+            lib_finalize(n, private, cookie, PTL_OK);
+    }
+
+    return(rc);
 }
 
 
 /* Function:  tcpnal_recv
- * Arguments: nal_cb_t *nal:     pointer to my nal control block
+ * Arguments: lib_nal_t *nal:    pointer to my nal control block
  *            void *private:     connection pointer passed through
  *                               lib_parse()
  *            lib_msg_t *cookie: passed back to portals library
@@ -150,15 +154,18 @@ int tcpnal_send(nal_cb_t *n,
  * blocking read of the requested data. must drain out the
  * difference of mainpulated and requested lengths from the network
  */
-int tcpnal_recv(nal_cb_t *n,
-               void *private,
-               lib_msg_t *cookie,
-                unsigned int niov,
-                struct iovec *iov,
-               size_t mlen,
-               size_t rlen)
+ptl_err_t tcpnal_recv(lib_nal_t *n,
+                      void *private,
+                      lib_msg_t *cookie,
+                      unsigned int niov,
+                      struct iovec *iov,
+                      size_t offset,
+                      size_t mlen,
+                      size_t rlen)
 
 {
+    struct iovec tiov[256];
+    int ntiov;
     int i;
 
     if (!niov)
@@ -168,16 +175,19 @@ int tcpnal_recv(nal_cb_t *n,
     LASSERT(rlen);
     LASSERT(rlen >= mlen);
 
+    ntiov = lib_extract_iov(256, tiov, niov, iov, offset, mlen);
+    
     /* FIXME
      * 1. Is this effecient enough? change to use readv() directly?
      * 2. need check return from read_connection()
      * - MeiJia
      */
-    for (i = 0; i < niov; i++)
-        read_connection(private, iov[i].iov_base, iov[i].iov_len);
+    for (i = 0; i < ntiov; i++)
+        read_connection(private, tiov[i].iov_base, tiov[i].iov_len);
 
 finalize:
-    lib_finalize(n, private, cookie);
+    /* FIXME; we always assume success here... */
+    lib_finalize(n, private, cookie, PTL_OK);
 
     if (mlen!=rlen){
         char *trash=malloc(rlen-mlen);
@@ -187,7 +197,7 @@ finalize:
         free(trash);
     }
 
-    return(rlen);
+    return(PTL_OK);
 }
 
 
@@ -207,7 +217,8 @@ static int from_connection(void *a, void *d)
     ptl_hdr_t hdr;
 
     if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
-        lib_parse(b->nal_cb, &hdr, c);
+        lib_parse(b->lib_nal, &hdr, c);
+        /*TODO: check error status*/
         return(1);
     }
     return(0);
@@ -229,19 +240,19 @@ int tcpnal_init(bridge b)
 {
     manager m;
         
-    b->nal_cb->cb_send=tcpnal_send;
-    b->nal_cb->cb_recv=tcpnal_recv;
+    b->lib_nal->libnal_send=tcpnal_send;
+    b->lib_nal->libnal_recv=tcpnal_recv;
     b->shutdown=tcpnal_shutdown;
     
-    if (!(m=init_connections(PNAL_PORT(b->nal_cb->ni.nid,
-                                       b->nal_cb->ni.pid),
+    if (!(m=init_connections(PNAL_PORT(b->lib_nal->libnal_ni.ni_pid.nid,
+                                       b->lib_nal->libnal_ni.ni_pid.pid),
                              from_connection,b))){
         /* TODO: this needs to shut down the
            newly created junk */
         return(PTL_NAL_FAILED);
     }
     /* XXX cfs hack */
-    b->nal_cb->ni.pid=0;
+//    b->lib_nal->libnal_ni.ni_pid.pid=0;
     b->lower=m;
     return(PTL_OK);
 }