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
12struct ksmbd_conn;
13struct ksmbd_session;
14struct ksmbd_tree_connect;
15
16enum {
17	KSMBD_WORK_ACTIVE = 0,
18	KSMBD_WORK_CANCELLED,
19	KSMBD_WORK_CLOSED,
20};
21
22struct aux_read {
23	void *buf;
24	struct list_head entry;
25};
26
27/* one of these for every pending CIFS request at the connection */
28struct 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 */
99static 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 */
108static 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 */
117static 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
122struct ksmbd_work *ksmbd_alloc_work_struct(void);
123void ksmbd_free_work_struct(struct ksmbd_work *work);
124
125void ksmbd_work_pool_destroy(void);
126int ksmbd_work_pool_init(void);
127
128int ksmbd_workqueue_init(void);
129void ksmbd_workqueue_destroy(void);
130bool ksmbd_queue_work(struct ksmbd_work *work);
131int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len,
132			   void *aux_buf, unsigned int aux_size);
133int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len);
134int allocate_interim_rsp_buf(struct ksmbd_work *work);
135#endif /* __KSMBD_WORK_H__ */
136