diff options
Diffstat (limited to 'xlators/nfs')
-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 |