cifsd: use xarray instead of linked list for tree connect list
authorNamjae Jeon <namjae.jeon@samsung.com>
Thu, 1 Apr 2021 08:45:33 +0000 (17:45 +0900)
committerSteve French <stfrench@microsoft.com>
Tue, 11 May 2021 00:15:34 +0000 (19:15 -0500)
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>
fs/cifsd/mgmt/tree_connect.c
fs/cifsd/mgmt/user_session.c
fs/cifsd/mgmt/user_session.h
fs/cifsd/smb2pdu.c

index d5670f2..0c8374e 100644 (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;
 }
index 5a2113b..f5cc7a6 100644 (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;
index 68018f0..1a97c85 100644 (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];
index 1390417..0b71994 100644 (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;
        }