diff options
author | Namjae Jeon <namjae.jeon@samsung.com> | 2021-04-01 11:45:33 +0300 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2021-05-11 03:15:34 +0300 |
commit | 02b68b2065c91ce706f462fd509032a77db5d9dc (patch) | |
tree | 82db53b5ac33c604aec9c1ded0cea98f263fc144 /fs | |
parent | 8044ee8e64b4fdb068e504ec3ade597d1ccad456 (diff) | |
download | linux-02b68b2065c91ce706f462fd509032a77db5d9dc.tar.xz |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifsd/mgmt/tree_connect.c | 35 | ||||
-rw-r--r-- | fs/cifsd/mgmt/user_session.c | 4 | ||||
-rw-r--r-- | fs/cifsd/mgmt/user_session.h | 6 | ||||
-rw-r--r-- | fs/cifsd/smb2pdu.c | 2 |
4 files changed, 24 insertions, 23 deletions
diff --git a/fs/cifsd/mgmt/tree_connect.c b/fs/cifsd/mgmt/tree_connect.c index d5670f2596a3..0c8374e8240f 100644 --- a/fs/cifsd/mgmt/tree_connect.c +++ b/fs/cifsd/mgmt/tree_connect.c @@ -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; } diff --git a/fs/cifsd/mgmt/user_session.c b/fs/cifsd/mgmt/user_session.c index 5a2113bf18ef..f5cc7a62d848 100644 --- a/fs/cifsd/mgmt/user_session.c +++ b/fs/cifsd/mgmt/user_session.c @@ -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; diff --git a/fs/cifsd/mgmt/user_session.h b/fs/cifsd/mgmt/user_session.h index 68018f0f5c0b..1a97c851f2fc 100644 --- a/fs/cifsd/mgmt/user_session.h +++ b/fs/cifsd/mgmt/user_session.h @@ -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]; diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 139041768f65..0b7199444f73 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -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; } |