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 struct connection_operations {
27 void (*recvmsg)(struct hmdfs_peer *con, void *head, void *buf);
28 void (*recvpage)(struct hmdfs_peer *con, struct hmdfs_head_cmd *head,
29 int err, void *data);
30 const struct file_operations *remote_file_fops;
31 const struct inode_operations *remote_file_iops;
32 const struct address_space_operations *remote_file_aops;
33 int (*remote_unlink)(struct hmdfs_peer *con, struct dentry *dentry);
34 int (*remote_readdir)(struct hmdfs_peer *con, struct file *file,
35 struct dir_context *ctx);
36 struct hmdfs_lookup_ret *(*remote_lookup)(struct hmdfs_peer *con,
37 const char *relative_path,
38 const char *d_name);
39 };
40
41 /*****************************************************************************
42 * connections(TCP, UDP, .etc) adapter for RPC
43 *****************************************************************************/
44
45 struct work_handler_desp {
46 struct work_struct work;
47 struct hmdfs_peer *peer;
48 struct hmdfs_head_cmd *head;
49 void *buf;
50 };
51
52 struct work_readfile_request_async {
53 struct work_struct work;
54 struct hmdfs_peer *con;
55 struct hmdfs_send_command sm;
56 };
57
hmdfs_init_cmd(struct hmdfs_cmd * op,u8 cmd)58 static inline void hmdfs_init_cmd(struct hmdfs_cmd *op, u8 cmd)
59 {
60 op->reserved = 0;
61 op->cmd_flag = C_REQUEST;
62 op->command = cmd;
63 op->reserved2 = 0;
64 }
65
66 int hmdfs_send_async_request(struct hmdfs_peer *peer,
67 const struct hmdfs_req *req);
68 int hmdfs_sendmessage_request(struct hmdfs_peer *con,
69 struct hmdfs_send_command *msg);
70 int hmdfs_sendpage_request(struct hmdfs_peer *con,
71 struct hmdfs_send_command *msg);
72
73 int hmdfs_sendmessage_response(struct hmdfs_peer *con,
74 struct hmdfs_head_cmd *cmd, __u32 data_len,
75 void *buf, __u32 ret_code);
76 int hmdfs_readfile_response(struct hmdfs_peer *con, struct hmdfs_head_cmd *head,
77 struct file *filp);
78 const struct connection_operations *hmdfs_get_peer_operation(__u8 version);
79
80 void hmdfs_recv_page_work_fn(struct work_struct *ptr);
81
82 /*****************************************************************************
83 * statistics info for RPC
84 *****************************************************************************/
85
86 enum hmdfs_resp_type {
87 HMDFS_RESP_NORMAL,
88 HMDFS_RESP_DELAY,
89 HMDFS_RESP_TIMEOUT
90 };
91
92 struct server_statistic {
93 unsigned long long cnt; /* request received */
94 unsigned long long max; /* max processing time */
95 unsigned long long total; /* total processing time */
96 unsigned long long snd_cnt; /* resp send to client */
97 unsigned long long snd_fail_cnt; /* send resp to client failed cnt */
98 };
99
100 struct client_statistic {
101 unsigned long long snd_cnt; /* request send to server */
102 unsigned long long resp_cnt; /* response receive from server */
103 unsigned long long timeout_cnt; /* no respone from server */
104 unsigned long long delay_resp_cnt; /* delay response from server */
105 unsigned long long max; /* max waiting time */
106 unsigned long long total; /* total waiting time */
107 unsigned long long snd_fail_cnt; /* request send failed to server */
108 };
109
110
hmdfs_statistic(struct hmdfs_sb_info * sbi,u8 cmd,unsigned long jiff)111 static inline void hmdfs_statistic(struct hmdfs_sb_info *sbi, u8 cmd,
112 unsigned long jiff)
113 {
114 if (cmd >= F_SIZE)
115 return;
116
117 sbi->s_server_statis[cmd].cnt++;
118 sbi->s_server_statis[cmd].total += jiff;
119 if (jiff > sbi->s_server_statis[cmd].max)
120 sbi->s_server_statis[cmd].max = jiff;
121 }
122
hmdfs_server_snd_statis(struct hmdfs_sb_info * sbi,u8 cmd,int ret)123 static inline void hmdfs_server_snd_statis(struct hmdfs_sb_info *sbi,
124 u8 cmd, int ret)
125 {
126 if (cmd >= F_SIZE)
127 return;
128 ret ? sbi->s_server_statis[cmd].snd_fail_cnt++ :
129 sbi->s_server_statis[cmd].snd_cnt++;
130 }
131
hmdfs_client_snd_statis(struct hmdfs_sb_info * sbi,u8 cmd,int ret)132 static inline void hmdfs_client_snd_statis(struct hmdfs_sb_info *sbi,
133 u8 cmd, int ret)
134 {
135 if (cmd >= F_SIZE)
136 return;
137 ret ? sbi->s_client_statis[cmd].snd_fail_cnt++ :
138 sbi->s_client_statis[cmd].snd_cnt++;
139 }
140
141 extern void hmdfs_client_resp_statis(struct hmdfs_sb_info *sbi, u8 cmd,
142 enum hmdfs_resp_type type,
143 unsigned long start, unsigned long end);
144
145 /*****************************************************************************
146 * timeout configuration for RPC
147 *****************************************************************************/
148
149 enum HMDFS_TIME_OUT {
150 TIMEOUT_NONE = 0,
151 TIMEOUT_COMMON = 4,
152 TIMEOUT_6S = 6,
153 TIMEOUT_30S = 30,
154 TIMEOUT_1M = 60,
155 TIMEOUT_90S = 90,
156 TIMEOUT_CONFIG = UINT_MAX - 1, // for hmdfs_req to read from config
157 TIMEOUT_UNINIT = UINT_MAX,
158 };
159
get_cmd_timeout(struct hmdfs_sb_info * sbi,enum FILE_CMD cmd)160 static inline int get_cmd_timeout(struct hmdfs_sb_info *sbi, enum FILE_CMD cmd)
161 {
162 return sbi->s_cmd_timeout[cmd];
163 }
164
set_cmd_timeout(struct hmdfs_sb_info * sbi,enum FILE_CMD cmd,unsigned int value)165 static inline void set_cmd_timeout(struct hmdfs_sb_info *sbi, enum FILE_CMD cmd,
166 unsigned int value)
167 {
168 sbi->s_cmd_timeout[cmd] = value;
169 }
170
171 void hmdfs_response_wakeup(struct sendmsg_wait_queue *msg_info,
172 __u32 ret_code, __u32 data_len, void *buf);
173
174 void hmdfs_wakeup_parasite(struct hmdfs_msg_parasite *mp);
175
176 void hmdfs_wakeup_async_work(struct hmdfs_async_work *async_work);
177
178 void msg_put(struct sendmsg_wait_queue *msg_wq);
179 void head_put(struct hmdfs_msg_idr_head *head);
180 void mp_put(struct hmdfs_msg_parasite *mp);
181 void asw_put(struct hmdfs_async_work *asw);
asw_done(struct hmdfs_async_work * asw)182 static inline void asw_done(struct hmdfs_async_work *asw)
183 {
184 if (asw->page)
185 unlock_page(asw->page);
186 asw_put(asw);
187 }
188
asw_get(struct hmdfs_async_work * asw)189 static inline void asw_get(struct hmdfs_async_work *asw)
190 {
191 kref_get(&asw->head.ref);
192 }
193 #endif
194