mds: delete orphan dirfrags if fragmentating directory fails

Record orphan dirfrags in EFragment::OP_COMMIT and EFragment::OP_ROLLBACK
events. Also introduce a new event EFragment::OP_FINISH, which indicates
that all orphan dirfrags are deleted. During MDS revovers, retry deleting
orphan dirfrags for unfinished EFragment:{OP_COMMIT/OP_ROLLBACK} events.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: trim log segment after finishing uncommitted fragments

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: properly store fragmenting dirfrags

fragmenting dirfrag does not exist on the object store. So all non-null
dentries should be included when committing a fragmenting dirfrag.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: properly update rstat/fragstat when fragmentating directory

The stale rstat/dirstat check in CDir::merge() is wrong. dirfrag's
rstat/fragstat is stale if the accounted rstat/fragstat version isn't
equal to inode's rstat/dirstat version.

For CDir::split(), no need to worry about if the rstat/fragstat of the
origin dirfrag is stale. If it's stale, the rstat/fragstat of the
resulting dirfrags are stale too.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: don't fragmentate stray directory

the code that prepares stray dentry assumes that stray inode contains
single dirfrag and we never freeze the stray inode's dirfrag.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: fix MDCache::merge_dir()

fragment 'bits' should be negative for the merging case.

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

make sure it return true when all dirfrags under the given frag_t
are found.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
mds: handle dirfrag mismatch when processing readdir request

If client has outdated dirfrags information, readdir request from
it may specify a non-existing dirfrag. Current method to handle this
case is reply -EAGAIN and let client retry. When client receives the
the -EAGAIN reply, it need to refresh its dirfrags information first,
then re-send the readdir request.

A better way to handle client request that specify a non-existing
dirfrag is: MDS chooses a approximate dirfrag, then handle the request
like normal. When client receives the readdir reply, it will also
update its dirfrags information.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
client: use dir_result_t::END as flag

So we don't lose the latest readdir frag and offset after marking
end of readdir.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
client: handle dirfrag mismatch when processing readdir reply

If client has outdated directory fragments information, it may request
readdir an non-existent directory fragment. In this case, the MDS finds
an approximate directory fragment and sends its contents back to the
client. When receiving a reply with fragment that is different than the
requested one, the client need to reset the 'readdir offset'.

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