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