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 <avati@redhat.com>
Reviewed-on: http://review.gluster.com/3524
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
This commit is contained in:
Anand Avati 2012-06-05 13:45:39 -07:00
parent 990bc3991a
commit 497532ef7e
2 changed files with 40 additions and 11 deletions

View File

@ -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) -

View File

@ -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];