mds: do remove the cap when seqs equal or larger than last issue
There is a race in case of:
MDS rw Client
- Issue the 'Asx' caps to
rw client
- Adds the cap, then removes it
later by queuing it to the cap
release list. But the cap->seq
may have been updated by previous
cap grant requests.
And the cap grant request won't
increase the 'last_issue' seq in
MDS.
- ro client's lookup
request comes and the
MDS sends a 'Ax' caps
revoke request to rw
client by increasing
the 'seq'.
- The revoke request just finds
that the cap doesn't exist, then
queues a new cap release
immediately with the new 'seq'.
Then trigger to flush the pending
cap releases to MDS.
- Just receives the cap
release request but the
'seq' > cap's 'last_issue',
then MDS will skip
removing the cap. And
then the _do_cap_release()
will issue the 'Ax' caps
back to rw client.
Then wakes up the ro
client's lookup request,
while the lookup request
will try to revoke the
'Ax' caps again from the
rw client.
This will cause a spinlock infinitely in mds side.
Fixes: https://tracker.ceph.com/issues/64977
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit
345978e7607e227854ccc78b066b274b97940391)