After Locker::issue_new_caps() adds new Capability data struct,
do not issue caps immediately. Let CInode::encode_inodestate()
do the job instead. This can avoid various races that early reply
is not allowed, caps that haven't been sent to client gets revoked.
Fixes: http://tracker.ceph.com/issues/19635
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit
799703a4acb49db0b6cc99a23e4326767e694c3a)
<< " wanted " << ccap_string(wanted)
<< dendl;
- // skip if suppress, and not revocation
- if (cap->is_suppress() && !(pending & ~allowed)) {
- dout(20) << " suppressed and !revoke, skipping client." << it->first << dendl;
- continue;
+ if (!(pending & ~allowed)) {
+ // skip if suppress or new, and not revocation
+ if (cap->is_new() || cap->is_suppress()) {
+ dout(20) << " !revoke and new|suppressed, skipping client." << it->first << dendl;
+ continue;
+ }
}
// notify clients about deleted inode, to make sure they release caps ASAP.
newi->filelock.set_state(LOCK_EXCL);
newi->authlock.set_state(LOCK_EXCL);
newi->xattrlock.set_state(LOCK_EXCL);
- cap->issue_norevoke(CEPH_CAP_AUTH_EXCL|CEPH_CAP_AUTH_SHARED|
- CEPH_CAP_XATTR_EXCL|CEPH_CAP_XATTR_SHARED|
- CEPH_CAP_ANY_FILE_WR);
}
}
newi->filelock.set_state(LOCK_EXCL);
newi->authlock.set_state(LOCK_EXCL);
newi->xattrlock.set_state(LOCK_EXCL);
- cap->issue_norevoke(CEPH_CAP_AUTH_EXCL|CEPH_CAP_AUTH_SHARED|
- CEPH_CAP_XATTR_EXCL|CEPH_CAP_XATTR_SHARED);
}
// make sure this inode gets into the journal