cifsd: use xarray instead of linked list for tree connect list

Matthew suggest to change linked list of tree connect list to xarray.
It will be tree connect lookup in O(log(n)) time instead of O(n) time.

Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Namjae Jeon 2021-04-01 17:45:33 +09:00 committed by Steve French
parent 8044ee8e64
commit 02b68b2065
4 changed files with 24 additions and 23 deletions

View File

@ -5,6 +5,8 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/xarray.h>
#include "../buffer_pool.h"
#include "../transport_ipc.h"
@ -23,6 +25,7 @@ ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
struct ksmbd_share_config *sc;
struct ksmbd_tree_connect *tree_conn = NULL;
struct sockaddr *peer_addr;
int ret;
sc = ksmbd_share_config_get(share_name);
if (!sc)
@ -59,8 +62,12 @@ ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
tree_conn->share_conf = sc;
status.tree_conn = tree_conn;
list_add(&tree_conn->list, &sess->tree_conn_list);
ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn,
GFP_KERNEL));
if (ret) {
status.ret = -ENOMEM;
goto out_error;
}
ksmbd_free(resp);
return status;
@ -80,7 +87,7 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id);
ksmbd_release_tree_conn_id(sess, tree_conn->id);
list_del(&tree_conn->list);
xa_erase(&sess->tree_conns, tree_conn->id);
ksmbd_share_config_put(tree_conn->share_conf);
ksmbd_free(tree_conn);
return ret;
@ -89,15 +96,7 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess,
unsigned int id)
{
struct ksmbd_tree_connect *tree_conn;
struct list_head *tmp;
list_for_each(tmp, &sess->tree_conn_list) {
tree_conn = list_entry(tmp, struct ksmbd_tree_connect, list);
if (tree_conn->id == id)
return tree_conn;
}
return NULL;
return xa_load(&sess->tree_conns, id);
}
struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
@ -114,15 +113,11 @@ struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess)
{
int ret = 0;
struct ksmbd_tree_connect *tc;
unsigned long id;
while (!list_empty(&sess->tree_conn_list)) {
struct ksmbd_tree_connect *tc;
tc = list_entry(sess->tree_conn_list.next,
struct ksmbd_tree_connect,
list);
xa_for_each(&sess->tree_conns, id, tc)
ret |= ksmbd_tree_conn_disconnect(sess, tc);
}
xa_destroy(&sess->tree_conns);
return ret;
}

View File

@ -6,6 +6,8 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/rwsem.h>
#include <linux/version.h>
#include <linux/xarray.h>
#include "ksmbd_ida.h"
#include "user_session.h"
@ -275,7 +277,7 @@ static struct ksmbd_session *__session_create(int protocol)
set_session_flag(sess, protocol);
INIT_LIST_HEAD(&sess->sessions_entry);
INIT_LIST_HEAD(&sess->tree_conn_list);
xa_init(&sess->tree_conns);
INIT_LIST_HEAD(&sess->ksmbd_chann_list);
INIT_LIST_HEAD(&sess->rpc_handle_list);
sess->sequence_number = 1;

View File

@ -7,6 +7,8 @@
#define __USER_SESSION_MANAGEMENT_H__
#include <linux/hashtable.h>
#include <linux/version.h>
#include <linux/xarray.h>
#include "../smb_common.h"
#include "../ntlmssp.h"
@ -50,10 +52,12 @@ struct ksmbd_session {
struct hlist_node hlist;
struct list_head ksmbd_chann_list;
struct list_head tree_conn_list;
struct xarray tree_conns;
struct ksmbd_ida *tree_conn_ida;
struct list_head rpc_handle_list;
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];

View File

@ -104,7 +104,7 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
return 0;
}
if (list_empty(&work->sess->tree_conn_list)) {
if (xa_empty(&work->sess->tree_conns)) {
ksmbd_debug(SMB, "NO tree connected\n");
return -1;
}