]> git.apps.os.sepia.ceph.com Git - ceph.git/commit
mds: do remove the cap when seqs equal or larger than last issue 58296/head
authorXiubo Li <xiubli@redhat.com>
Thu, 11 Apr 2024 01:53:04 +0000 (09:53 +0800)
committerPatrick Donnelly <pdonnell@redhat.com>
Mon, 30 Sep 2024 14:47:00 +0000 (10:47 -0400)
commit3ea5c50829d0ca80016af8c6f26119cc42d8c22f
treecbe412f9abccd66f3d24e86c45dd5175d0183983
parent113192a488e41f88d9e230b9f01a70d1ae2a438c
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