mds: freeze tree deadlock detection.

there are two situations that result freeze tree deadlock.

 - mds.0 authpins an item in subtree A
 - mds.0 sends request to mds.1 to authpin an item in subtree B
 - mds.0 freezes subtree A
 - mds.1 authpins an item in subtree B
 - mds.1 sends request to mds.0 to authpin an item in subtree A
 - mds.1 freezes subtree B
 - mds.1 receives the remote authpin request from mds.0
   (wait because subtree B is freezing)
 - mds.0 receives the remote authpin request from mds.1
   (wait because subtree A is freezing)

 - client request authpins items in subtree B
 - freeze subtree B
 - import subtree A which is parent of subtree B
   (authpins parent inode of subtree B, see CDir::set_dir_auth())
 - freeze subtree A
 - client request tries authpinning items in subtree A
   (wait because subtree A is freezing)

Enforcing a authpinning order can avoid the deadlock, but it's very
expensive. The deadlock is rare, so I think deadlock detection is
more suitable for the case.

This patch introduces freeze tree deadlock detection. We record the
start time of freezing tree. If we fail to freeze the tree within a
given duration, cancel the process of freezing tree.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: put import/export related states together

Current code uses several STL maps to record import/export related
states. A map lookup is required for each state access, this is not
efficient. It's better to put import/export related states together.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: rework stale import/export message detection

Current code uses import state to detect obsolete import/export messages.
it does not work for the case: cancel a subtree export, export the same
subtree again, the messages for the first export get dispatched.

This patch introduces "transation ID" for subtree exports. Each subtree
export has a unique TID, the ID is recorded in all import/export related
messages. By comparing the TID, we can reliably detect stale messages.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: unify nonce type

MDSCacheObject::replica_nonce is defined as __s16, but nonce type
in MDSCacheObject::replica_map is int. This mismatch may confuse
MDCache::handle_cache_expire().

this patch unifies the nonce type as uint32

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: handle cache rejoin corner case

A recovering MDS may receives strong cache rejoin from a survivor,
then the survivor restarts, the recovering MDS receives week cache
rejoin from the same MDS. Before processing the week cache rejoin,
we should scour replicas added by the obsoleted strong cache rejoin.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: process delayed expire if exporting dir cancelled in warnning state

we may add delayed expire when exporting dir is in warnning state

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: merge delayed cache expire

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix empty directory check

Since commit 310032ee81(fix mds scatter_writebehind starvation), rdlock
a scatter lock does not always propagate dirty fragstats to corresponding
inode. So Server::_dir_is_nonempty() needs to check each dirfrag's stat
intead of checking inode's dirstat.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: re-send discover if want_xlocked becomes true

If want_xlocked becomes true, we can not rely on previously sent discover
because it's likely the previous discover is blocked on the xlocked dentry.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix rename notify

commit 1d86f77edf (mds: fix cross-authorty rename race) introduced
rename notify, but it puts the code in wrong bracket.

This patch also fixes a rename notify related bug in
MDCache::handle_mds_failure()

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: avoid issuing caps when inode is frozen

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: re-issue caps after importing inode

After importing inode, the issued caps can be less than the caps
client wants. So always re-issue caps after importing inode.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: avoid leaving bare-bone dirfrags in the cache

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: keep dentry lock in sync state

unlike locks of other types, dentry lock in unreadable state can
block path traverse, so it should be in sync state as much as
possible.

This patch make Locker::try_eval() change dentry lock's state to
sync even when the dentry is freezing. Also make migrator check
imported dentries' lock states, change locks' states to sync if
necessary.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix sending resolve message

need to send resolve message when mds is in reconnect state

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: don't request CEPH_CAP_PIN from auth mds

avoid triggering assert(in->get_loner() >= 0 && in->mds_caps_wanted.empty())
in Locker::file_xsyn()

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: check lock state before eval_gather

Locker::eval_gather() can dispatch requests, which may change other
locks' states.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: waiting for slave reuqest to finish

If MDS receives a client request, but find there is an existing
slave request. It's possible that other MDS forwarded the request
to us, but the MMDSSlaveRequest::OP_FINISH message arrives after
the client request.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: avoid allocating MDRequest::More when cleanup request

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: flush session messages before exporting caps

Following sequence of events can happen when exporting inodes:

- client sends open file request to mds.0
- mds.0 handles the request and sends inode stat back to the client
- mds.0 export the inode to mds.1
- mds.1 sends cap import message to the client
- mds.0 sends cap export message to the client
- client receives the cap import message from mds.1, but the client
  still doesn't have corresponding inode in the cache. So the client
  releases the imported caps.
- client receives the open file reply from mds.0
- client receives the cap export message from mds.0.

After the end of these events, the client doesn't have any cap for
the opened file.

To fix the message ordering issue, this patch introduces a new session
operation FLUSHMSG. Before exporting caps, we send a FLUSHMSG seesion
message to client and wait for the acknowledgment. When receiveing the
FLUSHMSG_ACK message from client, we are sure that clients have received
all messages sent previously.