We should call Locker:eval() for all imported inodes who have non-zero
'wanted caps'. MDS does not properly handle following case.
- client open a inode for read, it send a cap message to MDS.a (the cap
message updates 'wanted caps')
- MDS.a receive the cap message, the inode is non-auth and is ambiguous
auth. MDS.a can not request 'wanted caps' from auth mds.
- MDS.a finishes importing the inode from. But no caps are imported and
mds_caps_wanted map is empty.
The bug can cause read hang.
Fixes: http://tracker.ceph.com/issues/22357
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
if (auth_cap)
::decode(in->get_mds_caps_wanted(), blp);
if (!cap_map.empty() ||
- (auth_cap && !in->get_mds_caps_wanted().empty())) {
+ (auth_cap && (in->get_caps_wanted() & ~CEPH_CAP_PIN))) {
peer_exports[in].swap(cap_map);
in->get(CInode::PIN_IMPORTINGCAPS);
}