xref: /kernel/linux/linux-5.10/fs/hmdfs/comm/protocol.h (revision 8c2ecf20)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * fs/hmdfs/comm/protocol.h
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8#ifndef HMDFS_PROTOCOL_H
9#define HMDFS_PROTOCOL_H
10
11#include <linux/kref.h>
12#include <linux/wait.h>
13#include <linux/workqueue.h>
14#include <linux/namei.h>
15
16struct hmdfs_cmd {
17	__u8 reserved;
18	__u8 cmd_flag;
19	__u8 command;
20	__u8 reserved2;
21} __packed;
22
23#define HMDFS_MSG_MAGIC	      0xF7
24#define HMDFS_MAX_MESSAGE_LEN (8 * 1024 * 1024)
25
26struct hmdfs_head_cmd {
27	__u8 magic;
28	__u8 version;
29	__le16 reserved;
30	__le32 data_len;
31	struct hmdfs_cmd operations;
32	__le32 ret_code;
33	__le32 msg_id;
34	__le32 reserved1;
35} __packed;
36
37enum FILE_RECV_STATE {
38	FILE_RECV_PROCESS = 0,
39	FILE_RECV_SUCC,
40	FILE_RECV_ERR_NET,
41	FILE_RECV_ERR_SPC,
42};
43
44struct file_recv_info {
45	void *local_filp;
46	atomic_t local_fslices;
47	atomic_t state;
48};
49
50enum MSG_IDR_TYPE {
51	MSG_IDR_1_0_NONE = 0,
52	MSG_IDR_1_0_MESSAGE_SYNC,
53	MSG_IDR_1_0_PAGE,
54	MSG_IDR_MESSAGE_SYNC,
55	MSG_IDR_MESSAGE_ASYNC,
56	MSG_IDR_PAGE,
57	MSG_IDR_MAX,
58};
59
60struct hmdfs_msg_idr_head {
61	__u32 type;
62	__u32 msg_id;
63	struct hmdfs_cmd send_cmd_operations;
64	struct kref ref;
65	struct hmdfs_peer *peer;
66};
67
68struct sendmsg_wait_queue {
69	struct hmdfs_msg_idr_head head;
70	wait_queue_head_t response_q;
71	struct list_head async_msg;
72	atomic_t valid;
73	__u32 size;
74	void *buf;
75	__u32 ret;
76	unsigned long start;
77	struct file_recv_info recv_info;
78};
79
80struct hmdfs_send_command {
81	struct hmdfs_cmd operations;
82	void *data;
83	size_t len;
84	void *local_filp;
85	void *out_buf;
86	size_t out_len;
87	__u32 ret_code;
88};
89
90struct hmdfs_req {
91	struct hmdfs_cmd operations;
92	/*
93	 * Normally, the caller ought set timeout to TIMEOUT_CONFIG, so that
94	 * hmdfs_send_async_request will search s_cmd_timeout for the user-
95	 * configured timeout values.
96	 *
97	 * However, consider the given scenery:
98	 * The caller may want to issue multiple requests sharing the same
99	 * timeout value, but the users may update the value during the gap.
100	 * To ensure the "atomicty" of timeout-using for these requests, we
101	 * provide the timeout field for hacking.
102	 */
103	unsigned int timeout;
104	void *data;
105	size_t data_len;
106
107	void *private; // optional
108	size_t private_len; // optional
109};
110
111struct hmdfs_resp {
112	void *out_buf;
113	size_t out_len;
114	__u32 ret_code;
115};
116
117struct hmdfs_msg_parasite {
118	struct hmdfs_msg_idr_head head;
119	struct delayed_work d_work;
120	bool wfired;
121	struct hmdfs_req req;
122	struct hmdfs_resp resp;
123	unsigned long start;
124};
125
126struct hmdfs_send_data {
127	// sect1: head
128	void *head;
129	size_t head_len;
130
131	// sect2: <optional> slice descriptor
132	void *sdesc;
133	size_t sdesc_len;
134
135	// sect3: request / response / file slice
136	void *data;
137	size_t len;
138};
139
140struct slice_descriptor {
141	__le32 num_slices;
142	__le32 slice_size;
143	__le32 slice_sn;
144	__le32 content_size;
145} __packed;
146
147enum DFS_VERSION {
148	HMDFS_VERSION = 0x40,
149	MAX_VERSION = 0xFF
150};
151
152enum CMD_FLAG { C_REQUEST = 0, C_RESPONSE = 1, C_FLAG_SIZE };
153
154enum FILE_CMD {
155	F_OPEN = 0,
156	F_RELEASE = 1,
157	F_READPAGE = 2,
158	F_WRITEPAGE = 3,
159	F_ITERATE = 4,
160	F_RESERVED_1 = 5,
161	F_RESERVED_2 = 6,
162	F_RESERVED_3 = 7,
163	F_RESERVED_4 = 8,
164	F_MKDIR = 9,
165	F_RMDIR = 10,
166	F_CREATE = 11,
167	F_UNLINK = 12,
168	F_RENAME = 13,
169	F_SETATTR = 14,
170	F_RESERVED_5 = 15,
171	F_STATFS = 16,
172	F_CONNECT_REKEY = 17,
173	F_DROP_PUSH = 18,
174	F_RESERVED_6 = 19,
175	F_GETATTR = 20,
176	F_FSYNC = 21,
177	F_SYNCFS = 22,
178	F_GETXATTR = 23,
179	F_SETXATTR = 24,
180	F_LISTXATTR = 25,
181	F_RESERVED_7 = 26,
182	F_RESERVED_8 = 27,
183	F_ATOMIC_OPEN = 28,
184	F_SIZE,
185};
186
187struct open_request {
188	__u8 file_type;
189	__le32 flags;
190	__le32 path_len;
191	char buf[0];
192} __packed;
193
194struct open_response {
195	__le32 change_detect_cap;
196	__le64 file_ver;
197	__le32 file_id;
198	__le64 file_size;
199	__le64 ino;
200	__le64 ctime;
201	__le32 ctime_nsec;
202	__le64 mtime;
203	__le32 mtime_nsec;
204	__le64 stable_ctime;
205	__le32 stable_ctime_nsec;
206	__le64 ichange_count;
207} __packed;
208
209enum hmdfs_open_flags {
210	HMDFS_O_TRUNC = O_TRUNC,
211	HMDFS_O_EXCL = O_EXCL,
212};
213
214struct atomic_open_request {
215	__le32 open_flags;
216	__le16 mode;
217	__le16 reserved1;
218	__le32 path_len;
219	__le32 file_len;
220	__le64 reserved2[4];
221	char buf[0];
222} __packed;
223
224struct atomic_open_response {
225	__le32 fno;
226	__le16 i_mode;
227	__le16 reserved1;
228	__le32 i_flags;
229	__le32 reserved2;
230	__le64 reserved3[4];
231	struct open_response open_resp;
232} __packed;
233
234struct release_request {
235	__le64 file_ver;
236	__le32 file_id;
237} __packed;
238
239struct fsync_request {
240	__le64 file_ver;
241	__le32 file_id;
242	__le32 datasync;
243	__le64 start;
244	__le64 end;
245} __packed;
246
247struct readpage_request {
248	__le64 file_ver;
249	__le32 file_id;
250	__le32 size;
251	__le64 index;
252} __packed;
253
254struct readpage_response {
255	char buf[0];
256} __packed;
257
258struct writepage_request {
259	__le64 file_ver;
260	__le32 file_id;
261	__le64 index;
262	__le32 count;
263	char buf[0];
264} __packed;
265
266struct writepage_response {
267	__le64 ichange_count;
268	__le64 ctime;
269	__le32 ctime_nsec;
270} __packed;
271
272struct readdir_request {
273	__le64 dcache_crtime;
274	__le64 dcache_crtime_nsec;
275	__le64 dentry_ctime;
276	__le64 dentry_ctime_nsec;
277	__le64 num;
278	__le32 verify_cache;
279	__le32 path_len;
280	char path[0];
281} __packed;
282
283struct hmdfs_inodeinfo_response {
284	__le64 i_size;
285	__le64 i_mtime;
286	__le32 i_mtime_nsec;
287	__le32 fno;
288	__le16 i_mode;
289	__le64 i_ino;
290	__le32 i_flags;
291	__le32 i_reserved;
292} __packed;
293
294struct mkdir_request {
295	__le32 path_len;
296	__le32 name_len;
297	__le16 mode;
298	char path[0];
299} __packed;
300
301struct create_request {
302	__le32 path_len;
303	__le32 name_len;
304	__le16 mode;
305	__u8 want_excl;
306	char path[0];
307} __packed;
308
309struct rmdir_request {
310	__le32 path_len;
311	__le32 name_len;
312	char path[0];
313} __packed;
314
315struct unlink_request {
316	__le32 path_len;
317	__le32 name_len;
318	char path[0];
319} __packed;
320
321struct rename_request {
322	__le32 old_path_len;
323	__le32 new_path_len;
324	__le32 old_name_len;
325	__le32 new_name_len;
326	__le32 flags;
327	char path[0];
328} __packed;
329
330struct drop_push_request {
331	__le32 path_len;
332	char path[0];
333} __packed;
334
335struct setattr_request {
336	__le64 size;
337	__le32 valid;
338	__le16 mode;
339	__le32 uid;
340	__le32 gid;
341	__le64 atime;
342	__le32 atime_nsec;
343	__le64 mtime;
344	__le32 mtime_nsec;
345	__le32 path_len;
346	char buf[0];
347} __packed;
348
349struct getattr_request {
350	__le32 lookup_flags;
351	__le32 path_len;
352	char buf[0];
353} __packed;
354
355struct getattr_response {
356	__le32 change_detect_cap;
357	__le32 result_mask;
358	__le32 flags;
359	__le64 fsid;
360	__le16 mode;
361	__le32 nlink;
362	__le32 uid;
363	__le32 gid;
364	__le32 rdev;
365	__le64 ino;
366	__le64 size;
367	__le64 blocks;
368	__le32 blksize;
369	__le64 atime;
370	__le32 atime_nsec;
371	__le64 mtime;
372	__le32 mtime_nsec;
373	__le64 ctime;
374	__le32 ctime_nsec;
375	__le64 crtime;
376	__le32 crtime_nsec;
377	__le64 ichange_count;
378} __packed;
379
380struct statfs_request {
381	__le32 path_len;
382	char path[0];
383} __packed;
384
385struct statfs_response {
386	__le64 f_type;
387	__le64 f_bsize;
388	__le64 f_blocks;
389	__le64 f_bfree;
390	__le64 f_bavail;
391	__le64 f_files;
392	__le64 f_ffree;
393	__le32 f_fsid_0;
394	__le32 f_fsid_1;
395	__le64 f_namelen;
396	__le64 f_frsize;
397	__le64 f_flags;
398	__le64 f_spare_0;
399	__le64 f_spare_1;
400	__le64 f_spare_2;
401	__le64 f_spare_3;
402} __packed;
403
404struct syncfs_request {
405	__le64 version;
406	__le32 flags;
407} __packed;
408
409struct getxattr_request {
410	__le32 path_len;
411	__le32 name_len;
412	__le32 size;
413	char buf[0];
414} __packed;
415
416struct getxattr_response {
417	__le32 size;
418	char value[0]; /* xattr value may non-printable */
419} __packed;
420
421struct setxattr_request {
422	__le32 path_len;
423	__le32 name_len;
424	__le32 size;
425	__le32 flags;
426	__u8 del; /* remove xattr */
427	char buf[0];
428} __packed;
429
430struct listxattr_request {
431	__le32 path_len;
432	__le32 size;
433	char buf[0];
434} __packed;
435
436struct listxattr_response {
437	__le32 size;
438	char list[0];
439} __packed;
440
441struct connection_rekey_request {
442	__le32 update_request;
443} __packed;
444
445enum CONNECTION_KEY_UPDATE_REQUEST {
446	UPDATE_NOT_REQUESTED = 0,
447	UPDATE_REQUESTED = 1
448};
449
450enum MSG_QUEUE_STATUS {
451	MSG_Q_SEND = 0,
452	MSG_Q_END_RECV,
453};
454#endif
455