blob: 77ac6b3acaabb947e99746200001e636f01a90e1
1 | /* |
2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
4 | |
5 | This program can be distributed under the terms of the GNU LGPLv2. |
6 | See the file COPYING.LIB. |
7 | */ |
8 | |
9 | #ifndef _FUSE_LOWLEVEL_H_ |
10 | #define _FUSE_LOWLEVEL_H_ |
11 | |
12 | /** @file |
13 | * |
14 | * Low level API |
15 | */ |
16 | |
17 | #include "fuse_common.h" |
18 | |
19 | #include <utime.h> |
20 | #include <fcntl.h> |
21 | #include <sys/types.h> |
22 | #include <sys/stat.h> |
23 | #if HAVE_SYS_STATVFS_H |
24 | #include <sys/statvfs.h> |
25 | #endif |
26 | #include <sys/uio.h> |
27 | |
28 | #ifdef __cplusplus |
29 | extern "C" { |
30 | #endif |
31 | |
32 | /* ----------------------------------------------------------- * |
33 | * Miscellaneous definitions * |
34 | * ----------------------------------------------------------- */ |
35 | |
36 | /** The node ID of the root inode */ |
37 | #define FUSE_ROOT_ID 1 |
38 | |
39 | /** Inode number type */ |
40 | typedef unsigned long fuse_ino_t; |
41 | |
42 | /** Request pointer type */ |
43 | typedef struct fuse_req *fuse_req_t; |
44 | |
45 | /** |
46 | * Session |
47 | * |
48 | * This provides hooks for processing requests, and exiting |
49 | */ |
50 | struct fuse_session; |
51 | |
52 | /** |
53 | * Channel |
54 | * |
55 | * A communication channel, providing hooks for sending and receiving |
56 | * messages |
57 | */ |
58 | struct fuse_chan; |
59 | |
60 | /** Directory entry parameters supplied to fuse_reply_entry() */ |
61 | struct fuse_entry_param { |
62 | /** Unique inode number |
63 | * |
64 | * In lookup, zero means negative entry (from version 2.5) |
65 | * Returning ENOENT also means negative entry, but by setting zero |
66 | * ino the kernel may cache negative entries for entry_timeout |
67 | * seconds. |
68 | */ |
69 | fuse_ino_t ino; |
70 | |
71 | /** Generation number for this entry. |
72 | * |
73 | * The ino/generation pair should be unique for the filesystem's |
74 | * lifetime. It must be non-zero, otherwise FUSE will treat it as an |
75 | * error. |
76 | */ |
77 | unsigned long generation; |
78 | |
79 | /** Inode attributes. |
80 | * |
81 | * Even if attr_timeout == 0, attr must be correct. For example, |
82 | * for open(), FUSE uses attr.st_size from lookup() to determine |
83 | * how many bytes to request. If this value is not correct, |
84 | * incorrect data will be returned. |
85 | */ |
86 | struct stat attr; |
87 | |
88 | /** Validity timeout (in seconds) for the attributes */ |
89 | double attr_timeout; |
90 | |
91 | /** Validity timeout (in seconds) for the name */ |
92 | double entry_timeout; |
93 | }; |
94 | |
95 | /** Additional context associated with requests */ |
96 | struct fuse_ctx { |
97 | /** User ID of the calling process */ |
98 | uid_t uid; |
99 | |
100 | /** Group ID of the calling process */ |
101 | gid_t gid; |
102 | |
103 | /** Thread ID of the calling process */ |
104 | pid_t pid; |
105 | |
106 | #ifdef POSIXACLS |
107 | /** Umask of the calling process (introduced in version 2.8) */ |
108 | mode_t umask; |
109 | #endif |
110 | }; |
111 | |
112 | /* 'to_set' flags in setattr */ |
113 | #define FUSE_SET_ATTR_MODE (1 << 0) |
114 | #define FUSE_SET_ATTR_UID (1 << 1) |
115 | #define FUSE_SET_ATTR_GID (1 << 2) |
116 | #define FUSE_SET_ATTR_SIZE (1 << 3) |
117 | #define FUSE_SET_ATTR_ATIME (1 << 4) |
118 | #define FUSE_SET_ATTR_MTIME (1 << 5) |
119 | #define FUSE_SET_ATTR_ATIME_NOW (1 << 7) |
120 | #define FUSE_SET_ATTR_MTIME_NOW (1 << 8) |
121 | |
122 | /* ----------------------------------------------------------- * |
123 | * Request methods and replies * |
124 | * ----------------------------------------------------------- */ |
125 | |
126 | /** |
127 | * Low level filesystem operations |
128 | * |
129 | * Most of the methods (with the exception of init and destroy) |
130 | * receive a request handle (fuse_req_t) as their first argument. |
131 | * This handle must be passed to one of the specified reply functions. |
132 | * |
133 | * This may be done inside the method invocation, or after the call |
134 | * has returned. The request handle is valid until one of the reply |
135 | * functions is called. |
136 | * |
137 | * Other pointer arguments (name, fuse_file_info, etc) are not valid |
138 | * after the call has returned, so if they are needed later, their |
139 | * contents have to be copied. |
140 | * |
141 | * The filesystem sometimes needs to handle a return value of -ENOENT |
142 | * from the reply function, which means, that the request was |
143 | * interrupted, and the reply discarded. For example if |
144 | * fuse_reply_open() return -ENOENT means, that the release method for |
145 | * this file will not be called. |
146 | */ |
147 | struct fuse_lowlevel_ops { |
148 | /** |
149 | * Initialize filesystem |
150 | * |
151 | * Called before any other filesystem method |
152 | * |
153 | * There's no reply to this function |
154 | * |
155 | * @param userdata the user data passed to fuse_lowlevel_new() |
156 | */ |
157 | void (*init) (void *userdata, struct fuse_conn_info *conn); |
158 | |
159 | /** |
160 | * Clean up filesystem |
161 | * |
162 | * Called on filesystem exit |
163 | * |
164 | * There's no reply to this function |
165 | * |
166 | * @param userdata the user data passed to fuse_lowlevel_new() |
167 | */ |
168 | void (*destroy) (void *userdata); |
169 | |
170 | /** |
171 | * Look up a directory entry by name and get its attributes. |
172 | * |
173 | * Valid replies: |
174 | * fuse_reply_entry |
175 | * fuse_reply_err |
176 | * |
177 | * @param req request handle |
178 | * @param parent inode number of the parent directory |
179 | * @param name the name to look up |
180 | */ |
181 | void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name); |
182 | |
183 | /** |
184 | * Forget about an inode |
185 | * |
186 | * The nlookup parameter indicates the number of lookups |
187 | * previously performed on this inode. |
188 | * |
189 | * If the filesystem implements inode lifetimes, it is recommended |
190 | * that inodes acquire a single reference on each lookup, and lose |
191 | * nlookup references on each forget. |
192 | * |
193 | * The filesystem may ignore forget calls, if the inodes don't |
194 | * need to have a limited lifetime. |
195 | * |
196 | * On unmount it is not guaranteed, that all referenced inodes |
197 | * will receive a forget message. |
198 | * |
199 | * Valid replies: |
200 | * fuse_reply_none |
201 | * |
202 | * @param req request handle |
203 | * @param ino the inode number |
204 | * @param nlookup the number of lookups to forget |
205 | */ |
206 | void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup); |
207 | |
208 | /** |
209 | * Get file attributes |
210 | * |
211 | * Valid replies: |
212 | * fuse_reply_attr |
213 | * fuse_reply_err |
214 | * |
215 | * @param req request handle |
216 | * @param ino the inode number |
217 | * @param fi for future use, currently always NULL |
218 | */ |
219 | void (*getattr) (fuse_req_t req, fuse_ino_t ino, |
220 | struct fuse_file_info *fi); |
221 | |
222 | /** |
223 | * Set file attributes |
224 | * |
225 | * In the 'attr' argument only members indicated by the 'to_set' |
226 | * bitmask contain valid values. Other members contain undefined |
227 | * values. |
228 | * |
229 | * If the setattr was invoked from the ftruncate() system call |
230 | * under Linux kernel versions 2.6.15 or later, the fi->fh will |
231 | * contain the value set by the open method or will be undefined |
232 | * if the open method didn't set any value. Otherwise (not |
233 | * ftruncate call, or kernel version earlier than 2.6.15) the fi |
234 | * parameter will be NULL. |
235 | * |
236 | * Valid replies: |
237 | * fuse_reply_attr |
238 | * fuse_reply_err |
239 | * |
240 | * @param req request handle |
241 | * @param ino the inode number |
242 | * @param attr the attributes |
243 | * @param to_set bit mask of attributes which should be set |
244 | * @param fi file information, or NULL |
245 | * |
246 | * Changed in version 2.5: |
247 | * file information filled in for ftruncate |
248 | */ |
249 | void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr, |
250 | int to_set, struct fuse_file_info *fi); |
251 | |
252 | /** |
253 | * Read symbolic link |
254 | * |
255 | * Valid replies: |
256 | * fuse_reply_readlink |
257 | * fuse_reply_err |
258 | * |
259 | * @param req request handle |
260 | * @param ino the inode number |
261 | */ |
262 | void (*readlink) (fuse_req_t req, fuse_ino_t ino); |
263 | |
264 | /** |
265 | * Create file node |
266 | * |
267 | * Create a regular file, character device, block device, fifo or |
268 | * socket node. |
269 | * |
270 | * Valid replies: |
271 | * fuse_reply_entry |
272 | * fuse_reply_err |
273 | * |
274 | * @param req request handle |
275 | * @param parent inode number of the parent directory |
276 | * @param name to create |
277 | * @param mode file type and mode with which to create the new file |
278 | * @param rdev the device number (only valid if created file is a device) |
279 | */ |
280 | void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name, |
281 | mode_t mode, dev_t rdev); |
282 | |
283 | /** |
284 | * Create a directory |
285 | * |
286 | * Valid replies: |
287 | * fuse_reply_entry |
288 | * fuse_reply_err |
289 | * |
290 | * @param req request handle |
291 | * @param parent inode number of the parent directory |
292 | * @param name to create |
293 | * @param mode with which to create the new file |
294 | */ |
295 | void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name, |
296 | mode_t mode); |
297 | |
298 | /** |
299 | * Remove a file |
300 | * |
301 | * Valid replies: |
302 | * fuse_reply_err |
303 | * |
304 | * @param req request handle |
305 | * @param parent inode number of the parent directory |
306 | * @param name to remove |
307 | */ |
308 | void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name); |
309 | |
310 | /** |
311 | * Remove a directory |
312 | * |
313 | * Valid replies: |
314 | * fuse_reply_err |
315 | * |
316 | * @param req request handle |
317 | * @param parent inode number of the parent directory |
318 | * @param name to remove |
319 | */ |
320 | void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name); |
321 | |
322 | /** |
323 | * Create a symbolic link |
324 | * |
325 | * Valid replies: |
326 | * fuse_reply_entry |
327 | * fuse_reply_err |
328 | * |
329 | * @param req request handle |
330 | * @param link the contents of the symbolic link |
331 | * @param parent inode number of the parent directory |
332 | * @param name to create |
333 | */ |
334 | void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent, |
335 | const char *name); |
336 | |
337 | /** Rename a file |
338 | * |
339 | * Valid replies: |
340 | * fuse_reply_err |
341 | * |
342 | * @param req request handle |
343 | * @param parent inode number of the old parent directory |
344 | * @param name old name |
345 | * @param newparent inode number of the new parent directory |
346 | * @param newname new name |
347 | */ |
348 | void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name, |
349 | fuse_ino_t newparent, const char *newname); |
350 | |
351 | /** |
352 | * Create a hard link |
353 | * |
354 | * Valid replies: |
355 | * fuse_reply_entry |
356 | * fuse_reply_err |
357 | * |
358 | * @param req request handle |
359 | * @param ino the old inode number |
360 | * @param newparent inode number of the new parent directory |
361 | * @param newname new name to create |
362 | */ |
363 | void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, |
364 | const char *newname); |
365 | |
366 | /** |
367 | * Open a file |
368 | * |
369 | * Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and |
370 | * O_TRUNC) are available in fi->flags. |
371 | * |
372 | * Filesystem may store an arbitrary file handle (pointer, index, |
373 | * etc) in fi->fh, and use this in other all other file operations |
374 | * (read, write, flush, release, fsync). |
375 | * |
376 | * Filesystem may also implement stateless file I/O and not store |
377 | * anything in fi->fh. |
378 | * |
379 | * There are also some flags (direct_io, keep_cache) which the |
380 | * filesystem may set in fi, to change the way the file is opened. |
381 | * See fuse_file_info structure in <fuse_common.h> for more details. |
382 | * |
383 | * Valid replies: |
384 | * fuse_reply_open |
385 | * fuse_reply_err |
386 | * |
387 | * @param req request handle |
388 | * @param ino the inode number |
389 | * @param fi file information |
390 | */ |
391 | void (*open) (fuse_req_t req, fuse_ino_t ino, |
392 | struct fuse_file_info *fi); |
393 | |
394 | /** |
395 | * Read data |
396 | * |
397 | * Read should send exactly the number of bytes requested except |
398 | * on EOF or error, otherwise the rest of the data will be |
399 | * substituted with zeroes. An exception to this is when the file |
400 | * has been opened in 'direct_io' mode, in which case the return |
401 | * value of the read system call will reflect the return value of |
402 | * this operation. |
403 | * |
404 | * fi->fh will contain the value set by the open method, or will |
405 | * be undefined if the open method didn't set any value. |
406 | * |
407 | * Valid replies: |
408 | * fuse_reply_buf |
409 | * fuse_reply_err |
410 | * |
411 | * @param req request handle |
412 | * @param ino the inode number |
413 | * @param size number of bytes to read |
414 | * @param off offset to read from |
415 | * @param fi file information |
416 | */ |
417 | void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, |
418 | struct fuse_file_info *fi); |
419 | |
420 | /** |
421 | * Write data |
422 | * |
423 | * Write should return exactly the number of bytes requested |
424 | * except on error. An exception to this is when the file has |
425 | * been opened in 'direct_io' mode, in which case the return value |
426 | * of the write system call will reflect the return value of this |
427 | * operation. |
428 | * |
429 | * fi->fh will contain the value set by the open method, or will |
430 | * be undefined if the open method didn't set any value. |
431 | * |
432 | * Valid replies: |
433 | * fuse_reply_write |
434 | * fuse_reply_err |
435 | * |
436 | * @param req request handle |
437 | * @param ino the inode number |
438 | * @param buf data to write |
439 | * @param size number of bytes to write |
440 | * @param off offset to write to |
441 | * @param fi file information |
442 | */ |
443 | void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf, |
444 | size_t size, off_t off, struct fuse_file_info *fi); |
445 | |
446 | /** |
447 | * Flush method |
448 | * |
449 | * This is called on each close() of the opened file. |
450 | * |
451 | * Since file descriptors can be duplicated (dup, dup2, fork), for |
452 | * one open call there may be many flush calls. |
453 | * |
454 | * Filesystems shouldn't assume that flush will always be called |
455 | * after some writes, or that if will be called at all. |
456 | * |
457 | * fi->fh will contain the value set by the open method, or will |
458 | * be undefined if the open method didn't set any value. |
459 | * |
460 | * NOTE: the name of the method is misleading, since (unlike |
461 | * fsync) the filesystem is not forced to flush pending writes. |
462 | * One reason to flush data, is if the filesystem wants to return |
463 | * write errors. |
464 | * |
465 | * If the filesystem supports file locking operations (setlk, |
466 | * getlk) it should remove all locks belonging to 'fi->owner'. |
467 | * |
468 | * Valid replies: |
469 | * fuse_reply_err |
470 | * |
471 | * @param req request handle |
472 | * @param ino the inode number |
473 | * @param fi file information |
474 | */ |
475 | void (*flush) (fuse_req_t req, fuse_ino_t ino, |
476 | struct fuse_file_info *fi); |
477 | |
478 | /** |
479 | * Release an open file |
480 | * |
481 | * Release is called when there are no more references to an open |
482 | * file: all file descriptors are closed and all memory mappings |
483 | * are unmapped. |
484 | * |
485 | * For every open call there will be exactly one release call. |
486 | * |
487 | * The filesystem may reply with an error, but error values are |
488 | * not returned to close() or munmap() which triggered the |
489 | * release. |
490 | * |
491 | * fi->fh will contain the value set by the open method, or will |
492 | * be undefined if the open method didn't set any value. |
493 | * fi->flags will contain the same flags as for open. |
494 | * |
495 | * Valid replies: |
496 | * fuse_reply_err |
497 | * |
498 | * @param req request handle |
499 | * @param ino the inode number |
500 | * @param fi file information |
501 | */ |
502 | void (*release) (fuse_req_t req, fuse_ino_t ino, |
503 | struct fuse_file_info *fi); |
504 | |
505 | /** |
506 | * Synchronize file contents |
507 | * |
508 | * If the datasync parameter is non-zero, then only the user data |
509 | * should be flushed, not the meta data. |
510 | * |
511 | * Valid replies: |
512 | * fuse_reply_err |
513 | * |
514 | * @param req request handle |
515 | * @param ino the inode number |
516 | * @param datasync flag indicating if only data should be flushed |
517 | * @param fi file information |
518 | */ |
519 | void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync, |
520 | struct fuse_file_info *fi); |
521 | |
522 | /** |
523 | * Open a directory |
524 | * |
525 | * Filesystem may store an arbitrary file handle (pointer, index, |
526 | * etc) in fi->fh, and use this in other all other directory |
527 | * stream operations (readdir, releasedir, fsyncdir). |
528 | * |
529 | * Filesystem may also implement stateless directory I/O and not |
530 | * store anything in fi->fh, though that makes it impossible to |
531 | * implement standard conforming directory stream operations in |
532 | * case the contents of the directory can change between opendir |
533 | * and releasedir. |
534 | * |
535 | * Valid replies: |
536 | * fuse_reply_open |
537 | * fuse_reply_err |
538 | * |
539 | * @param req request handle |
540 | * @param ino the inode number |
541 | * @param fi file information |
542 | */ |
543 | void (*opendir) (fuse_req_t req, fuse_ino_t ino, |
544 | struct fuse_file_info *fi); |
545 | |
546 | /** |
547 | * Read directory |
548 | * |
549 | * Send a buffer filled using fuse_add_direntry(), with size not |
550 | * exceeding the requested size. Send an empty buffer on end of |
551 | * stream. |
552 | * |
553 | * fi->fh will contain the value set by the opendir method, or |
554 | * will be undefined if the opendir method didn't set any value. |
555 | * |
556 | * Valid replies: |
557 | * fuse_reply_buf |
558 | * fuse_reply_err |
559 | * |
560 | * @param req request handle |
561 | * @param ino the inode number |
562 | * @param size maximum number of bytes to send |
563 | * @param off offset to continue reading the directory stream |
564 | * @param fi file information |
565 | */ |
566 | void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, |
567 | struct fuse_file_info *fi); |
568 | |
569 | /** |
570 | * Release an open directory |
571 | * |
572 | * For every opendir call there will be exactly one releasedir |
573 | * call. |
574 | * |
575 | * fi->fh will contain the value set by the opendir method, or |
576 | * will be undefined if the opendir method didn't set any value. |
577 | * |
578 | * Valid replies: |
579 | * fuse_reply_err |
580 | * |
581 | * @param req request handle |
582 | * @param ino the inode number |
583 | * @param fi file information |
584 | */ |
585 | void (*releasedir) (fuse_req_t req, fuse_ino_t ino, |
586 | struct fuse_file_info *fi); |
587 | |
588 | /** |
589 | * Synchronize directory contents |
590 | * |
591 | * If the datasync parameter is non-zero, then only the directory |
592 | * contents should be flushed, not the meta data. |
593 | * |
594 | * fi->fh will contain the value set by the opendir method, or |
595 | * will be undefined if the opendir method didn't set any value. |
596 | * |
597 | * Valid replies: |
598 | * fuse_reply_err |
599 | * |
600 | * @param req request handle |
601 | * @param ino the inode number |
602 | * @param datasync flag indicating if only data should be flushed |
603 | * @param fi file information |
604 | */ |
605 | void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync, |
606 | struct fuse_file_info *fi); |
607 | |
608 | /** |
609 | * Get file system statistics |
610 | * |
611 | * Valid replies: |
612 | * fuse_reply_statfs |
613 | * fuse_reply_err |
614 | * |
615 | * @param req request handle |
616 | * @param ino the inode number, zero means "undefined" |
617 | */ |
618 | void (*statfs) (fuse_req_t req, fuse_ino_t ino); |
619 | |
620 | /** |
621 | * Set an extended attribute |
622 | * |
623 | * Valid replies: |
624 | * fuse_reply_err |
625 | */ |
626 | void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name, |
627 | const char *value, size_t size, int flags); |
628 | |
629 | /** |
630 | * Get an extended attribute |
631 | * |
632 | * If size is zero, the size of the value should be sent with |
633 | * fuse_reply_xattr. |
634 | * |
635 | * If the size is non-zero, and the value fits in the buffer, the |
636 | * value should be sent with fuse_reply_buf. |
637 | * |
638 | * If the size is too small for the value, the ERANGE error should |
639 | * be sent. |
640 | * |
641 | * Valid replies: |
642 | * fuse_reply_buf |
643 | * fuse_reply_xattr |
644 | * fuse_reply_err |
645 | * |
646 | * @param req request handle |
647 | * @param ino the inode number |
648 | * @param name of the extended attribute |
649 | * @param size maximum size of the value to send |
650 | */ |
651 | void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name, |
652 | size_t size); |
653 | |
654 | /** |
655 | * List extended attribute names |
656 | * |
657 | * If size is zero, the total size of the attribute list should be |
658 | * sent with fuse_reply_xattr. |
659 | * |
660 | * If the size is non-zero, and the null character separated |
661 | * attribute list fits in the buffer, the list should be sent with |
662 | * fuse_reply_buf. |
663 | * |
664 | * If the size is too small for the list, the ERANGE error should |
665 | * be sent. |
666 | * |
667 | * Valid replies: |
668 | * fuse_reply_buf |
669 | * fuse_reply_xattr |
670 | * fuse_reply_err |
671 | * |
672 | * @param req request handle |
673 | * @param ino the inode number |
674 | * @param size maximum size of the list to send |
675 | */ |
676 | void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size); |
677 | |
678 | /** |
679 | * Remove an extended attribute |
680 | * |
681 | * Valid replies: |
682 | * fuse_reply_err |
683 | * |
684 | * @param req request handle |
685 | * @param ino the inode number |
686 | * @param name of the extended attribute |
687 | */ |
688 | void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name); |
689 | |
690 | /** |
691 | * Check file access permissions |
692 | * |
693 | * This will be called for the access() system call. If the |
694 | * 'default_permissions' mount option is given, this method is not |
695 | * called. |
696 | * |
697 | * This method is not called under Linux kernel versions 2.4.x |
698 | * |
699 | * Introduced in version 2.5 |
700 | * |
701 | * Valid replies: |
702 | * fuse_reply_err |
703 | * |
704 | * @param req request handle |
705 | * @param ino the inode number |
706 | * @param mask requested access mode |
707 | */ |
708 | void (*access) (fuse_req_t req, fuse_ino_t ino, int mask); |
709 | |
710 | /** |
711 | * Create and open a file |
712 | * |
713 | * If the file does not exist, first create it with the specified |
714 | * mode, and then open it. |
715 | * |
716 | * Open flags (with the exception of O_NOCTTY) are available in |
717 | * fi->flags. |
718 | * |
719 | * Filesystem may store an arbitrary file handle (pointer, index, |
720 | * etc) in fi->fh, and use this in other all other file operations |
721 | * (read, write, flush, release, fsync). |
722 | * |
723 | * There are also some flags (direct_io, keep_cache) which the |
724 | * filesystem may set in fi, to change the way the file is opened. |
725 | * See fuse_file_info structure in <fuse_common.h> for more details. |
726 | * |
727 | * If this method is not implemented or under Linux kernel |
728 | * versions earlier than 2.6.15, the mknod() and open() methods |
729 | * will be called instead. |
730 | * |
731 | * Introduced in version 2.5 |
732 | * |
733 | * Valid replies: |
734 | * fuse_reply_create |
735 | * fuse_reply_err |
736 | * |
737 | * @param req request handle |
738 | * @param parent inode number of the parent directory |
739 | * @param name to create |
740 | * @param mode file type and mode with which to create the new file |
741 | * @param fi file information |
742 | */ |
743 | void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name, |
744 | mode_t mode, struct fuse_file_info *fi); |
745 | |
746 | /** |
747 | * Test for a POSIX file lock |
748 | * |
749 | * Introduced in version 2.6 |
750 | * |
751 | * Valid replies: |
752 | * fuse_reply_lock |
753 | * fuse_reply_err |
754 | * |
755 | * @param req request handle |
756 | * @param ino the inode number |
757 | * @param fi file information |
758 | * @param lock the region/type to test |
759 | */ |
760 | void (*getlk) (fuse_req_t req, fuse_ino_t ino, |
761 | struct fuse_file_info *fi, struct flock *lock); |
762 | |
763 | /** |
764 | * Acquire, modify or release a POSIX file lock |
765 | * |
766 | * For POSIX threads (NPTL) there's a 1-1 relation between pid and |
767 | * owner, but otherwise this is not always the case. For checking |
768 | * lock ownership, 'fi->owner' must be used. The l_pid field in |
769 | * 'struct flock' should only be used to fill in this field in |
770 | * getlk(). |
771 | * |
772 | * Note: if the locking methods are not implemented, the kernel |
773 | * will still allow file locking to work locally. Hence these are |
774 | * only interesting for network filesystems and similar. |
775 | * |
776 | * Introduced in version 2.6 |
777 | * |
778 | * Valid replies: |
779 | * fuse_reply_err |
780 | * |
781 | * @param req request handle |
782 | * @param ino the inode number |
783 | * @param fi file information |
784 | * @param lock the region/type to test |
785 | * @param sleep locking operation may sleep |
786 | */ |
787 | void (*setlk) (fuse_req_t req, fuse_ino_t ino, |
788 | struct fuse_file_info *fi, |
789 | struct flock *lock, int sleep); |
790 | |
791 | /** |
792 | * Map block index within file to block index within device |
793 | * |
794 | * Note: This makes sense only for block device backed filesystems |
795 | * mounted with the 'blkdev' option |
796 | * |
797 | * Introduced in version 2.6 |
798 | * |
799 | * Valid replies: |
800 | * fuse_reply_bmap |
801 | * fuse_reply_err |
802 | * |
803 | * @param req request handle |
804 | * @param ino the inode number |
805 | * @param blocksize unit of block index |
806 | * @param idx block index within file |
807 | */ |
808 | void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize, |
809 | uint64_t idx); |
810 | }; |
811 | |
812 | /** |
813 | * Reply with an error code or success |
814 | * |
815 | * Possible requests: |
816 | * all except forget |
817 | * |
818 | * unlink, rmdir, rename, flush, release, fsync, fsyncdir, setxattr, |
819 | * removexattr and setlk may send a zero code |
820 | * |
821 | * @param req request handle |
822 | * @param err the positive error value, or zero for success |
823 | * @return zero for success, -errno for failure to send reply |
824 | */ |
825 | int fuse_reply_err(fuse_req_t req, int err); |
826 | |
827 | /** |
828 | * Don't send reply |
829 | * |
830 | * Possible requests: |
831 | * forget |
832 | * |
833 | * @param req request handle |
834 | */ |
835 | void fuse_reply_none(fuse_req_t req); |
836 | |
837 | /** |
838 | * Reply with a directory entry |
839 | * |
840 | * Possible requests: |
841 | * lookup, mknod, mkdir, symlink, link |
842 | * |
843 | * @param req request handle |
844 | * @param e the entry parameters |
845 | * @return zero for success, -errno for failure to send reply |
846 | */ |
847 | int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e); |
848 | |
849 | /** |
850 | * Reply with a directory entry and open parameters |
851 | * |
852 | * currently the following members of 'fi' are used: |
853 | * fh, direct_io, keep_cache |
854 | * |
855 | * Possible requests: |
856 | * create |
857 | * |
858 | * @param req request handle |
859 | * @param e the entry parameters |
860 | * @param fi file information |
861 | * @return zero for success, -errno for failure to send reply |
862 | */ |
863 | int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, |
864 | const struct fuse_file_info *fi); |
865 | |
866 | /** |
867 | * Reply with attributes |
868 | * |
869 | * Possible requests: |
870 | * getattr, setattr |
871 | * |
872 | * @param req request handle |
873 | * @param the attributes |
874 | * @param attr_timeout validity timeout (in seconds) for the attributes |
875 | * @return zero for success, -errno for failure to send reply |
876 | */ |
877 | int fuse_reply_attr(fuse_req_t req, const struct stat *attr, |
878 | double attr_timeout); |
879 | |
880 | /** |
881 | * Reply with the contents of a symbolic link |
882 | * |
883 | * Possible requests: |
884 | * readlink |
885 | * |
886 | * @param req request handle |
887 | * @param link symbolic link contents |
888 | * @return zero for success, -errno for failure to send reply |
889 | */ |
890 | int fuse_reply_readlink(fuse_req_t req, const char *link); |
891 | |
892 | /** |
893 | * Reply with open parameters |
894 | * |
895 | * currently the following members of 'fi' are used: |
896 | * fh, direct_io, keep_cache |
897 | * |
898 | * Possible requests: |
899 | * open, opendir |
900 | * |
901 | * @param req request handle |
902 | * @param fi file information |
903 | * @return zero for success, -errno for failure to send reply |
904 | */ |
905 | int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi); |
906 | |
907 | /** |
908 | * Reply with number of bytes written |
909 | * |
910 | * Possible requests: |
911 | * write |
912 | * |
913 | * @param req request handle |
914 | * @param count the number of bytes written |
915 | * @return zero for success, -errno for failure to send reply |
916 | */ |
917 | int fuse_reply_write(fuse_req_t req, size_t count); |
918 | |
919 | /** |
920 | * Reply with data |
921 | * |
922 | * Possible requests: |
923 | * read, readdir, getxattr, listxattr |
924 | * |
925 | * @param req request handle |
926 | * @param buf buffer containing data |
927 | * @param size the size of data in bytes |
928 | * @return zero for success, -errno for failure to send reply |
929 | */ |
930 | int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size); |
931 | |
932 | #ifdef POSIXACLS |
933 | /** |
934 | * Reply with data vector |
935 | * |
936 | * Possible requests: |
937 | * read, readdir, getxattr, listxattr |
938 | * |
939 | * @param req request handle |
940 | * @param iov the vector containing the data |
941 | * @param count the size of vector |
942 | * @return zero for success, -errno for failure to send reply |
943 | */ |
944 | int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count); |
945 | #endif |
946 | |
947 | /** |
948 | * Reply with filesystem statistics |
949 | * |
950 | * Possible requests: |
951 | * statfs |
952 | * |
953 | * @param req request handle |
954 | * @param stbuf filesystem statistics |
955 | * @return zero for success, -errno for failure to send reply |
956 | */ |
957 | #if HAVE_SYS_STATVFS_H |
958 | int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf); |
959 | #endif |
960 | |
961 | /** |
962 | * Reply with needed buffer size |
963 | * |
964 | * Possible requests: |
965 | * getxattr, listxattr |
966 | * |
967 | * @param req request handle |
968 | * @param count the buffer size needed in bytes |
969 | * @return zero for success, -errno for failure to send reply |
970 | */ |
971 | int fuse_reply_xattr(fuse_req_t req, size_t count); |
972 | |
973 | /** |
974 | * Reply with file lock information |
975 | * |
976 | * Possible requests: |
977 | * getlk |
978 | * |
979 | * @param req request handle |
980 | * @param lock the lock information |
981 | * @return zero for success, -errno for failure to send reply |
982 | */ |
983 | int fuse_reply_lock(fuse_req_t req, struct flock *lock); |
984 | |
985 | /** |
986 | * Reply with block index |
987 | * |
988 | * Possible requests: |
989 | * bmap |
990 | * |
991 | * @param req request handle |
992 | * @param idx block index within device |
993 | * @return zero for success, -errno for failure to send reply |
994 | */ |
995 | int fuse_reply_bmap(fuse_req_t req, uint64_t idx); |
996 | |
997 | /* ----------------------------------------------------------- * |
998 | * Filling a buffer in readdir * |
999 | * ----------------------------------------------------------- */ |
1000 | |
1001 | /** |
1002 | * Add a directory entry to the buffer |
1003 | * |
1004 | * Buffer needs to be large enough to hold the entry. Of it's not, |
1005 | * then the entry is not filled in but the size of the entry is still |
1006 | * returned. The caller can check this by comparing the bufsize |
1007 | * parameter with the returned entry size. If the entry size is |
1008 | * larger than the buffer size, the operation failed. |
1009 | * |
1010 | * From the 'stbuf' argument the st_ino field and bits 12-15 of the |
1011 | * st_mode field are used. The other fields are ignored. |
1012 | * |
1013 | * Note: offsets do not necessarily represent physical offsets, and |
1014 | * could be any marker, that enables the implementation to find a |
1015 | * specific point in the directory stream. |
1016 | * |
1017 | * @param req request handle |
1018 | * @param buf the point where the new entry will be added to the buffer |
1019 | * @param bufsize remaining size of the buffer |
1020 | * @param the name of the entry |
1021 | * @param stbuf the file attributes |
1022 | * @param off the offset of the next entry |
1023 | * @return the space needed for the entry |
1024 | */ |
1025 | size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, |
1026 | const char *name, const struct stat *stbuf, |
1027 | off_t off); |
1028 | |
1029 | /* ----------------------------------------------------------- * |
1030 | * Utility functions * |
1031 | * ----------------------------------------------------------- */ |
1032 | |
1033 | /** |
1034 | * Get the userdata from the request |
1035 | * |
1036 | * @param req request handle |
1037 | * @return the user data passed to fuse_lowlevel_new() |
1038 | */ |
1039 | void *fuse_req_userdata(fuse_req_t req); |
1040 | |
1041 | /** |
1042 | * Get the context from the request |
1043 | * |
1044 | * The pointer returned by this function will only be valid for the |
1045 | * request's lifetime |
1046 | * |
1047 | * @param req request handle |
1048 | * @return the context structure |
1049 | */ |
1050 | const struct fuse_ctx *fuse_req_ctx(fuse_req_t req); |
1051 | |
1052 | /** |
1053 | * Callback function for an interrupt |
1054 | * |
1055 | * @param req interrupted request |
1056 | * @param data user data |
1057 | */ |
1058 | typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data); |
1059 | |
1060 | /** |
1061 | * Register/unregister callback for an interrupt |
1062 | * |
1063 | * If an interrupt has already happened, then the callback function is |
1064 | * called from within this function, hence it's not possible for |
1065 | * interrupts to be lost. |
1066 | * |
1067 | * @param req request handle |
1068 | * @param func the callback function or NULL for unregister |
1069 | * @parm data user data passed to the callback function |
1070 | */ |
1071 | void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, |
1072 | void *data); |
1073 | |
1074 | /** |
1075 | * Check if a request has already been interrupted |
1076 | * |
1077 | * @param req request handle |
1078 | * @return 1 if the request has been interrupted, 0 otherwise |
1079 | */ |
1080 | int fuse_req_interrupted(fuse_req_t req); |
1081 | |
1082 | /* ----------------------------------------------------------- * |
1083 | * Filesystem setup * |
1084 | * ----------------------------------------------------------- */ |
1085 | |
1086 | #ifdef __SOLARIS__ |
1087 | |
1088 | /* Deprecated, don't use */ |
1089 | int fuse_lowlevel_is_lib_option(const char *opt); |
1090 | |
1091 | #endif /* __SOLARIS__ */ |
1092 | |
1093 | /** |
1094 | * Create a low level session |
1095 | * |
1096 | * @param args argument vector |
1097 | * @param op the low level filesystem operations |
1098 | * @param op_size sizeof(struct fuse_lowlevel_ops) |
1099 | * @param userdata user data |
1100 | * @return the created session object, or NULL on failure |
1101 | */ |
1102 | struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, |
1103 | const struct fuse_lowlevel_ops *op, |
1104 | size_t op_size, void *userdata); |
1105 | |
1106 | /* ----------------------------------------------------------- * |
1107 | * Session interface * |
1108 | * ----------------------------------------------------------- */ |
1109 | |
1110 | /** |
1111 | * Session operations |
1112 | * |
1113 | * This is used in session creation |
1114 | */ |
1115 | struct fuse_session_ops { |
1116 | /** |
1117 | * Hook to process a request (mandatory) |
1118 | * |
1119 | * @param data user data passed to fuse_session_new() |
1120 | * @param buf buffer containing the raw request |
1121 | * @param len request length |
1122 | * @param ch channel on which the request was received |
1123 | */ |
1124 | void (*process) (void *data, const char *buf, size_t len, |
1125 | struct fuse_chan *ch); |
1126 | |
1127 | /** |
1128 | * Hook for session exit and reset (optional) |
1129 | * |
1130 | * @param data user data passed to fuse_session_new() |
1131 | * @param val exited status (1 - exited, 0 - not exited) |
1132 | */ |
1133 | void (*exit) (void *data, int val); |
1134 | |
1135 | /** |
1136 | * Hook for querying the current exited status (optional) |
1137 | * |
1138 | * @param data user data passed to fuse_session_new() |
1139 | * @return 1 if exited, 0 if not exited |
1140 | */ |
1141 | int (*exited) (void *data); |
1142 | |
1143 | /** |
1144 | * Hook for cleaning up the channel on destroy (optional) |
1145 | * |
1146 | * @param data user data passed to fuse_session_new() |
1147 | */ |
1148 | void (*destroy) (void *data); |
1149 | }; |
1150 | |
1151 | /** |
1152 | * Create a new session |
1153 | * |
1154 | * @param op session operations |
1155 | * @param data user data |
1156 | * @return new session object, or NULL on failure |
1157 | */ |
1158 | struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data); |
1159 | |
1160 | /** |
1161 | * Assign a channel to a session |
1162 | * |
1163 | * Note: currently only a single channel may be assigned. This may |
1164 | * change in the future |
1165 | * |
1166 | * If a session is destroyed, the assigned channel is also destroyed |
1167 | * |
1168 | * @param se the session |
1169 | * @param ch the channel |
1170 | */ |
1171 | void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch); |
1172 | |
1173 | /** |
1174 | * Remove a channel from a session |
1175 | * |
1176 | * If the channel is not assigned to a session, then this is a no-op |
1177 | * |
1178 | * @param ch the channel to remove |
1179 | */ |
1180 | void fuse_session_remove_chan(struct fuse_chan *ch); |
1181 | |
1182 | /** |
1183 | * Iterate over the channels assigned to a session |
1184 | * |
1185 | * The iterating function needs to start with a NULL channel, and |
1186 | * after that needs to pass the previously returned channel to the |
1187 | * function. |
1188 | * |
1189 | * @param se the session |
1190 | * @param ch the previous channel, or NULL |
1191 | * @return the next channel, or NULL if no more channels exist |
1192 | */ |
1193 | struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, |
1194 | struct fuse_chan *ch); |
1195 | |
1196 | /** |
1197 | * Process a raw request |
1198 | * |
1199 | * @param se the session |
1200 | * @param buf buffer containing the raw request |
1201 | * @param len request length |
1202 | * @param ch channel on which the request was received |
1203 | */ |
1204 | void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, |
1205 | struct fuse_chan *ch); |
1206 | |
1207 | /** |
1208 | * Destroy a session |
1209 | * |
1210 | * @param se the session |
1211 | */ |
1212 | void fuse_session_destroy(struct fuse_session *se); |
1213 | |
1214 | /** |
1215 | * Exit a session |
1216 | * |
1217 | * @param se the session |
1218 | */ |
1219 | void fuse_session_exit(struct fuse_session *se); |
1220 | |
1221 | /** |
1222 | * Reset the exited status of a session |
1223 | * |
1224 | * @param se the session |
1225 | */ |
1226 | void fuse_session_reset(struct fuse_session *se); |
1227 | |
1228 | /** |
1229 | * Query the exited status of a session |
1230 | * |
1231 | * @param se the session |
1232 | * @return 1 if exited, 0 if not exited |
1233 | */ |
1234 | int fuse_session_exited(struct fuse_session *se); |
1235 | |
1236 | /** |
1237 | * Enter a single threaded event loop |
1238 | * |
1239 | * @param se the session |
1240 | * @return 0 on success, -1 on error |
1241 | */ |
1242 | int fuse_session_loop(struct fuse_session *se); |
1243 | |
1244 | /** |
1245 | * Enter a multi-threaded event loop |
1246 | * |
1247 | * @param se the session |
1248 | * @return 0 on success, -1 on error |
1249 | */ |
1250 | int fuse_session_loop_mt(struct fuse_session *se); |
1251 | |
1252 | /* ----------------------------------------------------------- * |
1253 | * Channel interface * |
1254 | * ----------------------------------------------------------- */ |
1255 | |
1256 | /** |
1257 | * Channel operations |
1258 | * |
1259 | * This is used in channel creation |
1260 | */ |
1261 | struct fuse_chan_ops { |
1262 | /** |
1263 | * Hook for receiving a raw request |
1264 | * |
1265 | * @param ch pointer to the channel |
1266 | * @param buf the buffer to store the request in |
1267 | * @param size the size of the buffer |
1268 | * @return the actual size of the raw request, or -1 on error |
1269 | */ |
1270 | int (*receive)(struct fuse_chan **chp, char *buf, size_t size); |
1271 | |
1272 | /** |
1273 | * Hook for sending a raw reply |
1274 | * |
1275 | * A return value of -ENOENT means, that the request was |
1276 | * interrupted, and the reply was discarded |
1277 | * |
1278 | * @param ch the channel |
1279 | * @param iov vector of blocks |
1280 | * @param count the number of blocks in vector |
1281 | * @return zero on success, -errno on failure |
1282 | */ |
1283 | int (*send)(struct fuse_chan *ch, const struct iovec iov[], |
1284 | size_t count); |
1285 | |
1286 | /** |
1287 | * Destroy the channel |
1288 | * |
1289 | * @param ch the channel |
1290 | */ |
1291 | void (*destroy)(struct fuse_chan *ch); |
1292 | }; |
1293 | |
1294 | /** |
1295 | * Create a new channel |
1296 | * |
1297 | * @param op channel operations |
1298 | * @param fd file descriptor of the channel |
1299 | * @param bufsize the minimal receive buffer size |
1300 | * @param data user data |
1301 | * @return the new channel object, or NULL on failure |
1302 | */ |
1303 | struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, |
1304 | size_t bufsize, void *data); |
1305 | |
1306 | /** |
1307 | * Query the file descriptor of the channel |
1308 | * |
1309 | * @param ch the channel |
1310 | * @return the file descriptor passed to fuse_chan_new() |
1311 | */ |
1312 | int fuse_chan_fd(struct fuse_chan *ch); |
1313 | |
1314 | /** |
1315 | * Query the minimal receive buffer size |
1316 | * |
1317 | * @param ch the channel |
1318 | * @return the buffer size passed to fuse_chan_new() |
1319 | */ |
1320 | size_t fuse_chan_bufsize(struct fuse_chan *ch); |
1321 | |
1322 | /** |
1323 | * Query the user data |
1324 | * |
1325 | * @param ch the channel |
1326 | * @return the user data passed to fuse_chan_new() |
1327 | */ |
1328 | void *fuse_chan_data(struct fuse_chan *ch); |
1329 | |
1330 | /** |
1331 | * Query the session to which this channel is assigned |
1332 | * |
1333 | * @param ch the channel |
1334 | * @return the session, or NULL if the channel is not assigned |
1335 | */ |
1336 | struct fuse_session *fuse_chan_session(struct fuse_chan *ch); |
1337 | |
1338 | /** |
1339 | * Receive a raw request |
1340 | * |
1341 | * A return value of -ENODEV means, that the filesystem was unmounted |
1342 | * |
1343 | * @param ch pointer to the channel |
1344 | * @param buf the buffer to store the request in |
1345 | * @param size the size of the buffer |
1346 | * @return the actual size of the raw request, or -errno on error |
1347 | */ |
1348 | int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size); |
1349 | |
1350 | /** |
1351 | * Send a raw reply |
1352 | * |
1353 | * A return value of -ENOENT means, that the request was |
1354 | * interrupted, and the reply was discarded |
1355 | * |
1356 | * @param ch the channel |
1357 | * @param iov vector of blocks |
1358 | * @param count the number of blocks in vector |
1359 | * @return zero on success, -errno on failure |
1360 | */ |
1361 | int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], |
1362 | size_t count); |
1363 | |
1364 | /** |
1365 | * Destroy a channel |
1366 | * |
1367 | * @param ch the channel |
1368 | */ |
1369 | void fuse_chan_destroy(struct fuse_chan *ch); |
1370 | |
1371 | #ifdef __cplusplus |
1372 | } |
1373 | #endif |
1374 | |
1375 | #endif /* _FUSE_LOWLEVEL_H_ */ |
1376 |