mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
ceph: issue a cap release immediately if no cap exists
In case:
mds client
- Releases cap and put Inode
- Increase cap->seq and sends
revokes req to the client
- Receives release req and - Receives & drops the revoke req
skip removing the cap and
then eval the CInode and
issue or revoke caps again.
- Receives & drops the caps update
or revoke req
- Health warning for client
isn't responding to
mclientcaps(revoke)
All the IMPORT/REVOKE/GRANT cap ops will increase the session seq
in MDS side and then the client need to issue a cap release to
unblock MDS to remove the corresponding cap to unblock possible
waiters.
Link: https://tracker.ceph.com/issues/61332
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Milind Changire <mchangir@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
@@ -4092,6 +4092,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
|
||||
struct cap_extra_info extra_info = {};
|
||||
bool queue_trunc;
|
||||
bool close_sessions = false;
|
||||
bool do_cap_release = false;
|
||||
|
||||
dout("handle_caps from mds%d\n", session->s_mds);
|
||||
|
||||
@@ -4198,17 +4199,14 @@ void ceph_handle_caps(struct ceph_mds_session *session,
|
||||
if (!inode) {
|
||||
dout(" i don't have ino %llx\n", vino.ino);
|
||||
|
||||
if (op == CEPH_CAP_OP_IMPORT) {
|
||||
cap = ceph_get_cap(mdsc, NULL);
|
||||
cap->cap_ino = vino.ino;
|
||||
cap->queue_release = 1;
|
||||
cap->cap_id = le64_to_cpu(h->cap_id);
|
||||
cap->mseq = mseq;
|
||||
cap->seq = seq;
|
||||
cap->issue_seq = seq;
|
||||
spin_lock(&session->s_cap_lock);
|
||||
__ceph_queue_cap_release(session, cap);
|
||||
spin_unlock(&session->s_cap_lock);
|
||||
switch (op) {
|
||||
case CEPH_CAP_OP_IMPORT:
|
||||
case CEPH_CAP_OP_REVOKE:
|
||||
case CEPH_CAP_OP_GRANT:
|
||||
do_cap_release = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto flush_cap_releases;
|
||||
}
|
||||
@@ -4258,6 +4256,14 @@ void ceph_handle_caps(struct ceph_mds_session *session,
|
||||
inode, ceph_ino(inode), ceph_snap(inode),
|
||||
session->s_mds);
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
switch (op) {
|
||||
case CEPH_CAP_OP_REVOKE:
|
||||
case CEPH_CAP_OP_GRANT:
|
||||
do_cap_release = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto flush_cap_releases;
|
||||
}
|
||||
|
||||
@@ -4308,6 +4314,18 @@ flush_cap_releases:
|
||||
* along for the mds (who clearly thinks we still have this
|
||||
* cap).
|
||||
*/
|
||||
if (do_cap_release) {
|
||||
cap = ceph_get_cap(mdsc, NULL);
|
||||
cap->cap_ino = vino.ino;
|
||||
cap->queue_release = 1;
|
||||
cap->cap_id = le64_to_cpu(h->cap_id);
|
||||
cap->mseq = mseq;
|
||||
cap->seq = seq;
|
||||
cap->issue_seq = seq;
|
||||
spin_lock(&session->s_cap_lock);
|
||||
__ceph_queue_cap_release(session, cap);
|
||||
spin_unlock(&session->s_cap_lock);
|
||||
}
|
||||
ceph_flush_cap_releases(mdsc, session);
|
||||
goto done;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user