Skip to content

Commit 702c2cc

Browse files
fs: add fuse primitives
This commit adds fuse structures, requests and functions to fill them Signed-off-by: Jakub Michalski <jmichalski@antmicro.com>
1 parent 30928ba commit 702c2cc

File tree

6 files changed

+866
-0
lines changed

6 files changed

+866
-0
lines changed

include/zephyr/fs/fuse.h

Lines changed: 394 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,394 @@
1+
/*
2+
* Copyright (c) 2025 Antmicro <www.antmicro.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_SUBSYS_FS_FUSE_H_
8+
#define ZEPHYR_SUBSYS_FS_FUSE_H_
9+
#include <stdint.h>
10+
#include <zephyr/kernel.h>
11+
12+
/* adapted from Linux: include/uapi/linux/fuse.h */
13+
14+
#define FUSE_MAJOR_VERSION 7
15+
#define FUSE_MINOR_VERSION 31
16+
17+
#define FUSE_LOOKUP 1
18+
#define FUSE_FORGET 2
19+
#define FUSE_SETATTR 4
20+
#define FUSE_MKDIR 9
21+
#define FUSE_UNLINK 10
22+
#define FUSE_RENAME 12
23+
#define FUSE_OPEN 14
24+
#define FUSE_READ 15
25+
#define FUSE_WRITE 16
26+
#define FUSE_STATFS 17
27+
#define FUSE_RELEASE 18
28+
#define FUSE_FSYNC 20
29+
#define FUSE_INIT 26
30+
#define FUSE_OPENDIR 27
31+
#define FUSE_READDIR 28
32+
#define FUSE_RELEASEDIR 29
33+
#define FUSE_CREATE 35
34+
#define FUSE_DESTROY 38
35+
#define FUSE_LSEEK 46
36+
37+
#define FUSE_ROOT_INODE 1
38+
39+
struct fuse_in_header {
40+
uint32_t len;
41+
uint32_t opcode;
42+
uint64_t unique;
43+
uint64_t nodeid;
44+
uint32_t uid;
45+
uint32_t gid;
46+
uint32_t pid;
47+
uint16_t total_extlen;
48+
uint16_t padding;
49+
};
50+
51+
struct fuse_out_header {
52+
uint32_t len;
53+
int32_t error;
54+
uint64_t unique;
55+
};
56+
57+
struct fuse_init_in {
58+
uint32_t major;
59+
uint32_t minor;
60+
uint32_t max_readahead;
61+
uint32_t flags;
62+
uint32_t flags2;
63+
uint32_t unused[11];
64+
};
65+
66+
struct fuse_init_out {
67+
uint32_t major;
68+
uint32_t minor;
69+
uint32_t max_readahead;
70+
uint32_t flags;
71+
uint16_t max_background;
72+
uint16_t congestion_threshold;
73+
uint32_t max_write;
74+
uint32_t time_gran;
75+
uint16_t max_pages;
76+
uint16_t map_alignment;
77+
uint32_t flags2;
78+
uint32_t max_stack_depth;
79+
uint32_t unused[6];
80+
};
81+
82+
struct fuse_open_in {
83+
uint32_t flags;
84+
uint32_t open_flags;
85+
};
86+
87+
struct fuse_open_out {
88+
uint64_t fh;
89+
uint32_t open_flags;
90+
int32_t backing_id;
91+
};
92+
93+
struct fuse_attr {
94+
uint64_t ino;
95+
uint64_t size;
96+
uint64_t blocks;
97+
uint64_t atime;
98+
uint64_t mtime;
99+
uint64_t ctime;
100+
uint32_t atimensec;
101+
uint32_t mtimensec;
102+
uint32_t ctimensec;
103+
uint32_t mode;
104+
uint32_t nlink;
105+
uint32_t uid;
106+
uint32_t gid;
107+
uint32_t rdev;
108+
uint32_t blksize;
109+
uint32_t flags;
110+
};
111+
112+
struct fuse_entry_out {
113+
uint64_t nodeid;
114+
uint64_t generation;
115+
uint64_t entry_valid;
116+
uint64_t attr_valid;
117+
uint32_t entry_valid_nsec;
118+
uint32_t attr_valid_nsec;
119+
struct fuse_attr attr;
120+
};
121+
122+
struct fuse_read_in {
123+
uint64_t fh;
124+
uint64_t offset;
125+
uint32_t size;
126+
uint32_t read_flags;
127+
uint64_t lock_owner;
128+
uint32_t flags;
129+
uint32_t padding;
130+
};
131+
132+
struct fuse_release_in {
133+
uint64_t fh;
134+
uint32_t flags;
135+
uint32_t release_flags;
136+
uint64_t lock_owner;
137+
};
138+
139+
struct fuse_create_in {
140+
uint32_t flags;
141+
uint32_t mode;
142+
uint32_t umask;
143+
uint32_t open_flags;
144+
};
145+
146+
struct fuse_create_out {
147+
struct fuse_entry_out entry_out;
148+
struct fuse_open_out open_out;
149+
};
150+
151+
struct fuse_write_in {
152+
uint64_t fh;
153+
uint64_t offset;
154+
uint32_t size;
155+
uint32_t write_flags;
156+
uint64_t lock_owner;
157+
uint32_t flags;
158+
uint32_t padding;
159+
};
160+
161+
struct fuse_write_out {
162+
uint32_t size;
163+
uint32_t padding;
164+
};
165+
166+
struct fuse_lseek_in {
167+
uint64_t fh;
168+
uint64_t offset;
169+
uint32_t whence;
170+
uint32_t padding;
171+
};
172+
173+
struct fuse_lseek_out {
174+
uint64_t offset;
175+
};
176+
177+
/* mask used to set file size, used in fuse_setattr_in::valid */
178+
#define FATTR_SIZE (1 << 3)
179+
180+
struct fuse_setattr_in {
181+
uint32_t valid;
182+
uint32_t padding;
183+
uint64_t fh;
184+
uint64_t size;
185+
uint64_t lock_owner;
186+
uint64_t atime;
187+
uint64_t mtime;
188+
uint64_t ctime;
189+
uint32_t atimensec;
190+
uint32_t mtimensec;
191+
uint32_t ctimensec;
192+
uint32_t mode;
193+
uint32_t unused4;
194+
uint32_t uid;
195+
uint32_t gid;
196+
uint32_t unused5;
197+
};
198+
199+
struct fuse_attr_out {
200+
uint64_t attr_valid;
201+
uint32_t attr_valid_nsec;
202+
uint32_t dummy;
203+
struct fuse_attr attr;
204+
};
205+
206+
struct fuse_fsync_in {
207+
uint64_t fh;
208+
uint32_t fsync_flags;
209+
uint32_t padding;
210+
};
211+
212+
struct fuse_mkdir_in {
213+
uint32_t mode;
214+
uint32_t umask;
215+
};
216+
217+
struct fuse_rename_in {
218+
uint64_t newdir;
219+
};
220+
221+
struct fuse_kstatfs {
222+
uint64_t blocks;
223+
uint64_t bfree;
224+
uint64_t bavail;
225+
uint64_t files;
226+
uint64_t ffree;
227+
uint32_t bsize;
228+
uint32_t namelen;
229+
uint32_t frsize;
230+
uint32_t padding;
231+
uint32_t spare[6];
232+
};
233+
234+
struct fuse_dirent {
235+
uint64_t ino;
236+
uint64_t off;
237+
uint32_t namelen;
238+
uint32_t type;
239+
char name[];
240+
};
241+
242+
struct fuse_forget_in {
243+
uint64_t nlookup;
244+
};
245+
246+
/*
247+
* requests are put into structs to leverage the fact that they are contiguous in memory and can
248+
* be passed to virtqueue as smaller amount of buffers, e.g. in_header + init_in can be sent as
249+
* a single buffer containing both of them instead of two separate buffers
250+
*/
251+
252+
struct fuse_init_req {
253+
struct fuse_in_header in_header;
254+
struct fuse_init_in init_in;
255+
struct fuse_out_header out_header;
256+
struct fuse_init_out init_out;
257+
};
258+
259+
struct fuse_open_req {
260+
struct fuse_in_header in_header;
261+
struct fuse_open_in open_in;
262+
struct fuse_out_header out_header;
263+
struct fuse_open_out open_out;
264+
};
265+
266+
struct fuse_create_req {
267+
struct fuse_in_header in_header;
268+
struct fuse_create_in create_in;
269+
struct fuse_out_header out_header;
270+
struct fuse_create_out create_out;
271+
};
272+
273+
struct fuse_write_req {
274+
struct fuse_in_header in_header;
275+
struct fuse_write_in write_in;
276+
struct fuse_out_header out_header;
277+
struct fuse_write_out write_out;
278+
};
279+
280+
struct fuse_lseek_req {
281+
struct fuse_in_header in_header;
282+
struct fuse_lseek_in lseek_in;
283+
struct fuse_out_header out_header;
284+
struct fuse_lseek_out lseek_out;
285+
};
286+
287+
struct fuse_mkdir_req {
288+
struct fuse_in_header in_header;
289+
struct fuse_mkdir_in mkdir_in;
290+
struct fuse_out_header out_header;
291+
struct fuse_entry_out entry_out;
292+
};
293+
294+
struct fuse_lookup_req {
295+
struct fuse_in_header in_header;
296+
struct fuse_out_header out_header;
297+
struct fuse_entry_out entry_out;
298+
};
299+
300+
struct fuse_read_req {
301+
struct fuse_in_header in_header;
302+
struct fuse_read_in read_in;
303+
struct fuse_out_header out_header;
304+
};
305+
306+
struct fuse_release_req {
307+
struct fuse_in_header in_header;
308+
struct fuse_release_in release_in;
309+
struct fuse_out_header out_header;
310+
};
311+
312+
struct fuse_destroy_req {
313+
struct fuse_in_header in_header;
314+
struct fuse_out_header out_header;
315+
};
316+
317+
struct fuse_setattr_req {
318+
struct fuse_in_header in_header;
319+
struct fuse_out_header out_header;
320+
};
321+
322+
struct fuse_fsync_req {
323+
struct fuse_in_header in_header;
324+
struct fuse_fsync_in fsync_in;
325+
struct fuse_out_header out_header;
326+
};
327+
328+
struct fuse_unlink_req {
329+
struct fuse_in_header in_header;
330+
struct fuse_out_header out_header;
331+
};
332+
333+
struct fuse_rename_req {
334+
struct fuse_in_header in_header;
335+
struct fuse_rename_in rename_in;
336+
struct fuse_out_header out_header;
337+
};
338+
339+
struct fuse_kstatfs_req {
340+
struct fuse_in_header in_header;
341+
struct fuse_out_header out_header;
342+
struct fuse_kstatfs kstatfs_out;
343+
};
344+
345+
struct fuse_forget_req {
346+
struct fuse_in_header in_header;
347+
struct fuse_forget_in forget_in;
348+
};
349+
350+
enum fuse_object_type {
351+
FUSE_FILE,
352+
FUSE_DIR
353+
};
354+
355+
void fuse_fill_header(struct fuse_in_header *hdr, uint32_t len, uint32_t opcode, uint64_t nodeid);
356+
357+
void fuse_create_init_req(struct fuse_init_req *req);
358+
void fuse_create_open_req(struct fuse_open_req *req, uint64_t inode, uint32_t flags,
359+
enum fuse_object_type type);
360+
void fuse_create_lookup_req(struct fuse_lookup_req *req, uint64_t inode, uint32_t fname_len);
361+
void fuse_create_read_req(
362+
struct fuse_read_req *req, uint64_t inode, uint64_t fh, uint64_t offset, uint32_t size,
363+
enum fuse_object_type type);
364+
void fuse_create_release_req(struct fuse_release_req *req, uint64_t inode, uint64_t fh,
365+
enum fuse_object_type type);
366+
void fuse_create_destroy_req(struct fuse_destroy_req *req);
367+
void fuse_create_create_req(
368+
struct fuse_create_req *req, uint64_t inode, uint32_t fname_len, uint32_t flags,
369+
uint32_t mode);
370+
void fuse_create_write_req(
371+
struct fuse_write_req *req, uint64_t inode, uint64_t fh, uint64_t offset, uint32_t size);
372+
void fuse_create_lseek_req(
373+
struct fuse_lseek_req *req, uint64_t inode, uint64_t fh, uint64_t offset, uint32_t whence);
374+
void fuse_create_setattr_req(struct fuse_setattr_req *req, uint64_t inode);
375+
void fuse_create_fsync_req(struct fuse_fsync_req *req, uint64_t inode, uint64_t fh);
376+
void fuse_create_mkdir_req(
377+
struct fuse_mkdir_req *req, uint64_t inode, uint32_t dirname_len, uint32_t mode);
378+
void fuse_create_unlink_req(struct fuse_unlink_req *req, uint32_t fname_len);
379+
void fuse_create_rename_req(
380+
struct fuse_rename_req *req, uint64_t old_dir_nodeid, uint32_t old_len,
381+
uint64_t new_dir_nodeid, uint32_t new_len);
382+
383+
const char *fuse_opcode_to_string(uint32_t opcode);
384+
385+
void fuse_dump_init_req_out(struct fuse_init_req *req);
386+
void fuse_dump_entry_out(struct fuse_entry_out *eo);
387+
void fuse_dump_open_req_out(struct fuse_open_req *req);
388+
void fuse_dump_create_req_out(struct fuse_create_out *req);
389+
void fuse_dump_write_out(struct fuse_write_out *wo);
390+
void fuse_dump_lseek_out(struct fuse_lseek_out *lo);
391+
void fuse_dump_attr_out(struct fuse_attr_out *ao);
392+
void fuse_dump_kstafs(struct fuse_kstatfs *ks);
393+
394+
#endif /* ZEPHYR_SUBSYS_FS_FUSE_H_ */

0 commit comments

Comments
 (0)