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