summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiels de Vos <ndevos@redhat.com>2014-09-25 12:08:47 +0200
committerKaleb KEITHLEY <kkeithle@redhat.com>2014-09-25 03:56:56 -0700
commitab0547eba39b155246f0d9f09e9a580665c6053f (patch)
treeaef0c39fd5fad3c9b8f6d3ccf036d69f6a828c6f
parente2a76e76e3d9174fa77f40f3abd0212705283f00 (diff)
socket: Fixed parsing RPC records containing multi fragments
In __socket_proto_state_machine(), when parsing RPC records containing multi fragments, just change the state of parsing process, had not processed the memory to coalesce the multi fragments. Cherry picked from commit fb6702b7f8ba19333b7ba4af543d908e3f5e1923: > Change-Id: I5583e578603bd7290814a5d26885b31759c73115 > BUG: 1139598 > Signed-off-by: Gu Feng <flygoast@126.com> > Reviewed-on: http://review.gluster.org/8662 > Tested-by: Gluster Build System <jenkins@build.gluster.com> > Reviewed-by: Niels de Vos <ndevos@redhat.com> > Reviewed-by: Raghavendra G <rgowdapp@redhat.com> > Tested-by: Raghavendra G <rgowdapp@redhat.com> Change-Id: I5583e578603bd7290814a5d26885b31759c73115 BUG: 1146470 Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/8849 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
-rw-r--r--rpc/rpc-transport/socket/src/socket.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c
index 943071b34a7..c2e6d730209 100644
--- a/rpc/rpc-transport/socket/src/socket.c
+++ b/rpc/rpc-transport/socket/src/socket.c
@@ -382,10 +382,11 @@ __socket_cached_read (rpc_transport_t *this, struct iovec *opvector, int opcount
/* first call after passing SP_STATE_READING_FRAGHDR */
in->ra_max = min (RPC_FRAGSIZE (in->fraghdr), GF_SOCKET_RA_MAX);
/* Note that the in->iobuf is the primary iobuf into which
- headers are read into. By using this itself as our
+ headers are read into, and in->frag.fragcurrent points to
+ some position in the buffer. By using this itself as our
read-ahead cache, we can avoid memory copies in iov_load
*/
- in->ra_buf = iobuf_ptr (in->iobuf);
+ in->ra_buf = in->frag.fragcurrent;
}
/* fill read-ahead */
@@ -1987,9 +1988,22 @@ __socket_proto_state_machine (rpc_transport_t *this,
goto out;
}
+ if (in->iobuf == NULL) {
+ /* first fragment */
+ frag->fragcurrent = iobuf_ptr (iobuf);
+ } else {
+ /* second or further fragment */
+ memcpy(iobuf_ptr (iobuf), iobuf_ptr (in->iobuf),
+ in->total_bytes_read - RPC_FRAGSIZE(in->fraghdr));
+ iobuf_unref (in->iobuf);
+ frag->fragcurrent = (char *) iobuf_ptr (iobuf) +
+ in->total_bytes_read - RPC_FRAGSIZE(in->fraghdr);
+ frag->pending_vector->iov_base = frag->fragcurrent;
+ in->pending_vector = frag->pending_vector;
+ }
+
in->iobuf = iobuf;
in->iobuf_size = 0;
- frag->fragcurrent = iobuf_ptr (iobuf);
in->record_state = SP_STATE_READING_FRAG;
/* fall through */
@@ -2004,6 +2018,9 @@ __socket_proto_state_machine (rpc_transport_t *this,
frag->bytes_read = 0;
if (!RPC_LASTFRAG (in->fraghdr)) {
+ in->pending_vector = in->vector;
+ in->pending_vector->iov_base = &in->fraghdr;
+ in->pending_vector->iov_len = sizeof(in->fraghdr);
in->record_state = SP_STATE_READING_FRAGHDR;
break;
}