mds: handle interaction between slave rollback and fragmenting

For slave rename and rmdir events, the MDS needs to preserve non-auth
dirfrag where the renamed inode originally lives in until slave commit
event is encountered. Current method to handle this is use MDCache::
uncommitted_slave_rename_olddir to track any non-auth dirfrag that
need to be preserved. This method does not works well if any preserved
dirfrag gets fragmented by log event (such as ESubtreeMap) between the
slave prepare event and the slave commit event.

The fix is tracking inode of dirfrag instead of tracking dirfrag that
need to preserved directly.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: handle race between cache rejoin and fragmenting

MDCache::handle_cache_expire() ignores mismatched dirfrags. this is
OK during normal operation because MDS doesn't trim replica inode
whose dirfrags are likely being fragmented (see commit 22535340).

During recovery, the recovering MDS can reveive survivor MDS' cache
expire message before it sends cache rejoin acks. In this case,
there still can be mismatched dirfrags, but nothing prevents the
survivor MDS to trim inode of these mismatched dirfrags. So there
can be unconnected dirfrags when the recovering MDS sends cache
rejoin acks.

The fix is, when mismatched dirfrag is encountered during recovery,
check if inode of the dirfrag is still replicated to the sender MDS.
If the inode is not replicated, remove the sender MDS from replica
maps of all child dirfrags.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: avoid journaling non-auth opened inode

Inode that is being renamed can have AUTH bit set, but is attached
to non-auth subtree.

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

make sure CDir::WAIT_ANY_MASK include MDSCacheObject::WAIT_UNFREEZE

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix how to preserve COMPLETE flag for fragment rollback

commit 6e013cd6 (properly set COMPLETE flag when merging dirfrags)
tries solving the issue that new dirfrag's COMPLETE flag gets lost
if the dirfrag gets fragmented, then the fragment operation gets
rolled back. It records if the original dirfrag is complete when
EFragment::OP_PREPARE event is encountered. If the fragment operation
is rolled back later, The complete flag is journaled in corresponding
EFragment::OP_ROLLBACK event. This is problematic when the PREPARE
and ROLLBACK events are in different log segments. The dirfrag can be
not complete if only the ROLLBACK event exists (the log segment that
contains PREPARE event is trimmed)

The fix is do not journal the complete flag in ROLLBACK event. The
COMPLETE flag is saved when replaying EFragment::PREPARE event. Later
when the EFragment::ROLLBACK event is encountered, COMPLETE flag is
restored.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: properly journal fragment rollback

If dirfrags are subtree roots, mark the dirfragtreelock as scattered
dirty, otherwise journal the dirfragtree change.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: trim non-auth inode with remote parents

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: trim empty non-auth dirfrags

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: don't trim ambiguous import dirfrags

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

return NULL if there is no opened dirfrag

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: journal EFragment::OP_COMMIT before drop locks

Dropping locks can dispatch other requests. These request can submit
log entry.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix null pointer dereference in MDCache::rejoin_send_rejoins()

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: skip non-opened session when flushing client sessions

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: explicitly set nonce for imported dirfrag

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: don't clear scatter dirty when cache rejoin ack is received

The auth mds has received dirty scatterlock state. But it hasn't
journaled the dirty state yet. The log segment that marked the
scatterlock dirty need to be preserved. Therefore, we can't clear
the dirty flag of scatterlock.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: avoid journaling non-auth opened inode

The exporting inode has AUTH bit set while EExport event is being
journaled.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix stack overflow caused by nested dispatch

Commit bc3325b37 fixes a stack overflow bug happens when replaying
client requests. Similar stack overflow can happens when processing
finished contexts.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix negative dirstat assertion

When splitting dirfrag, delta dirstat is always added to the first new
dirfrag. Before the delta dirstat is propagated to inode, unlinking file
from the rest dirfrags can cause nagtive inode dirstat.

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