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 struct list_head interim_entry;
93 };
94
95 /**
96 * ksmbd_resp_buf_next - Get next buffer on compound response.
97 * @work: smb work containing response buffer
98 */
ksmbd_resp_buf_next(struct ksmbd_work * work)99 static inline void *ksmbd_resp_buf_next(struct ksmbd_work *work)
100 {
101 return work->response_buf + work->next_smb2_rsp_hdr_off + 4;
102 }
103
104 /**
105 * ksmbd_resp_buf_curr - Get current buffer on compound response.
106 * @work: smb work containing response buffer
107 */
ksmbd_resp_buf_curr(struct ksmbd_work * work)108 static inline void *ksmbd_resp_buf_curr(struct ksmbd_work *work)
109 {
110 return work->response_buf + work->curr_smb2_rsp_hdr_off + 4;
111 }
112
113 /**
114 * ksmbd_req_buf_next - Get next buffer on compound request.
115 * @work: smb work containing response buffer
116 */
ksmbd_req_buf_next(struct ksmbd_work * work)117 static inline void *ksmbd_req_buf_next(struct ksmbd_work *work)
118 {
119 return work->request_buf + work->next_smb2_rcv_hdr_off + 4;
120 }
121
122 struct ksmbd_work *ksmbd_alloc_work_struct(void);
123 void ksmbd_free_work_struct(struct ksmbd_work *work);
124
125 void ksmbd_work_pool_destroy(void);
126 int ksmbd_work_pool_init(void);
127
128 int ksmbd_workqueue_init(void);
129 void ksmbd_workqueue_destroy(void);
130 bool ksmbd_queue_work(struct ksmbd_work *work);
131 int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len,
132 void *aux_buf, unsigned int aux_size);
133 int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len);
134 int allocate_interim_rsp_buf(struct ksmbd_work *work);
135 #endif /* __KSMBD_WORK_H__ */
136