Commit 02b68b20 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French
Browse files

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: default avatarNamjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 8044ee8e
Loading
Loading
Loading
Loading
+15 −20
Original line number Diff line number Diff line
@@ -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;

	while (!list_empty(&sess->tree_conn_list)) {
	struct ksmbd_tree_connect *tc;
	unsigned long id;

		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;
}
+3 −1
Original line number Diff line number Diff line
@@ -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;
+5 −1
Original line number Diff line number Diff line
@@ -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];
+1 −1
Original line number Diff line number Diff line
@@ -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;
	}