]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ksmbd: use connection ClientGUID for lease lookup
authorNamjae Jeon <linkinjeon@kernel.org>
Thu, 18 Jun 2026 01:33:20 +0000 (10:33 +0900)
committerSteve French <stfrench@microsoft.com>
Tue, 23 Jun 2026 01:15:03 +0000 (20:15 -0500)
MS-SMB2 defines the lease table lookup key as Connection.ClientGuid.
Use the connection ClientGUID consistently when checking for same-client
leases and duplicate lease keys.

Also preserve directory and parent lease metadata when copying an existing
lease state to a new open.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/oplock.c
fs/smb/server/oplock.h
fs/smb/server/smb2pdu.c

index 5c6c0550a477354e755c34e33dba1a7d5a501b76..627cea7fd7ea559ef68bddcf69429b922c2a9c87 100644 (file)
@@ -520,7 +520,7 @@ static inline int compare_guid_key(struct oplock_info *opinfo,
  * Return:      oplock(lease) object on success, otherwise NULL
  */
 static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
-                                                char *client_guid,
+                                                const char *client_guid,
                                                 struct lease_ctx_info *lctx)
 {
        int ret;
@@ -1012,7 +1012,7 @@ again:
        write_unlock(&lease_list_lock);
 }
 
-int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
+int find_same_lease_key(struct ksmbd_conn *conn, struct ksmbd_inode *ci,
                        struct lease_ctx_info *lctx)
 {
        struct oplock_info *opinfo;
@@ -1029,7 +1029,7 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
        }
 
        list_for_each_entry(lb, &lease_table_list, l_entry) {
-               if (!memcmp(lb->client_guid, sess->ClientGUID,
+               if (!memcmp(lb->client_guid, conn->ClientGUID,
                            SMB2_CLIENT_GUID_SIZE))
                        goto found;
        }
@@ -1045,7 +1045,7 @@ found:
                rcu_read_unlock();
                if (opinfo->o_fp->f_ci == ci)
                        goto op_next;
-               err = compare_guid_key(opinfo, sess->ClientGUID,
+               err = compare_guid_key(opinfo, conn->ClientGUID,
                                       lctx->lease_key);
                if (err) {
                        err = -EINVAL;
@@ -1078,6 +1078,9 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2)
        lease2->flags = lease1->flags;
        lease2->epoch = lease1->epoch;
        lease2->version = lease1->version;
+       lease2->is_dir = lease1->is_dir;
+       memcpy(lease2->parent_lease_key, lease1->parent_lease_key,
+              SMB2_LEASE_KEY_SIZE);
 }
 
 static void add_lease_global_list(struct oplock_info *opinfo,
@@ -1216,7 +1219,6 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
                     struct ksmbd_file *fp, __u16 tid,
                     struct lease_ctx_info *lctx, int share_ret)
 {
-       struct ksmbd_session *sess = work->sess;
        int err = 0;
        struct oplock_info *opinfo = NULL, *prev_opinfo = NULL;
        struct ksmbd_inode *ci = fp->f_ci;
@@ -1259,12 +1261,12 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
                struct oplock_info *m_opinfo;
 
                /* is lease already granted ? */
-               m_opinfo = same_client_has_lease(ci, sess->ClientGUID,
+               m_opinfo = same_client_has_lease(ci, work->conn->ClientGUID,
                                                 lctx);
                if (m_opinfo) {
                        copy_lease(m_opinfo, opinfo);
                        if (atomic_read(&m_opinfo->breaking_cnt))
-                               opinfo->o_lease->flags =
+                               opinfo->o_lease->flags |=
                                        SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE;
                        opinfo_put(m_opinfo);
                        goto out;
index d91a8266e065ef340a357a773c48670e2ce276a6..795a9119dad9adf253be717f83910d43d51b9c14 100644 (file)
@@ -116,7 +116,7 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp);
 struct create_context *smb2_find_context_vals(void *open_req, const char *tag, int tag_len);
 struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
                                          char *lease_key);
-int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
+int find_same_lease_key(struct ksmbd_conn *conn, struct ksmbd_inode *ci,
                        struct lease_ctx_info *lctx);
 void destroy_lease_table(struct ksmbd_conn *conn);
 void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
index 19e819898fd0ff8873b39e78561e6bbf398a75c6..0766f0d662be3d67041ae89b7d64d750ecc607ad 100644 (file)
@@ -3637,7 +3637,7 @@ int smb2_open(struct ksmbd_work *work)
                        ksmbd_debug(SMB,
                                    "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
                                    name, req_op_level, lc->req_state);
-                       rc = find_same_lease_key(sess, fp->f_ci, lc);
+                       rc = find_same_lease_key(conn, fp->f_ci, lc);
                        if (rc)
                                goto err_out1;
                } else if (open_flags == O_RDONLY &&