]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
mds: do remove the cap when seqs equal or larger than last issue 58294/head
authorXiubo Li <xiubli@redhat.com>
Thu, 11 Apr 2024 01:53:04 +0000 (09:53 +0800)
committerPatrick Donnelly <pdonnell@redhat.com>
Wed, 26 Jun 2024 18:01:48 +0000 (14:01 -0400)
commitabb79bcc44fd8670210c882fa4e5f8986eac3cf6
treea997909c0d47af99684df4d3f9879640378d8889
parent98c31c1ac4a1afb24e2179b554f89c5e40efdfb0
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)
src/mds/Locker.cc