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