1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (C) 2019 Samsung Electronics Co., Ltd.
4 */
5
6 #ifndef __KSMBD_WORK_H__
7 #define __KSMBD_WORK_H__
8
9 #include <linux/ctype.h>
10 #include <linux/workqueue.h>
11
12 struct ksmbd_conn;
13 struct ksmbd_session;
14 struct ksmbd_tree_connect;
15
16 enum {
17 KSMBD_WORK_ACTIVE = 0,
18 KSMBD_WORK_CANCELLED,
19 KSMBD_WORK_CLOSED,
20 };
21
22 struct aux_read {
23 void *buf;
24 struct list_head entry;
25 };
26
27 /* one of these for every pending CIFS request at the connection */
28 struct ksmbd_work {
29 /* Server corresponding to this mid */
30 struct ksmbd_conn *conn;
31 struct ksmbd_session *sess;
32 struct ksmbd_tree_connect *tcon;
33
34 /* Pointer to received SMB header */
35 void *request_buf;
36 /* Response buffer */
37 void *response_buf;
38
39 struct list_head aux_read_list;
40
41 struct kvec *iov;
42 int iov_alloc_cnt;
43 int iov_cnt;
44 int iov_idx;
45
46 /* Next cmd hdr in compound req buf*/
47 int next_smb2_rcv_hdr_off;
48 /* Next cmd hdr in compound rsp buf*/
49 int next_smb2_rsp_hdr_off;
50 /* Current cmd hdr in compound rsp buf*/
51 int curr_smb2_rsp_hdr_off;
52
53 /*
54 * Current Local FID assigned compound response if SMB2 CREATE
55 * command is present in compound request
56 */
57 u64 compound_fid;
58 u64 compound_pfid;
59 u64 compound_sid;
60
61 const struct cred *saved_cred;
62
63 /* Number of granted credits */
64 unsigned int credits_granted;
65
66 /* response smb header size */
67 unsigned int response_sz;
68
69 void *tr_buf;
70
71 unsigned char state;
72 /* No response for cancelled request */
73 bool send_no_response:1;
74 /* Request is encrypted */
75 bool encrypted:1;
76 /* Is this SYNC or ASYNC ksmbd_work */
77 bool asynchronous:1;
78 bool need_invalidate_rkey:1;
79
80 unsigned int remote_key;
81 /* cancel works */
82 int async_id;
83 void **cancel_argv;
84 void (*cancel_fn)(void **argv);
85
86 struct work_struct work;
87 /* List head at conn->requests */
88 struct list_head request_entry;
89 /* List head at conn->async_requests */
90 struct list_head async_request_entry;
91 struct list_head fp_entry;
92 };
93
94 /**
95 * ksmbd_resp_buf_next - Get next buffer on compound response.
96 * @work: smb work containing response buffer
97 */
ksmbd_resp_buf_next(struct ksmbd_work * work)98 static inline void *ksmbd_resp_buf_next(struct ksmbd_work *work)
99 {
100 return work->response_buf + work->next_smb2_rsp_hdr_off + 4;
101 }
102
103 /**
104 * ksmbd_resp_buf_curr - Get current buffer on compound response.
105 * @work: smb work containing response buffer
106 */
ksmbd_resp_buf_curr(struct ksmbd_work * work)107 static inline void *ksmbd_resp_buf_curr(struct ksmbd_work *work)
108 {
109 return work->response_buf + work->curr_smb2_rsp_hdr_off + 4;
110 }
111
112 /**
113 * ksmbd_req_buf_next - Get next buffer on compound request.
114 * @work: smb work containing response buffer
115 */
ksmbd_req_buf_next(struct ksmbd_work * work)116 static inline void *ksmbd_req_buf_next(struct ksmbd_work *work)
117 {
118 return work->request_buf + work->next_smb2_rcv_hdr_off + 4;
119 }
120
121 struct ksmbd_work *ksmbd_alloc_work_struct(void);
122 void ksmbd_free_work_struct(struct ksmbd_work *work);
123
124 void ksmbd_work_pool_destroy(void);
125 int ksmbd_work_pool_init(void);
126
127 int ksmbd_workqueue_init(void);
128 void ksmbd_workqueue_destroy(void);
129 bool ksmbd_queue_work(struct ksmbd_work *work);
130 int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len,
131 void *aux_buf, unsigned int aux_size);
132 int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len);
133 int allocate_interim_rsp_buf(struct ksmbd_work *work);
134 #endif /* __KSMBD_WORK_H__ */
135