Check before allocating

Avoid useless allocation/free in a loop by delaying allocation
until we know we need the memory.

Signed-off-by: Shevek <shevek@anarres.org>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
Easier to grep for PANIC calls

Add PANIC to all panic formats, to make logs easier to grep.
All fmt parameters should be string constants, so this concatenation
is always valid.

Signed-off-by: Shevek <shevek@anarres.org>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
Rebracket unregister_event calls in group.c

Fixes the pairing of register_event and unregister_event on the
cluster driver file descriptor. It now (coincidentally) matches the
assignments to event_running.

There were several code paths where either a duplicate unregister
could happen, or no work would be queued, so the file descriptor
would never be re-registered.

Signed-off-by: Shevek <shevek@anarres.org>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: bug in event_done leads to dead lock

Dead lock was found in the following scenario:

Suppose that there are two sheeps: S1, S2, and their event_queues
are empty.

Now S1 received a notify message: M1, and call sd_notify_handler()
which will add notify event to its event_queue and than call
process_request_event_queues() to queue_work this event.

At the same time, S2 send a notify message: M2 to cluster and an
I/O request(eg. do_lookup_vdi operation) was submitted to S1 when
S2 calls zk_dispatch() to handle M2.

After S1 received I/O request from S2, it would finally call
process_request_event_queues() to deal with this event, if S1 call
this function before M1's event_done() finished, this I/O request
would not to be processed for the event_queue was not empty. This
problem leads to dead lock between S1 and S2, S2 would be blocked
in read() waitting for the data responsed by S1, and the whole cluster
would be suspended forever.

To fix this problem, we just modify the code in event_done, so that
it can process request_queue after event_queue is empty.

Signed-off-by: Yunkai Zhang <qiushu.zyk@taobao.com>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: cleanup is_access_local

All callers have a struct request that is used for various arguments,
so pass it directly.  Also mark the function static given that is has
no callers outside of sdnet.c.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: cleanup io_op_done

Use a switch statement to make checking of the various error returns more
readable, use a goto label for the common retry code, and split the data
object consistency checking into a function of its own.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: remove setup_ordered_sd_vnode_list

There is little value to a function that has two callers, where one of
them only needs half of it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: rewrite the vnode mapping layer

Rewrite vnode mapping by making the structure containing the
<vnodes,nr_vnodes,nr_zones> tuple a first class citizen and passing it
around to all places that deal with vnodes.  This in turn also allows
getting rid of the list of these structures, as we can simply create
one at each epoch change and reference count it.

This also uncovered a nasty bug where queue_request called
setup_access_to_local_objects before the vnode-related fields in
the request were set up.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: add a oid_to_vnode helper

Abstract away mapping from a oid to a vnode into a new helper instead
of calling obj_to_sheep directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: add a vnode_is_local helper

Add a helper to check if a given vnode is local to shorten the repeated
calls to is_myself.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: cleanup nr_copies handling

Add a new get_nr_copies helper to consolidate calculating the number of
copies of an object that we need to deal with.  As a side effect this
allows making struct vnode_info private to group.c again.

There are a few places that take a different number of copies from the
inode or the on the wire header.  These look incorrect to me, but I'd
like to have some review of those.  These places should be either
documented or removed ASAP.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: rename nr_sobjs to nr_copies

nr_sobjs is an extremly confusing name for the number of copies in the
cluster, so let's rename it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: rewrite get_max_copies using get_zones_nr_from

Also document it and rename it to get_max_nr_copies_from to avoid confusion
with get_nr_copies.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>
sheep: fix get_zones_nr_from for clusters with gateways

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Liu Yuan <tailai.ly@taobao.com>