1 /* 2 * Copyright (c) 2025 Antmicro <www.antmicro.com> 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /* 8 * This header provides helper functions to pack FUSE client requests. Note the client is the 9 * side which initiates these requests, and that in a typical FUSE usage the client would be 10 * the Linux kernel. While in Zephyr's case this is to enable functionality like the embedded 11 * virtiofs client connecting to a virtiofsd daemon running in the host. 12 */ 13 14 #ifndef ZEPHYR_SUBSYS_FS_FUSE_CLIENT_H_ 15 #define ZEPHYR_SUBSYS_FS_FUSE_CLIENT_H_ 16 #include <stdint.h> 17 #include "fuse_abi.h" 18 19 /* 20 * requests are put into structs to leverage the fact that they are contiguous in memory and can 21 * be passed to virtqueue as smaller amount of buffers, e.g. in_header + init_in can be sent as 22 * a single buffer containing both of them instead of two separate buffers 23 */ 24 25 struct fuse_init_req { 26 struct fuse_in_header in_header; 27 struct fuse_init_in init_in; 28 struct fuse_out_header out_header; 29 struct fuse_init_out init_out; 30 }; 31 32 struct fuse_open_req { 33 struct fuse_in_header in_header; 34 struct fuse_open_in open_in; 35 struct fuse_out_header out_header; 36 struct fuse_open_out open_out; 37 }; 38 39 struct fuse_create_req { 40 struct fuse_in_header in_header; 41 struct fuse_create_in create_in; 42 struct fuse_out_header out_header; 43 struct fuse_create_out create_out; 44 }; 45 46 struct fuse_write_req { 47 struct fuse_in_header in_header; 48 struct fuse_write_in write_in; 49 struct fuse_out_header out_header; 50 struct fuse_write_out write_out; 51 }; 52 53 struct fuse_lseek_req { 54 struct fuse_in_header in_header; 55 struct fuse_lseek_in lseek_in; 56 struct fuse_out_header out_header; 57 struct fuse_lseek_out lseek_out; 58 }; 59 60 struct fuse_mkdir_req { 61 struct fuse_in_header in_header; 62 struct fuse_mkdir_in mkdir_in; 63 struct fuse_out_header out_header; 64 struct fuse_entry_out entry_out; 65 }; 66 67 struct fuse_lookup_req { 68 struct fuse_in_header in_header; 69 struct fuse_out_header out_header; 70 struct fuse_entry_out entry_out; 71 }; 72 73 struct fuse_read_req { 74 struct fuse_in_header in_header; 75 struct fuse_read_in read_in; 76 struct fuse_out_header out_header; 77 }; 78 79 struct fuse_release_req { 80 struct fuse_in_header in_header; 81 struct fuse_release_in release_in; 82 struct fuse_out_header out_header; 83 }; 84 85 struct fuse_destroy_req { 86 struct fuse_in_header in_header; 87 struct fuse_out_header out_header; 88 }; 89 90 struct fuse_setattr_req { 91 struct fuse_in_header in_header; 92 struct fuse_out_header out_header; 93 }; 94 95 struct fuse_fsync_req { 96 struct fuse_in_header in_header; 97 struct fuse_fsync_in fsync_in; 98 struct fuse_out_header out_header; 99 }; 100 101 struct fuse_unlink_req { 102 struct fuse_in_header in_header; 103 struct fuse_out_header out_header; 104 }; 105 106 struct fuse_rename_req { 107 struct fuse_in_header in_header; 108 struct fuse_rename_in rename_in; 109 struct fuse_out_header out_header; 110 }; 111 112 struct fuse_kstatfs_req { 113 struct fuse_in_header in_header; 114 struct fuse_out_header out_header; 115 struct fuse_kstatfs kstatfs_out; 116 }; 117 118 struct fuse_forget_req { 119 struct fuse_in_header in_header; 120 struct fuse_forget_in forget_in; 121 }; 122 123 enum fuse_object_type { 124 FUSE_FILE, 125 FUSE_DIR 126 }; 127 128 void fuse_fill_header(struct fuse_in_header *hdr, uint32_t len, uint32_t opcode, uint64_t nodeid); 129 130 void fuse_create_init_req(struct fuse_init_req *req); 131 void fuse_create_open_req(struct fuse_open_req *req, uint64_t inode, uint32_t flags, 132 enum fuse_object_type type); 133 void fuse_create_lookup_req(struct fuse_lookup_req *req, uint64_t inode, uint32_t fname_len); 134 void fuse_create_read_req( 135 struct fuse_read_req *req, uint64_t inode, uint64_t fh, uint64_t offset, uint32_t size, 136 enum fuse_object_type type); 137 void fuse_create_release_req(struct fuse_release_req *req, uint64_t inode, uint64_t fh, 138 enum fuse_object_type type); 139 void fuse_create_destroy_req(struct fuse_destroy_req *req); 140 void fuse_create_create_req( 141 struct fuse_create_req *req, uint64_t inode, uint32_t fname_len, uint32_t flags, 142 uint32_t mode); 143 void fuse_create_write_req( 144 struct fuse_write_req *req, uint64_t inode, uint64_t fh, uint64_t offset, uint32_t size); 145 void fuse_create_lseek_req( 146 struct fuse_lseek_req *req, uint64_t inode, uint64_t fh, uint64_t offset, uint32_t whence); 147 void fuse_create_setattr_req(struct fuse_setattr_req *req, uint64_t inode); 148 void fuse_create_fsync_req(struct fuse_fsync_req *req, uint64_t inode, uint64_t fh); 149 void fuse_create_mkdir_req( 150 struct fuse_mkdir_req *req, uint64_t inode, uint32_t dirname_len, uint32_t mode); 151 void fuse_create_unlink_req( 152 struct fuse_unlink_req *req, uint32_t fname_len, enum fuse_object_type type); 153 void fuse_create_rename_req( 154 struct fuse_rename_req *req, uint64_t old_dir_nodeid, uint32_t old_len, 155 uint64_t new_dir_nodeid, uint32_t new_len); 156 157 const char *fuse_opcode_to_string(uint32_t opcode); 158 159 void fuse_dump_init_req_out(struct fuse_init_req *req); 160 void fuse_dump_entry_out(struct fuse_entry_out *eo); 161 void fuse_dump_open_req_out(struct fuse_open_req *req); 162 void fuse_dump_create_req_out(struct fuse_create_out *req); 163 void fuse_dump_write_out(struct fuse_write_out *wo); 164 void fuse_dump_lseek_out(struct fuse_lseek_out *lo); 165 void fuse_dump_attr_out(struct fuse_attr_out *ao); 166 void fuse_dump_kstafs(struct fuse_kstatfs *ks); 167 168 #endif /* ZEPHYR_SUBSYS_FS_FUSE_CLIENT_H_ */ 169