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 hmdfs_cmd send_cmd_operations; 64 struct kref ref; 65 struct hmdfs_peer *peer; 66 }; 67 68 struct 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 80 struct 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 90 struct 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 111 struct hmdfs_resp { 112 void *out_buf; 113 size_t out_len; 114 __u32 ret_code; 115 }; 116 117 struct 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 126 struct 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 140 struct slice_descriptor { 141 __le32 num_slices; 142 __le32 slice_size; 143 __le32 slice_sn; 144 __le32 content_size; 145 } __packed; 146 147 enum DFS_VERSION { 148 HMDFS_VERSION = 0x40, 149 MAX_VERSION = 0xFF 150 }; 151 152 enum CMD_FLAG { C_REQUEST = 0, C_RESPONSE = 1, C_FLAG_SIZE }; 153 154 enum 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 187 struct open_request { 188 __u8 file_type; 189 __le32 flags; 190 __le32 path_len; 191 char buf[0]; 192 } __packed; 193 194 struct 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 209 enum hmdfs_open_flags { 210 HMDFS_O_TRUNC = O_TRUNC, 211 HMDFS_O_EXCL = O_EXCL, 212 }; 213 214 struct 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 224 struct 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 234 struct release_request { 235 __le64 file_ver; 236 __le32 file_id; 237 } __packed; 238 239 struct fsync_request { 240 __le64 file_ver; 241 __le32 file_id; 242 __le32 datasync; 243 __le64 start; 244 __le64 end; 245 } __packed; 246 247 struct readpage_request { 248 __le64 file_ver; 249 __le32 file_id; 250 __le32 size; 251 __le64 index; 252 } __packed; 253 254 struct readpage_response { 255 char buf[0]; 256 } __packed; 257 258 struct writepage_request { 259 __le64 file_ver; 260 __le32 file_id; 261 __le64 index; 262 __le32 count; 263 char buf[0]; 264 } __packed; 265 266 struct writepage_response { 267 __le64 ichange_count; 268 __le64 ctime; 269 __le32 ctime_nsec; 270 } __packed; 271 272 struct 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 283 struct 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 294 struct mkdir_request { 295 __le32 path_len; 296 __le32 name_len; 297 __le16 mode; 298 char path[0]; 299 } __packed; 300 301 struct create_request { 302 __le32 path_len; 303 __le32 name_len; 304 __le16 mode; 305 __u8 want_excl; 306 char path[0]; 307 } __packed; 308 309 struct rmdir_request { 310 __le32 path_len; 311 __le32 name_len; 312 char path[0]; 313 } __packed; 314 315 struct unlink_request { 316 __le32 path_len; 317 __le32 name_len; 318 char path[0]; 319 } __packed; 320 321 struct 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 330 struct drop_push_request { 331 __le32 path_len; 332 char path[0]; 333 } __packed; 334 335 struct 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 349 struct getattr_request { 350 __le32 lookup_flags; 351 __le32 path_len; 352 char buf[0]; 353 } __packed; 354 355 struct 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 380 struct statfs_request { 381 __le32 path_len; 382 char path[0]; 383 } __packed; 384 385 struct 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 404 struct syncfs_request { 405 __le64 version; 406 __le32 flags; 407 } __packed; 408 409 struct getxattr_request { 410 __le32 path_len; 411 __le32 name_len; 412 __le32 size; 413 char buf[0]; 414 } __packed; 415 416 struct getxattr_response { 417 __le32 size; 418 char value[0]; /* xattr value may non-printable */ 419 } __packed; 420 421 struct 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 430 struct listxattr_request { 431 __le32 path_len; 432 __le32 size; 433 char buf[0]; 434 } __packed; 435 436 struct listxattr_response { 437 __le32 size; 438 char list[0]; 439 } __packed; 440 441 struct connection_rekey_request { 442 __le32 update_request; 443 } __packed; 444 445 enum CONNECTION_KEY_UPDATE_REQUEST { 446 UPDATE_NOT_REQUESTED = 0, 447 UPDATE_REQUESTED = 1 448 }; 449 450 enum MSG_QUEUE_STATUS { 451 MSG_Q_SEND = 0, 452 MSG_Q_END_RECV, 453 }; 454 #endif 455