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