diff options
| author | Anand Avati <avati@redhat.com> | 2012-06-05 13:45:39 -0700 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-06-06 11:41:40 -0700 | 
| commit | 497532ef7e5c4361ac6c2c76fe5f2d209b986953 (patch) | |
| tree | 43b3e622e3f3b3ed2557b9740ae467e585ba951f /rpc | |
| parent | 990bc3991a0a998dc74d43250fed40ad1f72e849 (diff) | |
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>
Diffstat (limited to 'rpc')
| -rw-r--r-- | rpc/rpc-transport/socket/src/socket.c | 44 | ||||
| -rw-r--r-- | rpc/rpc-transport/socket/src/socket.h | 7 | 
2 files changed, 40 insertions, 11 deletions
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];  | 
