1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * fs/hmdfs/comm/socket_adapter.h
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8#ifndef SOCKET_ADAPTER_H
9#define SOCKET_ADAPTER_H
10
11#include <linux/net.h>
12#include <linux/pagemap.h>
13
14#include "connection.h"
15#include "hmdfs.h"
16#include "protocol.h"
17
18#define HMDFS_KEY_SIZE	  32
19#define HMDFS_IV_SIZE	  12
20#define HMDFS_TAG_SIZE	  16
21#define HMDFS_CID_SIZE	  64
22#define INVALID_SOCKET_FD (-1)
23
24#define HMDFS_IDR_RESCHED_COUNT 512
25
26/*****************************************************************************
27 * connections(TCP, UDP, .etc) adapter for RPC
28 *****************************************************************************/
29
30struct work_handler_desp {
31	struct work_struct work;
32	struct hmdfs_peer *peer;
33	struct hmdfs_head_cmd *head;
34	void *buf;
35};
36
37struct work_readfile_request_async {
38	struct work_struct work;
39	struct hmdfs_peer *con;
40	struct hmdfs_send_command sm;
41};
42
43static inline void hmdfs_init_cmd(struct hmdfs_cmd *op, u8 cmd)
44{
45	op->reserved = 0;
46	op->cmd_flag = C_REQUEST;
47	op->command = cmd;
48	op->reserved2 = 0;
49}
50
51int hmdfs_send_async_request(struct hmdfs_peer *peer,
52			     const struct hmdfs_req *req);
53int hmdfs_sendmessage_request(struct hmdfs_peer *con,
54			      struct hmdfs_send_command *msg);
55int hmdfs_sendpage_request(struct hmdfs_peer *con,
56			   struct hmdfs_send_command *msg);
57
58int hmdfs_sendmessage_response(struct hmdfs_peer *con,
59			       struct hmdfs_head_cmd *cmd, __u32 data_len,
60			       void *buf, __u32 ret_code);
61int hmdfs_readfile_response(struct hmdfs_peer *con, struct hmdfs_head_cmd *head,
62			    struct file *filp);
63
64void hmdfs_recv_page_work_fn(struct work_struct *ptr);
65
66/*****************************************************************************
67 * statistics info for RPC
68 *****************************************************************************/
69
70enum hmdfs_resp_type {
71	HMDFS_RESP_NORMAL,
72	HMDFS_RESP_DELAY,
73	HMDFS_RESP_TIMEOUT
74};
75
76struct server_statistic {
77	unsigned long long cnt;		 /* request received */
78	unsigned long long max;		 /* max processing time */
79	unsigned long long total;	 /* total processing time */
80	unsigned long long snd_cnt;      /* resp send to client */
81	unsigned long long snd_fail_cnt; /* send resp to client failed cnt */
82};
83
84struct client_statistic {
85	unsigned long long snd_cnt;	   /* request send to server */
86	unsigned long long resp_cnt;	   /* response receive from server */
87	unsigned long long timeout_cnt;    /* no respone from server */
88	unsigned long long delay_resp_cnt; /* delay response from server */
89	unsigned long long max;            /* max waiting time */
90	unsigned long long total;	   /* total waiting time */
91	unsigned long long snd_fail_cnt;   /* request send failed to server */
92};
93
94
95static inline void hmdfs_statistic(struct hmdfs_sb_info *sbi, u8 cmd,
96				   unsigned long jiff)
97{
98	if (cmd >= F_SIZE)
99		return;
100
101	sbi->s_server_statis[cmd].cnt++;
102	sbi->s_server_statis[cmd].total += jiff;
103	if (jiff > sbi->s_server_statis[cmd].max)
104		sbi->s_server_statis[cmd].max = jiff;
105}
106
107static inline void hmdfs_server_snd_statis(struct hmdfs_sb_info *sbi,
108					   u8 cmd, int ret)
109{
110	if (cmd >= F_SIZE)
111		return;
112	ret ? sbi->s_server_statis[cmd].snd_fail_cnt++ :
113	      sbi->s_server_statis[cmd].snd_cnt++;
114}
115
116static inline void hmdfs_client_snd_statis(struct hmdfs_sb_info *sbi,
117					   u8 cmd, int ret)
118{
119	if (cmd >= F_SIZE)
120		return;
121	ret ? sbi->s_client_statis[cmd].snd_fail_cnt++ :
122	      sbi->s_client_statis[cmd].snd_cnt++;
123}
124
125extern void hmdfs_client_resp_statis(struct hmdfs_sb_info *sbi, u8 cmd,
126				     enum hmdfs_resp_type type,
127				     unsigned long start, unsigned long end);
128
129/*****************************************************************************
130 * timeout configuration for RPC
131 *****************************************************************************/
132
133enum HMDFS_TIME_OUT {
134	TIMEOUT_NONE = 0,
135	TIMEOUT_COMMON = 4,
136	TIMEOUT_6S = 6,
137	TIMEOUT_30S = 30,
138	TIMEOUT_1M = 60,
139	TIMEOUT_90S = 90,
140	TIMEOUT_CONFIG = UINT_MAX - 1, // for hmdfs_req to read from config
141	TIMEOUT_UNINIT = UINT_MAX,
142};
143
144static inline int get_cmd_timeout(struct hmdfs_sb_info *sbi, enum FILE_CMD cmd)
145{
146	return sbi->s_cmd_timeout[cmd];
147}
148
149static inline void set_cmd_timeout(struct hmdfs_sb_info *sbi, enum FILE_CMD cmd,
150				   unsigned int value)
151{
152	sbi->s_cmd_timeout[cmd] = value;
153}
154
155void hmdfs_recv_mesg_callback(struct hmdfs_peer *con, void *head, void *buf);
156
157void hmdfs_response_wakeup(struct sendmsg_wait_queue *msg_info,
158			   __u32 ret_code, __u32 data_len, void *buf);
159
160void hmdfs_wakeup_parasite(struct hmdfs_msg_parasite *mp);
161
162void hmdfs_wakeup_async_work(struct hmdfs_async_work *async_work);
163
164void msg_put(struct sendmsg_wait_queue *msg_wq);
165void head_put(struct hmdfs_msg_idr_head *head);
166void mp_put(struct hmdfs_msg_parasite *mp);
167void asw_put(struct hmdfs_async_work *asw);
168static inline void asw_done(struct hmdfs_async_work *asw)
169{
170	if (asw->page)
171		unlock_page(asw->page);
172	asw_put(asw);
173}
174
175static inline void asw_get(struct hmdfs_async_work *asw)
176{
177	kref_get(&asw->head.ref);
178}
179#endif
180