summaryrefslogtreecommitdiffstats
path: root/xlators/nfs
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2011-03-15 01:53:41 +0000
committerAnand Avati <avati@gluster.com>2011-04-11 01:37:32 -0700
commit4248b4e501abd647e337328944778b447dc5a34d (patch)
tree766288e2b72bb0bec5a6f7ecaf869b848db6ab47 /xlators/nfs
parent7b368061eaf15cf8b6e8adc3506b5baabdc466e8 (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
Diffstat (limited to 'xlators/nfs')
-rw-r--r--xlators/nfs/lib/src/rpc-socket.c6
-rw-r--r--xlators/nfs/lib/src/rpc-socket.h2
-rw-r--r--xlators/nfs/lib/src/rpcsvc.c17
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