From: Max Kellermann <max.kellermann@ionos.com>
To: idryomov@gmail.com, amarkuze@redhat.com,
ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Max Kellermann <max.kellermann@ionos.com>
Subject: [PATCH v2 3/4] fs/ceph/caps: mark cap remove with RB_CLEAR_NODE() instead of ci=NULL
Date: Mon, 6 Jul 2026 09:38:11 +0200 [thread overview]
Message-ID: <20260706073812.3922732-3-max.kellermann@ionos.com> (raw)
In-Reply-To: <20260706073812.3922732-1-max.kellermann@ionos.com>
__ceph_remove_cap() erases the ceph_cap object from the RB tree, thus
it seems natural to use RB_CLEAR_NODE() / RB_EMPTY_NODE() for the
removal check.
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
v1->v2:
- move code to new patch "add helper function ceph_cap_is_removed()"
- add locking documentation to ceph_cap.ci_node
- fix data race by calling RB_CLEAR_NODE() under s_cap_lock
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
fs/ceph/caps.c | 7 +++++--
fs/ceph/super.h | 16 ++++++++++++++--
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index f6f3e817b712..a6a59bc91b79 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1157,8 +1157,11 @@ static void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
cap->session = NULL;
removed = 1;
}
- /* protect backpointer with s_cap_lock: see iterate_session_caps */
- cap->ci = NULL;
+
+ /* protect removal marker with both i_ceph_lock and
+ s_cap_lock, so either one can be used to check for
+ removal */
+ RB_CLEAR_NODE(&cap->ci_node);
/*
* s_cap_reconnect is protected by s_cap_lock. no one changes
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 628d153601a5..509839c1db0b 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -203,7 +203,19 @@ struct ceph_fs_client {
*/
struct ceph_cap {
struct ceph_inode_info *ci;
- struct rb_node ci_node; /* per-ci cap tree */
+
+ /**
+ * Per-ci cap tree. Protected with
+ * `ceph_inode_info.i_ceph_lock`.
+ *
+ * Clearing this field with RB_CLEAR_NODE() requires holding
+ * both `ceph_inode_info.i_ceph_lock` and
+ * `ceph_mds_session->s_cap_lock`. Calling RB_EMPTY_NODE()
+ * (via ceph_cap_is_removed()) requires holding at least one
+ * of these.
+ */
+ struct rb_node ci_node;
+
struct ceph_mds_session *session;
struct list_head session_caps; /* per-session caplist */
u64 cap_id; /* unique cap id (mds provided) */
@@ -1280,7 +1292,7 @@ extern void ceph_add_cap(struct inode *inode,
*/
static inline bool ceph_cap_is_removed(const struct ceph_cap *cap)
{
- return !cap->ci;
+ return RB_EMPTY_NODE(&cap->ci_node);
}
extern void ceph_remove_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
--
2.47.3
next prev parent reply other threads:[~2026-07-06 7:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-06 7:38 [PATCH v2 1/4] fs/ceph/caps: make __ceph_remove_cap() static Max Kellermann
2026-07-06 7:38 ` [PATCH v2 2/4] fs/ceph: add helper function ceph_cap_is_removed() Max Kellermann
2026-07-06 7:38 ` Max Kellermann [this message]
2026-07-06 7:38 ` [PATCH v2 4/4] fs/ceph/cap: pass inode pointer around instead of reloading from RAM Max Kellermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260706073812.3922732-3-max.kellermann@ionos.com \
--to=max.kellermann@ionos.com \
--cc=amarkuze@redhat.com \
--cc=ceph-devel@vger.kernel.org \
--cc=idryomov@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.