[PATCH] ksmbd: annotate oplock list traversals under m_lock

From: Runyu Xiao

Date: Fri Jun 26 2026 - 00:14:38 EST


session_fd_check() and ksmbd_reopen_durable_fd() walk ci->m_op_list with
list_for_each_entry_rcu() while holding ci->m_lock for write. That is
the local inode/oplock serializer, but the RCU-list iterator does not
currently tell lockdep about it.

Pass lockdep_is_held(&ci->m_lock) to these iterators so
CONFIG_PROVE_RCU_LIST can see the rwsem protection already in place.

This was found by our static analysis tool and then manually reviewed
against the current tree. The dynamic triage evidence is a
target-matched CONFIG_PROVE_RCU_LIST warning; the change is limited
to documenting the existing protection contract.

This is a lockdep annotation cleanup. It does not change oplock list
lifetime or durable-handle behavior.

Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
fs/smb/server/vfs_cache.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index 6ef116585af6..a3c0bb2a5279 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -909,7 +909,8 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
conn = fp->conn;
ci = fp->f_ci;
down_write(&ci->m_lock);
- list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
+ list_for_each_entry_rcu(op, &ci->m_op_list, op_entry,
+ lockdep_is_held(&ci->m_lock)) {
if (op->conn != conn)
continue;
if (op->conn && atomic_dec_and_test(&op->conn->refcnt))
@@ -1012,7 +1013,8 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)

ci = fp->f_ci;
down_write(&ci->m_lock);
- list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
+ list_for_each_entry_rcu(op, &ci->m_op_list, op_entry,
+ lockdep_is_held(&ci->m_lock)) {
if (op->conn)
continue;
op->conn = fp->conn;
--
2.34.1