From 497532ef7e5c4361ac6c2c76fe5f2d209b986953 Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Tue, 5 Jun 2012 13:45:39 -0700 Subject: rpc-transport/socket: fix the state machine for XDATA reading The socket state machine was broken for reading XDATA on the server. This code was structured such that when there was a partial read in a particular state, some variables would remain uninitialized in the next 'run' of the state machine. Also did some re-org of the state machine with two more states to make the code more readable and similar in state-breakup pattern to the other states. Change-Id: Ia32c78d4b9567bb08c6df8dc9fd6f05749d312a4 BUG: 829062 Signed-off-by: Anand Avati Reviewed-on: http://review.gluster.com/3524 Reviewed-by: Amar Tumballi Tested-by: Gluster Build System Reviewed-by: Jeff Darcy --- rpc/rpc-transport/socket/src/socket.c | 44 ++++++++++++++++++++++++++--------- rpc/rpc-transport/socket/src/socket.h | 7 ++++++ 2 files changed, 40 insertions(+), 11 deletions(-) (limited to 'rpc/rpc-transport') diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index cf30e7d7d..0fee6cb41 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -815,7 +815,6 @@ __socket_read_vectored_request (rpc_transport_t *this, rpcsvc_vector_sizer vecto uint32_t remaining_size = 0; ssize_t readsize = 0; size_t size = 0; - char *proghdr_buf = NULL; GF_VALIDATE_OR_GOTO ("socket", this, out); GF_VALIDATE_OR_GOTO ("socket", this->private, out); @@ -872,10 +871,13 @@ __socket_read_vectored_request (rpc_transport_t *this, rpcsvc_vector_sizer vecto case SP_STATE_READ_VERFBYTES: sp_state_read_verfbytes: - proghdr_buf = priv->incoming.frag.fragcurrent; + /* set the base_addr 'persistently' across multiple calls + into the state machine */ + priv->incoming.proghdr_base_addr = priv->incoming.frag.fragcurrent; + priv->incoming.frag.call_body.request.vector_sizer_state = vector_sizer (priv->incoming.frag.call_body.request.vector_sizer_state, - &readsize, proghdr_buf, + &readsize, priv->incoming.proghdr_base_addr, priv->incoming.frag.fragcurrent); __socket_proto_init_pending (priv, readsize); priv->incoming.frag.call_body.request.vector_state @@ -885,21 +887,41 @@ sp_state_read_verfbytes: case SP_STATE_READING_PROGHDR: __socket_proto_read (priv, ret); -sp_state_reading_proghdr: + priv->incoming.frag.call_body.request.vector_state = + SP_STATE_READ_PROGHDR; + + /* fall through */ + + case SP_STATE_READ_PROGHDR: +sp_state_read_proghdr: priv->incoming.frag.call_body.request.vector_sizer_state = vector_sizer (priv->incoming.frag.call_body.request.vector_sizer_state, - &readsize, proghdr_buf, + &readsize, + priv->incoming.proghdr_base_addr, priv->incoming.frag.fragcurrent); if (readsize == 0) { priv->incoming.frag.call_body.request.vector_state = - SP_STATE_READ_PROGHDR; - } else { - __socket_proto_init_pending (priv, readsize); - __socket_proto_read (priv, ret); - goto sp_state_reading_proghdr; + SP_STATE_READ_PROGHDR_XDATA; + goto sp_state_read_proghdr_xdata; } - case SP_STATE_READ_PROGHDR: + __socket_proto_init_pending (priv, readsize); + + priv->incoming.frag.call_body.request.vector_state = + SP_STATE_READING_PROGHDR_XDATA; + + /* fall through */ + + case SP_STATE_READING_PROGHDR_XDATA: + __socket_proto_read (priv, ret); + + priv->incoming.frag.call_body.request.vector_state = + SP_STATE_READ_PROGHDR; + /* check if the vector_sizer() has more to say */ + goto sp_state_read_proghdr; + + case SP_STATE_READ_PROGHDR_XDATA: +sp_state_read_proghdr_xdata: if (priv->incoming.payload_vector.iov_base == NULL) { size = RPC_FRAGSIZE (priv->incoming.fraghdr) - diff --git a/rpc/rpc-transport/socket/src/socket.h b/rpc/rpc-transport/socket/src/socket.h index 6d6802a54..0304f1db1 100644 --- a/rpc/rpc-transport/socket/src/socket.h +++ b/rpc/rpc-transport/socket/src/socket.h @@ -72,6 +72,12 @@ typedef enum { SP_STATE_READ_VERFBYTES, /* read verifier data */ SP_STATE_READING_PROGHDR, SP_STATE_READ_PROGHDR, + SP_STATE_READING_PROGHDR_XDATA, + SP_STATE_READ_PROGHDR_XDATA, /* It's a bad "name" in the generic + RPC state machine, but greatly + aids code review (and xdata is + the only "consumer" of this state) + */ SP_STATE_READING_PROG, } sp_rpcfrag_vectored_request_state_t; @@ -165,6 +171,7 @@ typedef struct { sp_rpcfrag_simple_msg_state_t simple_state; sp_rpcfrag_state_t state; } frag; + char *proghdr_base_addr; struct iobuf *iobuf; size_t iobuf_size; struct iovec vector[2]; -- cgit