Message ID | 20230618231011.9077-1-xiubli@redhat.com |
---|---|
State | New |
Headers | show |
Series | ceph: issue a cap release immediately if no cap exists | expand |
Looks good to me. Reviewed-by: Milind Changire <mchangir@redhat.com> On Mon, Jun 19, 2023 at 4:42 AM <xiubli@redhat.com> wrote: > > From: Xiubo Li <xiubli@redhat.com> > > 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. > > URL: https://tracker.ceph.com/issues/61332 > Signed-off-by: Xiubo Li <xiubli@redhat.com> > --- > fs/ceph/caps.c | 40 +++++++++++++++++++++++++++++----------- > 1 file changed, 29 insertions(+), 11 deletions(-) > > diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c > index 5498bc36c1e7..59ab5d905ac4 100644 > --- a/fs/ceph/caps.c > +++ b/fs/ceph/caps.c > @@ -4232,6 +4232,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); > > @@ -4349,17 +4350,14 @@ void ceph_handle_caps(struct ceph_mds_session *session, > else > 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; > } > @@ -4413,6 +4411,14 @@ void ceph_handle_caps(struct ceph_mds_session *session, > pr_info("%s: no cap on %p ino %llx:%llx from mds%d for flush_ack!\n", > __func__, inode, ceph_ino(inode), > ceph_snap(inode), session->s_mds); > + switch (op) { > + case CEPH_CAP_OP_REVOKE: > + case CEPH_CAP_OP_GRANT: > + do_cap_release = true; > + break; > + default: > + break; > + } > goto flush_cap_releases; > } > > @@ -4467,6 +4473,18 @@ void ceph_handle_caps(struct ceph_mds_session *session, > * 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; > > -- > 2.40.1 >
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 5498bc36c1e7..59ab5d905ac4 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -4232,6 +4232,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); @@ -4349,17 +4350,14 @@ void ceph_handle_caps(struct ceph_mds_session *session, else 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; } @@ -4413,6 +4411,14 @@ void ceph_handle_caps(struct ceph_mds_session *session, pr_info("%s: no cap on %p ino %llx:%llx from mds%d for flush_ack!\n", __func__, inode, ceph_ino(inode), ceph_snap(inode), session->s_mds); + switch (op) { + case CEPH_CAP_OP_REVOKE: + case CEPH_CAP_OP_GRANT: + do_cap_release = true; + break; + default: + break; + } goto flush_cap_releases; } @@ -4467,6 +4473,18 @@ void ceph_handle_caps(struct ceph_mds_session *session, * 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;