sheep: port list_splice_tail_init() from linux kernel

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: make requests with new epoch sleep until epoch is updated

If requests comes with epoch newer than system epoch, then
we shouldn't just make it done with result SD_RES_NEW_NODE_VER,
if so, the sender would busy retrying this request, which may
casue CPU too busy to process other request.

We push the requests with new epoch into a wait_epoch_queue to
make it wait for epoch consistency, after epoch changes we wake
up these requests in the queue, which avoids busy retrying.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: make gateway to retry when received SD_RES_OLD_NODE_VER

When gateway requests get SD_RES_OLD_NODE_VER in io_op_done(),
it means epoch of gateway is older than peer, and peer has set
response's epoch with its system epoch, then gateway should check
whether its system epoch has reach peer's system epoch which in
req->rp.epoch, and whether the result is SD_RES_OLD_NODE_VER,
if so, the request should be pushed into wait_epoch_queue to
wait until system epoch change, but if system epoch has reached
peer's system epoch, retry this request at once.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
recovery: make IO request to wait when recovery is in RW_INIT

When recovery is in RW_INIT state, the IO request would be
marked as recovering, then the sender will busy retrying,
we should make the request wait until recovery enters RW_RUN
state to determine whether the object requested is in recovery
instead of just return SD_RES_NEW_NODE_VER.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
recovery: make IO request to wait when the requested object is in recovery

When an object requested is in recovery, we should put it into
the wait_obj_queue to make the request wait until the object is
recovered by the recovery work.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
recovery: clear the object wait queue when new recovery work comes

When a new recovery work replaces the old one, we should
clear the waiting requests in the wait_obj_queue to make
them retry for the new work, or else, the requests in the
queue may never be waked up.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
recovery: fix a race condition in recovery

Take consider of this scene:

Node A and B are in recovery
A is recovering object x from B,
and object x hasn't been recovered by B.
B is recovering object y from A,
and object y hasn't been recovered by A.

Then B will response A with result SD_RES_NEW_NODE_VER, and
A will also response B with result SD_RES_NEW_NODE_VER, then
A and B will continually retry to recover object x and y, but always
get an response SD_RES_NEW_NODE_VER, neither success, so here's a
dead lock which stops the recovery from completing.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: make gateway requests only retry when requested object is local

We should not make gateway retry in check_request when the
requested object in recovery is not local, in the case of requesting a
non-local object we should make it retry in io_op_done(), if the
requesting object is local, then we should make the gateway request
to retry.

Signed-off-by: levin li <xingke.lwp@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>