2022-07-25 9:56 GMT+09:00, Hyunchul Lee <hyc.lee@xxxxxxxxx>: > 2022년 7월 22일 (금) 오후 12:04, Namjae Jeon <linkinjeon@xxxxxxxxxx>님이 작성: >> >> After multi-channel connection with windows, Several channels of >> session are connected. Among them, if there is a problem in one channel, >> Windows connects again after disconnecting the channel. In this process, >> the session is released and a kernel oop can occurs while processing >> requests to other channels. When the channel is disconnected, if other >> channels still exist in the session after deleting the channel from >> the channel list in the session, the session should not be released. >> Finally, the session will be released after all channels are >> disconnected. >> >> Signed-off-by: Namjae Jeon <linkinjeon@xxxxxxxxxx> >> --- >> fs/ksmbd/auth.c | 56 ++++++++++++++++------------- >> fs/ksmbd/auth.h | 11 +++--- >> fs/ksmbd/connection.h | 7 ---- >> fs/ksmbd/mgmt/tree_connect.c | 5 +-- >> fs/ksmbd/mgmt/tree_connect.h | 4 ++- >> fs/ksmbd/mgmt/user_session.c | 68 ++++++++++++++++++++++++------------ >> fs/ksmbd/mgmt/user_session.h | 7 ++-- >> fs/ksmbd/oplock.c | 11 +++--- >> fs/ksmbd/smb2pdu.c | 21 +++++------ >> fs/ksmbd/smb_common.h | 2 +- >> fs/ksmbd/vfs.c | 3 +- >> fs/ksmbd/vfs_cache.c | 2 +- >> 12 files changed, 111 insertions(+), 86 deletions(-) >> >> diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c >> index 911444d21267..c5a5c7b90d72 100644 >> --- a/fs/ksmbd/auth.c >> +++ b/fs/ksmbd/auth.c >> @@ -121,8 +121,8 @@ static int ksmbd_gen_sess_key(struct ksmbd_session >> *sess, char *hash, >> return rc; >> } >> >> -static int calc_ntlmv2_hash(struct ksmbd_session *sess, char >> *ntlmv2_hash, >> - char *dname) >> +static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session >> *sess, >> + char *ntlmv2_hash, char *dname) >> { >> int ret, len, conv_len; >> wchar_t *domain = NULL; >> @@ -158,7 +158,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session >> *sess, char *ntlmv2_hash, >> } >> >> conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len, >> - sess->conn->local_nls); >> + conn->local_nls); >> if (conv_len < 0 || conv_len > len) { >> ret = -EINVAL; >> goto out; >> @@ -182,7 +182,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session >> *sess, char *ntlmv2_hash, >> } >> >> conv_len = smb_strtoUTF16((__le16 *)domain, dname, len, >> - sess->conn->local_nls); >> + conn->local_nls); >> if (conv_len < 0 || conv_len > len) { >> ret = -EINVAL; >> goto out; >> @@ -215,8 +215,9 @@ static int calc_ntlmv2_hash(struct ksmbd_session >> *sess, char *ntlmv2_hash, >> * >> * Return: 0 on success, error number on error >> */ >> -int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp >> *ntlmv2, >> - int blen, char *domain_name, char *cryptkey) >> +int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session >> *sess, >> + struct ntlmv2_resp *ntlmv2, int blen, char >> *domain_name, >> + char *cryptkey) >> { >> char ntlmv2_hash[CIFS_ENCPWD_SIZE]; >> char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE]; >> @@ -230,7 +231,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, >> struct ntlmv2_resp *ntlmv2, >> return -ENOMEM; >> } >> >> - rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name); >> + rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name); >> if (rc) { >> ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc); >> goto out; >> @@ -333,7 +334,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct >> authenticate_message *authblob, >> /* process NTLMv2 authentication */ >> ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n", >> domain_name); >> - ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char >> *)authblob + nt_off), >> + ret = ksmbd_auth_ntlmv2(conn, sess, >> + (struct ntlmv2_resp *)((char *)authblob + >> nt_off), >> nt_len - CIFS_ENCPWD_SIZE, >> domain_name, conn->ntlmssp.cryptkey); >> kfree(domain_name); >> @@ -659,8 +661,9 @@ struct derivation { >> bool binding; >> }; >> >> -static int generate_key(struct ksmbd_session *sess, struct kvec label, >> - struct kvec context, __u8 *key, unsigned int >> key_size) >> +static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session >> *sess, >> + struct kvec label, struct kvec context, __u8 >> *key, >> + unsigned int key_size) >> { >> unsigned char zero = 0x0; >> __u8 i[4] = {0, 0, 0, 1}; >> @@ -720,8 +723,8 @@ static int generate_key(struct ksmbd_session *sess, >> struct kvec label, >> goto smb3signkey_ret; >> } >> >> - if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || >> - sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) >> + if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || >> + conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) >> rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, >> 4); >> else >> rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, >> 4); >> @@ -756,17 +759,17 @@ static int generate_smb3signingkey(struct >> ksmbd_session *sess, >> if (!chann) >> return 0; >> >> - if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding) >> + if (conn->dialect >= SMB30_PROT_ID && signing->binding) >> key = chann->smb3signingkey; >> else >> key = sess->smb3signingkey; >> >> - rc = generate_key(sess, signing->label, signing->context, key, >> + rc = generate_key(conn, sess, signing->label, signing->context, >> key, >> SMB3_SIGN_KEY_SIZE); >> if (rc) >> return rc; >> >> - if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding)) >> + if (!(conn->dialect >= SMB30_PROT_ID && signing->binding)) >> memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE); >> >> ksmbd_debug(AUTH, "dumping generated AES signing keys\n"); >> @@ -820,30 +823,31 @@ struct derivation_twin { >> struct derivation decryption; >> }; >> >> -static int generate_smb3encryptionkey(struct ksmbd_session *sess, >> +static int generate_smb3encryptionkey(struct ksmbd_conn *conn, >> + struct ksmbd_session *sess, >> const struct derivation_twin >> *ptwin) >> { >> int rc; >> >> - rc = generate_key(sess, ptwin->encryption.label, >> + rc = generate_key(conn, sess, ptwin->encryption.label, >> ptwin->encryption.context, >> sess->smb3encryptionkey, >> SMB3_ENC_DEC_KEY_SIZE); >> if (rc) >> return rc; >> >> - rc = generate_key(sess, ptwin->decryption.label, >> + rc = generate_key(conn, sess, ptwin->decryption.label, >> ptwin->decryption.context, >> sess->smb3decryptionkey, >> SMB3_ENC_DEC_KEY_SIZE); >> if (rc) >> return rc; >> >> ksmbd_debug(AUTH, "dumping generated AES encryption keys\n"); >> - ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type); >> + ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type); >> ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); >> ksmbd_debug(AUTH, "Session Key %*ph\n", >> SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); >> - if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || >> - sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) { >> + if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || >> + conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) { >> ksmbd_debug(AUTH, "ServerIn Key %*ph\n", >> SMB3_GCM256_CRYPTKEY_SIZE, >> sess->smb3encryptionkey); >> ksmbd_debug(AUTH, "ServerOut Key %*ph\n", >> @@ -857,7 +861,8 @@ static int generate_smb3encryptionkey(struct >> ksmbd_session *sess, >> return 0; >> } >> >> -int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess) >> +int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn, >> + struct ksmbd_session *sess) >> { >> struct derivation_twin twin; >> struct derivation *d; >> @@ -874,10 +879,11 @@ int ksmbd_gen_smb30_encryptionkey(struct >> ksmbd_session *sess) >> d->context.iov_base = "ServerIn "; >> d->context.iov_len = 10; >> >> - return generate_smb3encryptionkey(sess, &twin); >> + return generate_smb3encryptionkey(conn, sess, &twin); >> } >> >> -int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess) >> +int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn, >> + struct ksmbd_session *sess) >> { >> struct derivation_twin twin; >> struct derivation *d; >> @@ -894,7 +900,7 @@ int ksmbd_gen_smb311_encryptionkey(struct >> ksmbd_session *sess) >> d->context.iov_base = sess->Preauth_HashValue; >> d->context.iov_len = 64; >> >> - return generate_smb3encryptionkey(sess, &twin); >> + return generate_smb3encryptionkey(conn, sess, &twin); >> } >> >> int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf, >> diff --git a/fs/ksmbd/auth.h b/fs/ksmbd/auth.h >> index 95629651cf26..25b772653de0 100644 >> --- a/fs/ksmbd/auth.h >> +++ b/fs/ksmbd/auth.h >> @@ -38,8 +38,9 @@ struct kvec; >> int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, >> unsigned int nvec, int enc); >> void ksmbd_copy_gss_neg_header(void *buf); >> -int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp >> *ntlmv2, >> - int blen, char *domain_name, char *cryptkey); >> +int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session >> *sess, >> + struct ntlmv2_resp *ntlmv2, int blen, char >> *domain_name, >> + char *cryptkey); >> int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message >> *authblob, >> int blob_len, struct ksmbd_conn *conn, >> struct ksmbd_session *sess); >> @@ -58,8 +59,10 @@ int ksmbd_gen_smb30_signingkey(struct ksmbd_session >> *sess, >> struct ksmbd_conn *conn); >> int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess, >> struct ksmbd_conn *conn); >> -int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess); >> -int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess); >> +int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn, >> + struct ksmbd_session *sess); >> +int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn, >> + struct ksmbd_session *sess); >> int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf, >> __u8 *pi_hash); >> int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len, >> diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h >> index 2e4730457c92..e7f7d5707951 100644 >> --- a/fs/ksmbd/connection.h >> +++ b/fs/ksmbd/connection.h >> @@ -20,13 +20,6 @@ >> >> #define KSMBD_SOCKET_BACKLOG 16 >> >> -/* >> - * WARNING >> - * >> - * This is nothing but a HACK. Session status should move to channel >> - * or to session. As of now we have 1 tcp_conn : 1 ksmbd_session, but >> - * we need to change it to 1 tcp_conn : N ksmbd_sessions. >> - */ >> enum { >> KSMBD_SESS_NEW = 0, >> KSMBD_SESS_GOOD, >> diff --git a/fs/ksmbd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c >> index 0d28e723a28c..b35ea6a6abc5 100644 >> --- a/fs/ksmbd/mgmt/tree_connect.c >> +++ b/fs/ksmbd/mgmt/tree_connect.c >> @@ -16,7 +16,8 @@ >> #include "user_session.h" >> >> struct ksmbd_tree_conn_status >> -ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name) >> +ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session >> *sess, >> + char *share_name) >> { >> struct ksmbd_tree_conn_status status = {-EINVAL, NULL}; >> struct ksmbd_tree_connect_response *resp = NULL; >> @@ -41,7 +42,7 @@ ksmbd_tree_conn_connect(struct ksmbd_session *sess, char >> *share_name) >> goto out_error; >> } >> >> - peer_addr = KSMBD_TCP_PEER_SOCKADDR(sess->conn); >> + peer_addr = KSMBD_TCP_PEER_SOCKADDR(conn); >> resp = ksmbd_ipc_tree_connect_request(sess, >> sc, >> tree_conn, >> diff --git a/fs/ksmbd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h >> index 18e2a996e0aa..71e50271dccf 100644 >> --- a/fs/ksmbd/mgmt/tree_connect.h >> +++ b/fs/ksmbd/mgmt/tree_connect.h >> @@ -12,6 +12,7 @@ >> >> struct ksmbd_share_config; >> struct ksmbd_user; >> +struct ksmbd_conn; >> >> struct ksmbd_tree_connect { >> int id; >> @@ -40,7 +41,8 @@ static inline int test_tree_conn_flag(struct >> ksmbd_tree_connect *tree_conn, >> struct ksmbd_session; >> >> struct ksmbd_tree_conn_status >> -ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name); >> +ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session >> *sess, >> + char *share_name); >> >> int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, >> struct ksmbd_tree_connect *tree_conn); >> diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c >> index b9acb6770b03..ce32fdd66807 100644 >> --- a/fs/ksmbd/mgmt/user_session.c >> +++ b/fs/ksmbd/mgmt/user_session.c >> @@ -151,9 +151,6 @@ void ksmbd_session_destroy(struct ksmbd_session >> *sess) >> if (!sess) >> return; >> >> - if (!atomic_dec_and_test(&sess->refcnt)) >> - return; >> - >> down_write(&sessions_table_lock); >> hash_del(&sess->hlist); >> up_write(&sessions_table_lock); >> @@ -184,16 +181,59 @@ static struct ksmbd_session >> *__session_lookup(unsigned long long id) >> int ksmbd_session_register(struct ksmbd_conn *conn, >> struct ksmbd_session *sess) >> { >> - sess->conn = conn; >> + sess->dialect = conn->dialect; >> + memcpy(sess->ClientGUID, conn->ClientGUID, >> SMB2_CLIENT_GUID_SIZE); >> return xa_err(xa_store(&conn->sessions, sess->id, sess, >> GFP_KERNEL)); >> } >> >> +static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session >> *sess) >> +{ >> + struct channel *chann, *tmp; >> + >> + write_lock(&sess->chann_lock); >> + list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list, >> + chann_list) { >> + if (chann->conn == conn) { >> + list_del(&chann->chann_list); >> + kfree(chann); >> + write_unlock(&sess->chann_lock); >> + return 0; >> + } >> + } >> + write_unlock(&sess->chann_lock); >> + >> + return -ENOENT; >> +} >> + > > Can we delete free_channel_list() because ksmbd_sessions_deregister() > frees all channels by this function. If smb2 session setup fail, session should be freed by ksmbd_session_destroy(). and free_channel_list will delete chann entries in ksmbd_session_destroy(). > >> void ksmbd_sessions_deregister(struct ksmbd_conn *conn) >> { >> struct ksmbd_session *sess; >> - unsigned long id; >> >> - xa_for_each(&conn->sessions, id, sess) { >> + if (conn->binding) { >> + struct hlist_node *tmp; >> + int bkt; >> + >> + down_write(&sessions_table_lock); >> + hash_for_each_safe(sessions_table, bkt, tmp, sess, hlist) >> { > > I think hash_for_each is enough instead of hash_for_each_safe. My initial version patch delete session in this loop. Indeed, hash_for_each() can be used on this version. Thanks. > >> + if (!ksmbd_chann_del(conn, sess)) { >> + up_write(&sessions_table_lock); >> + goto sess_destroy; >> + } >> + } >> + up_write(&sessions_table_lock); >> + } else { >> + unsigned long id; >> + >> + xa_for_each(&conn->sessions, id, sess) { >> + if (!ksmbd_chann_del(conn, sess)) >> + goto sess_destroy; >> + } >> + } >> + >> + return; >> + >> +sess_destroy: >> + if (list_empty(&sess->ksmbd_chann_list)) { >> xa_erase(&conn->sessions, sess->id); >> ksmbd_session_destroy(sess); >> } >> @@ -205,27 +245,12 @@ struct ksmbd_session *ksmbd_session_lookup(struct >> ksmbd_conn *conn, >> return xa_load(&conn->sessions, id); >> } >> >> -int get_session(struct ksmbd_session *sess) >> -{ >> - return atomic_inc_not_zero(&sess->refcnt); >> -} >> - >> -void put_session(struct ksmbd_session *sess) >> -{ >> - if (atomic_dec_and_test(&sess->refcnt)) >> - pr_err("get/%s seems to be mismatched.", __func__); >> -} >> - >> struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long >> id) >> { >> struct ksmbd_session *sess; >> >> down_read(&sessions_table_lock); >> sess = __session_lookup(id); >> - if (sess) { >> - if (!get_session(sess)) >> - sess = NULL; >> - } >> up_read(&sessions_table_lock); >> >> return sess; >> @@ -306,7 +331,6 @@ static struct ksmbd_session *__session_create(int >> protocol) >> INIT_LIST_HEAD(&sess->ksmbd_chann_list); >> INIT_LIST_HEAD(&sess->rpc_handle_list); >> sess->sequence_number = 1; >> - atomic_set(&sess->refcnt, 1); >> rwlock_init(&sess->chann_lock); >> >> switch (protocol) { >> diff --git a/fs/ksmbd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h >> index 1ec659f0151b..8934b8ee275b 100644 >> --- a/fs/ksmbd/mgmt/user_session.h >> +++ b/fs/ksmbd/mgmt/user_session.h >> @@ -33,8 +33,10 @@ struct preauth_session { >> struct ksmbd_session { >> u64 id; >> >> + __u16 dialect; >> + char >> ClientGUID[SMB2_CLIENT_GUID_SIZE]; >> + >> struct ksmbd_user *user; >> - struct ksmbd_conn *conn; >> unsigned int sequence_number; >> unsigned int flags; >> >> @@ -59,7 +61,6 @@ struct ksmbd_session { >> __u8 >> smb3signingkey[SMB3_SIGN_KEY_SIZE]; >> >> struct ksmbd_file_table file_table; >> - atomic_t refcnt; >> }; >> >> static inline int test_session_flag(struct ksmbd_session *sess, int bit) >> @@ -100,6 +101,4 @@ void ksmbd_release_tree_conn_id(struct ksmbd_session >> *sess, int id); >> int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name); >> void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id); >> int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id); >> -int get_session(struct ksmbd_session *sess); >> -void put_session(struct ksmbd_session *sess); >> #endif /* __USER_SESSION_MANAGEMENT_H__ */ >> diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c >> index 9bb4fb8b80de..ce4c15c3554d 100644 >> --- a/fs/ksmbd/oplock.c >> +++ b/fs/ksmbd/oplock.c >> @@ -30,6 +30,7 @@ static DEFINE_RWLOCK(lease_list_lock); >> static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, >> u64 id, __u16 Tid) >> { >> + struct ksmbd_conn *conn = work->conn; >> struct ksmbd_session *sess = work->sess; >> struct oplock_info *opinfo; >> >> @@ -38,7 +39,7 @@ static struct oplock_info *alloc_opinfo(struct >> ksmbd_work *work, >> return NULL; >> >> opinfo->sess = sess; >> - opinfo->conn = sess->conn; >> + opinfo->conn = conn; >> opinfo->level = SMB2_OPLOCK_LEVEL_NONE; >> opinfo->op_state = OPLOCK_STATE_NONE; >> opinfo->pending_break = 0; >> @@ -971,7 +972,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->conn->ClientGUID, >> + if (!memcmp(lb->client_guid, sess->ClientGUID, >> SMB2_CLIENT_GUID_SIZE)) >> goto found; >> } >> @@ -987,7 +988,7 @@ int find_same_lease_key(struct ksmbd_session *sess, >> struct ksmbd_inode *ci, >> rcu_read_unlock(); >> if (opinfo->o_fp->f_ci == ci) >> goto op_next; >> - err = compare_guid_key(opinfo, sess->conn->ClientGUID, >> + err = compare_guid_key(opinfo, sess->ClientGUID, >> lctx->lease_key); >> if (err) { >> err = -EINVAL; >> @@ -1121,7 +1122,7 @@ 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->conn->ClientGUID, >> + m_opinfo = same_client_has_lease(ci, sess->ClientGUID, >> lctx); >> if (m_opinfo) { >> copy_lease(m_opinfo, opinfo); >> @@ -1239,7 +1240,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work >> *work, struct ksmbd_file *fp, >> { >> struct oplock_info *op, *brk_op; >> struct ksmbd_inode *ci; >> - struct ksmbd_conn *conn = work->sess->conn; >> + struct ksmbd_conn *conn = work->conn; >> >> if (!test_share_config_flag(work->tcon->share_conf, >> KSMBD_SHARE_FLAG_OPLOCKS)) >> diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c >> index ae5677a66cb2..1f4f2d5217a6 100644 >> --- a/fs/ksmbd/smb2pdu.c >> +++ b/fs/ksmbd/smb2pdu.c >> @@ -603,12 +603,9 @@ static void destroy_previous_session(struct >> ksmbd_conn *conn, >> if (!prev_user || >> strcmp(user->name, prev_user->name) || >> user->passkey_sz != prev_user->passkey_sz || >> - memcmp(user->passkey, prev_user->passkey, user->passkey_sz)) >> { >> - put_session(prev_sess); >> + memcmp(user->passkey, prev_user->passkey, user->passkey_sz)) >> return; >> - } >> >> - put_session(prev_sess); >> prev_sess->state = SMB2_SESSION_EXPIRED; >> write_lock(&prev_sess->chann_lock); >> list_for_each_entry(chann, &prev_sess->ksmbd_chann_list, >> chann_list) >> @@ -1499,7 +1496,7 @@ static int ntlm_authenticate(struct ksmbd_work >> *work) >> >> if (smb3_encryption_negotiated(conn) && >> !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { >> - rc = conn->ops->generate_encryptionkey(sess); >> + rc = conn->ops->generate_encryptionkey(conn, sess); >> if (rc) { >> ksmbd_debug(SMB, >> "SMB3 encryption key generation >> failed\n"); >> @@ -1590,7 +1587,7 @@ static int krb5_authenticate(struct ksmbd_work >> *work) >> sess->sign = true; >> >> if (smb3_encryption_negotiated(conn)) { >> - retval = conn->ops->generate_encryptionkey(sess); >> + retval = conn->ops->generate_encryptionkey(conn, sess); >> if (retval) { >> ksmbd_debug(SMB, >> "SMB3 encryption key generation >> failed\n"); >> @@ -1678,7 +1675,7 @@ int smb2_sess_setup(struct ksmbd_work *work) >> goto out_err; >> } >> >> - if (conn->dialect != sess->conn->dialect) { >> + if (conn->dialect != sess->dialect) { >> rc = -EINVAL; >> goto out_err; >> } >> @@ -1688,7 +1685,7 @@ int smb2_sess_setup(struct ksmbd_work *work) >> goto out_err; >> } >> >> - if (strncmp(conn->ClientGUID, sess->conn->ClientGUID, >> + if (strncmp(conn->ClientGUID, sess->ClientGUID, >> SMB2_CLIENT_GUID_SIZE)) { >> rc = -ENOENT; >> goto out_err; >> @@ -1890,7 +1887,7 @@ int smb2_tree_connect(struct ksmbd_work *work) >> ksmbd_debug(SMB, "tree connect request for tree %s treename >> %s\n", >> name, treename); >> >> - status = ksmbd_tree_conn_connect(sess, name); >> + status = ksmbd_tree_conn_connect(conn, sess, name); >> if (status.ret == KSMBD_TREE_CONN_STATUS_OK) >> rsp->hdr.Id.SyncId.TreeId = >> cpu_to_le32(status.tree_conn->id); >> else >> @@ -4875,7 +4872,7 @@ static int smb2_get_info_filesystem(struct >> ksmbd_work *work, >> struct smb2_query_info_rsp *rsp) >> { >> struct ksmbd_session *sess = work->sess; >> - struct ksmbd_conn *conn = sess->conn; >> + struct ksmbd_conn *conn = work->conn; >> struct ksmbd_share_config *share = work->tcon->share_conf; >> int fsinfoclass = 0; >> struct kstatfs stfs; >> @@ -5793,7 +5790,7 @@ static int set_rename_info(struct ksmbd_work *work, >> struct ksmbd_file *fp, >> } >> next: >> return smb2_rename(work, fp, user_ns, rename_info, >> - work->sess->conn->local_nls); >> + work->conn->local_nls); >> } >> >> static int set_file_disposition_info(struct ksmbd_file *fp, >> @@ -5925,7 +5922,7 @@ static int smb2_set_info_file(struct ksmbd_work >> *work, struct ksmbd_file *fp, >> return smb2_create_link(work, work->tcon->share_conf, >> (struct smb2_file_link_info >> *)req->Buffer, >> buf_len, fp->filp, >> - work->sess->conn->local_nls); >> + work->conn->local_nls); >> } >> case FILE_DISPOSITION_INFORMATION: >> { >> diff --git a/fs/ksmbd/smb_common.h b/fs/ksmbd/smb_common.h >> index e1369b4345a9..318c16fa81da 100644 >> --- a/fs/ksmbd/smb_common.h >> +++ b/fs/ksmbd/smb_common.h >> @@ -421,7 +421,7 @@ struct smb_version_ops { >> int (*check_sign_req)(struct ksmbd_work *work); >> void (*set_sign_rsp)(struct ksmbd_work *work); >> int (*generate_signingkey)(struct ksmbd_session *sess, struct >> ksmbd_conn *conn); >> - int (*generate_encryptionkey)(struct ksmbd_session *sess); >> + int (*generate_encryptionkey)(struct ksmbd_conn *conn, struct >> ksmbd_session *sess); >> bool (*is_transform_hdr)(void *buf); >> int (*decrypt_req)(struct ksmbd_work *work); >> int (*encrypt_resp)(struct ksmbd_work *work); >> diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c >> index 5d185564aef6..4f75b1436eab 100644 >> --- a/fs/ksmbd/vfs.c >> +++ b/fs/ksmbd/vfs.c >> @@ -481,12 +481,11 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct >> ksmbd_file *fp, >> char *buf, size_t count, loff_t *pos, bool sync, >> ssize_t *written) >> { >> - struct ksmbd_session *sess = work->sess; >> struct file *filp; >> loff_t offset = *pos; >> int err = 0; >> >> - if (sess->conn->connection_type) { >> + if (work->conn->connection_type) { >> if (!(fp->daccess & FILE_WRITE_DATA_LE)) { >> pr_err("no right to write(%pd)\n", >> fp->filp->f_path.dentry); >> diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c >> index c4d59d2735f0..da9163b00350 100644 >> --- a/fs/ksmbd/vfs_cache.c >> +++ b/fs/ksmbd/vfs_cache.c >> @@ -569,7 +569,7 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work >> *work, struct file *filp) >> atomic_set(&fp->refcount, 1); >> >> fp->filp = filp; >> - fp->conn = work->sess->conn; >> + fp->conn = work->conn; >> fp->tcon = work->tcon; >> fp->volatile_id = KSMBD_NO_FID; >> fp->persistent_id = KSMBD_NO_FID; >> -- >> 2.25.1 >> > > > -- > Thanks, > Hyunchul >