mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3 0/3] ceph: don't unregister an MDS session before removing its caps
@ 2026-08-28 17:45 Max Kellermann
  2026-08-28 17:45 ` [PATCH v3 1/3] ceph/mds_client: pin sessions while checking a new MDS map Max Kellermann
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Max Kellermann @ 2026-08-28 17:45 UTC (permalink / raw)
  To: idryomov, amarkuze, xiubo.li, ceph-devel, linux-kernel; +Cc: Max Kellermann

handle_session() removed the session from mdsc->sessions[] at the very
top of `CEPH_SESSION_CLOSE` handling, before taking `s_mutex`.
Between session unregistration and remove_session_caps(), the MDS rank
has no registered session while the old session still owns all caps it
was granted.

Any concurrent filesystem operation may walk into that and the next
__do_request() call registers a new session for this rank.  Once it is
open and the MDS issues caps, ceph_fill_inode() calls
ceph_add_cap(), which looks caps up by rank, not
by session identity, finding old caps linked to the old session.

The list_move_tail() call then moves the cap object to the new
session, which is already a bad thing to do.  Since it doesn't
decrement `old_session->s_nr_caps`, this will quickly run into a BUG()
instead of crashing:

  kernel BUG at fs/ceph/mds_client.c:1959!
  Internal error: Oops - BUG: 00000000f2000800 [#1]  SMP
  [...]
  Workqueue: ceph-msgr ceph_con_workfn
  pstate: 20400009 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : remove_session_caps+0x2bc/0x2d8
  lr : remove_session_caps+0x74/0x2d8
  [...]
  Call trace:
   remove_session_caps+0x2bc/0x2d8 (P)
   mds_dispatch+0xf48/0x1b60
   ceph_con_process_message+0x74/0xa0
   ceph_con_v1_try_read+0x3a0/0x1510
   ceph_con_workfn+0x260/0x460
   process_one_work+0x168/0x3b8
   worker_thread+0x1bc/0x3a0
   kthread+0x118/0x1e0
   ret_from_fork+0x10/0x20

That's BUG_ON(session->s_nr_caps > 0).

I was able to reproduce this reliably by delaying the close and
starting I/O during the delay.

This patch keeps the session registered with
`CEPH_MDS_SESSION_CLOSED`.  New requests will be put on the
`s_waiting` list where they will be resumed on the new session.

Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
v1->v2: skip CLOSED sessions in check_new_map()
v2->v3: split session pinning and stale-map guards into two preparatory
    patches; rework CLOSED-session and export-target teardown handling

Max Kellermann (3):
  ceph/mds_client: pin sessions while checking a new MDS map
  ceph/mds_client: stop checking a stale MDS map after dropping mutex
  ceph: don't unregister an MDS session before removing its caps

 fs/ceph/caps.c       |   3 +
 fs/ceph/mds_client.c | 164 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 150 insertions(+), 17 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-28 17:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-28 17:45 [PATCH v3 0/3] ceph: don't unregister an MDS session before removing its caps Max Kellermann
2026-08-28 17:45 ` [PATCH v3 1/3] ceph/mds_client: pin sessions while checking a new MDS map Max Kellermann
2026-08-28 17:45 ` [PATCH v3 2/3] ceph/mds_client: stop checking a stale MDS map after dropping mutex Max Kellermann
2026-08-28 17:45 ` [PATCH v3 3/3] ceph: don't unregister an MDS session before removing its caps Max Kellermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®