Merge tag 'cgroup-for-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[linux-2.6-microblaze.git] / fs / ksmbd / connection.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
4  */
5
6 #ifndef __KSMBD_CONNECTION_H__
7 #define __KSMBD_CONNECTION_H__
8
9 #include <linux/list.h>
10 #include <linux/ip.h>
11 #include <net/sock.h>
12 #include <net/tcp.h>
13 #include <net/inet_connection_sock.h>
14 #include <net/request_sock.h>
15 #include <linux/kthread.h>
16 #include <linux/nls.h>
17 #include <linux/unicode.h>
18
19 #include "smb_common.h"
20 #include "ksmbd_work.h"
21
22 #define KSMBD_SOCKET_BACKLOG            16
23
24 enum {
25         KSMBD_SESS_NEW = 0,
26         KSMBD_SESS_GOOD,
27         KSMBD_SESS_EXITING,
28         KSMBD_SESS_NEED_RECONNECT,
29         KSMBD_SESS_NEED_NEGOTIATE
30 };
31
32 struct ksmbd_stats {
33         atomic_t                        open_files_count;
34         atomic64_t                      request_served;
35 };
36
37 struct ksmbd_transport;
38
39 struct ksmbd_conn {
40         struct smb_version_values       *vals;
41         struct smb_version_ops          *ops;
42         struct smb_version_cmds         *cmds;
43         unsigned int                    max_cmds;
44         struct mutex                    srv_mutex;
45         int                             status;
46         unsigned int                    cli_cap;
47         char                            *request_buf;
48         struct ksmbd_transport          *transport;
49         struct nls_table                *local_nls;
50         struct unicode_map              *um;
51         struct list_head                conns_list;
52         /* smb session 1 per user */
53         struct xarray                   sessions;
54         unsigned long                   last_active;
55         /* How many request are running currently */
56         atomic_t                        req_running;
57         /* References which are made for this Server object*/
58         atomic_t                        r_count;
59         unsigned int                    total_credits;
60         unsigned int                    outstanding_credits;
61         spinlock_t                      credits_lock;
62         wait_queue_head_t               req_running_q;
63         wait_queue_head_t               r_count_q;
64         /* Lock to protect requests list*/
65         spinlock_t                      request_lock;
66         struct list_head                requests;
67         struct list_head                async_requests;
68         int                             connection_type;
69         struct ksmbd_stats              stats;
70         char                            ClientGUID[SMB2_CLIENT_GUID_SIZE];
71         struct ntlmssp_auth             ntlmssp;
72
73         spinlock_t                      llist_lock;
74         struct list_head                lock_list;
75
76         struct preauth_integrity_info   *preauth_info;
77
78         bool                            need_neg;
79         unsigned int                    auth_mechs;
80         unsigned int                    preferred_auth_mech;
81         bool                            sign;
82         bool                            use_spnego:1;
83         __u16                           cli_sec_mode;
84         __u16                           srv_sec_mode;
85         /* dialect index that server chose */
86         __u16                           dialect;
87
88         char                            *mechToken;
89
90         struct ksmbd_conn_ops   *conn_ops;
91
92         /* Preauth Session Table */
93         struct list_head                preauth_sess_table;
94
95         struct sockaddr_storage         peer_addr;
96
97         /* Identifier for async message */
98         struct ida                      async_ida;
99
100         __le16                          cipher_type;
101         __le16                          compress_algorithm;
102         bool                            posix_ext_supported;
103         bool                            signing_negotiated;
104         __le16                          signing_algorithm;
105         bool                            binding;
106 };
107
108 struct ksmbd_conn_ops {
109         int     (*process_fn)(struct ksmbd_conn *conn);
110         int     (*terminate_fn)(struct ksmbd_conn *conn);
111 };
112
113 struct ksmbd_transport_ops {
114         int (*prepare)(struct ksmbd_transport *t);
115         void (*disconnect)(struct ksmbd_transport *t);
116         void (*shutdown)(struct ksmbd_transport *t);
117         int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
118         int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
119                       int size, bool need_invalidate_rkey,
120                       unsigned int remote_key);
121         int (*rdma_read)(struct ksmbd_transport *t,
122                          void *buf, unsigned int len,
123                          struct smb2_buffer_desc_v1 *desc,
124                          unsigned int desc_len);
125         int (*rdma_write)(struct ksmbd_transport *t,
126                           void *buf, unsigned int len,
127                           struct smb2_buffer_desc_v1 *desc,
128                           unsigned int desc_len);
129 };
130
131 struct ksmbd_transport {
132         struct ksmbd_conn               *conn;
133         struct ksmbd_transport_ops      *ops;
134         struct task_struct              *handler;
135 };
136
137 #define KSMBD_TCP_RECV_TIMEOUT  (7 * HZ)
138 #define KSMBD_TCP_SEND_TIMEOUT  (5 * HZ)
139 #define KSMBD_TCP_PEER_SOCKADDR(c)      ((struct sockaddr *)&((c)->peer_addr))
140
141 extern struct list_head conn_list;
142 extern rwlock_t conn_list_lock;
143
144 bool ksmbd_conn_alive(struct ksmbd_conn *conn);
145 void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
146 struct ksmbd_conn *ksmbd_conn_alloc(void);
147 void ksmbd_conn_free(struct ksmbd_conn *conn);
148 bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
149 int ksmbd_conn_write(struct ksmbd_work *work);
150 int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
151                          void *buf, unsigned int buflen,
152                          struct smb2_buffer_desc_v1 *desc,
153                          unsigned int desc_len);
154 int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
155                           void *buf, unsigned int buflen,
156                           struct smb2_buffer_desc_v1 *desc,
157                           unsigned int desc_len);
158 void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
159 int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
160 void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
161 int ksmbd_conn_handler_loop(void *p);
162 int ksmbd_conn_transport_init(void);
163 void ksmbd_conn_transport_destroy(void);
164
165 /*
166  * WARNING
167  *
168  * This is a hack. We will move status to a proper place once we land
169  * a multi-sessions support.
170  */
171 static inline bool ksmbd_conn_good(struct ksmbd_work *work)
172 {
173         return work->conn->status == KSMBD_SESS_GOOD;
174 }
175
176 static inline bool ksmbd_conn_need_negotiate(struct ksmbd_work *work)
177 {
178         return work->conn->status == KSMBD_SESS_NEED_NEGOTIATE;
179 }
180
181 static inline bool ksmbd_conn_need_reconnect(struct ksmbd_work *work)
182 {
183         return work->conn->status == KSMBD_SESS_NEED_RECONNECT;
184 }
185
186 static inline bool ksmbd_conn_exiting(struct ksmbd_work *work)
187 {
188         return work->conn->status == KSMBD_SESS_EXITING;
189 }
190
191 static inline void ksmbd_conn_set_good(struct ksmbd_work *work)
192 {
193         work->conn->status = KSMBD_SESS_GOOD;
194 }
195
196 static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_work *work)
197 {
198         work->conn->status = KSMBD_SESS_NEED_NEGOTIATE;
199 }
200
201 static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_work *work)
202 {
203         work->conn->status = KSMBD_SESS_NEED_RECONNECT;
204 }
205
206 static inline void ksmbd_conn_set_exiting(struct ksmbd_work *work)
207 {
208         work->conn->status = KSMBD_SESS_EXITING;
209 }
210 #endif /* __CONNECTION_H__ */