diff options
| author | Shehjar Tikoo <shehjart@gluster.com> | 2011-03-15 01:53:41 +0000 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-04-11 01:37:32 -0700 | 
| commit | 4248b4e501abd647e337328944778b447dc5a34d (patch) | |
| tree | 766288e2b72bb0bec5a6f7ecaf869b848db6ab47 | |
| parent | 7b368061eaf15cf8b6e8adc3506b5baabdc466e8 (diff) | |
nfs-rpc: Exit txbuf transmission loop on EAGAIN
..instead of looping till the buffer is completely transmitted.
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2491 ([glusterfs-3.1.3qa4]: iozone fails due to data corruption)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2491
| -rw-r--r-- | xlators/nfs/lib/src/rpc-socket.c | 6 | ||||
| -rw-r--r-- | xlators/nfs/lib/src/rpc-socket.h | 2 | ||||
| -rw-r--r-- | xlators/nfs/lib/src/rpcsvc.c | 17 | 
3 files changed, 19 insertions, 6 deletions
diff --git a/xlators/nfs/lib/src/rpc-socket.c b/xlators/nfs/lib/src/rpc-socket.c index 6c399d90416..ec56f3fc49e 100644 --- a/xlators/nfs/lib/src/rpc-socket.c +++ b/xlators/nfs/lib/src/rpc-socket.c @@ -226,7 +226,7 @@ nfs_rpcsvc_socket_read (int sockfd, char *readaddr, size_t readsize)  ssize_t -nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size) +nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size, int *eagain)  {          size_t          writelen = -1;          ssize_t         written = 0; @@ -240,8 +240,10 @@ nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size)                          if (errno != EAGAIN) {                                  written = -1;                                  break; -                        } else +                        } else { +                                *eagain = 1;                                  break; +                        }                  } else if (writelen == 0)                          break; diff --git a/xlators/nfs/lib/src/rpc-socket.h b/xlators/nfs/lib/src/rpc-socket.h index 0f91729774f..8662df0a741 100644 --- a/xlators/nfs/lib/src/rpc-socket.h +++ b/xlators/nfs/lib/src/rpc-socket.h @@ -49,7 +49,7 @@ extern ssize_t  nfs_rpcsvc_socket_read (int sockfd, char *readaddr, size_t readsize);  extern ssize_t -nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size); +nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size, int *eagain);  extern int  nfs_rpcsvc_socket_peername (int sockfd, char *hostname, int hostlen); diff --git a/xlators/nfs/lib/src/rpcsvc.c b/xlators/nfs/lib/src/rpcsvc.c index 363b94fbe13..3f6e3b9f0ea 100644 --- a/xlators/nfs/lib/src/rpcsvc.c +++ b/xlators/nfs/lib/src/rpcsvc.c @@ -2555,6 +2555,7 @@ __nfs_rpcsvc_conn_data_poll_out (rpcsvc_conn_t *conn)          ssize_t                 written = -1;          char                    *writeaddr = NULL;          size_t                  writesize = -1; +        int                     eagain = 0;          if (!conn)                  return -1; @@ -2562,6 +2563,7 @@ __nfs_rpcsvc_conn_data_poll_out (rpcsvc_conn_t *conn)          /* Attempt transmission of each of the pending buffers */          list_for_each_entry_safe (txbuf, tmp, &conn->txbufs, txlist) {  tx_remaining: +                eagain = 0;                  writeaddr = (char *)(txbuf->buf.iov_base + txbuf->offset);                  writesize = (txbuf->buf.iov_len - txbuf->offset); @@ -2571,7 +2573,7 @@ tx_remaining:                  }                  written = nfs_rpcsvc_socket_write (conn->sockfd, writeaddr, -                                                   writesize); +                                                   writesize, &eagain);                  if (txbuf->txbehave & RPCSVC_TXB_LAST) {                          gf_log (GF_RPCSVC, GF_LOG_TRACE, "Last Tx Buf");                          nfs_rpcsvc_socket_unblock_tx (conn->sockfd); @@ -2600,12 +2602,21 @@ tx_remaining:                          list_del (&txbuf->txlist);                          mem_put (conn->txpool, txbuf); -                } else +                } else {                          /* If the current buffer is incompletely tx'd, do not                           * go to the head of the loop, since that moves us to                           * the next buffer. +                         * +                         * BUT, if the current transmission exited due to EAGAIN +                         * we need to leave the buffers where they are and come +                         * back later for retransmission.                           */ -                        goto tx_remaining; +                        if (!eagain) +                                goto tx_remaining; +                        else +                                break; +                } +          }          /* If we've broken out of the loop above then we must unblock  | 
