libfuse: lib/fuse.c Source File

libfuse

fuse.c
1 /*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4
5 Implementation of the high-level FUSE API on top of the low-level
6 API.
7
8 This program can be distributed under the terms of the GNU LGPLv2.
9 See the file COPYING.LIB
10 */
11
12
13 /* For pthread_rwlock_t */
14 #define _GNU_SOURCE
15
16 #include "config.h"
17 #include "fuse_i.h"
18 #include "fuse_lowlevel.h"
19 #include "fuse_opt.h"
20 #include "fuse_misc.h"
21 #include "fuse_kernel.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stddef.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <time.h>
30 #include <fcntl.h>
31 #include <limits.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <dlfcn.h>
35 #include <assert.h>
36 #include <poll.h>
37 #include <sys/param.h>
38 #include <sys/uio.h>
39 #include <sys/time.h>
40 #include <sys/mman.h>
41 #include <sys/file.h>
42
43 #define FUSE_NODE_SLAB 1
44
45 #ifndef MAP_ANONYMOUS
46 #undef FUSE_NODE_SLAB
47 #endif
48
49 #ifndef RENAME_EXCHANGE
50 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
51 #endif
52
53 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
54
55 #define FUSE_UNKNOWN_INO 0xffffffff
56 #define OFFSET_MAX 0x7fffffffffffffffLL
57
58 #define NODE_TABLE_MIN_SIZE 8192
59
60 struct fuse_fs {
61 struct fuse_operations op;
62 struct fuse_module *m;
63 void *user_data;
64 int debug;
65 };
66
67 struct fusemod_so {
68 void *handle;
69 int ctr;
70 };
71
72 struct lock_queue_element {
73 struct lock_queue_element *next;
74 pthread_cond_t cond;
75 fuse_ino_t nodeid1;
76 const char *name1;
77 char **path1;
78 struct node **wnode1;
79 fuse_ino_t nodeid2;
80 const char *name2;
81 char **path2;
82 struct node **wnode2;
83 int err;
84 bool first_locked : 1;
85 bool second_locked : 1;
86 bool done : 1;
87 };
88
89 struct node_table {
90 struct node **array;
91 size_t use;
92 size_t size;
93 size_t split;
94 };
95
96 #define container_of(ptr, type, member) ({ \
97 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
98 (type *)( (char *)__mptr - offsetof(type,member) );})
99
100 #define list_entry(ptr, type, member) \
101 container_of(ptr, type, member)
102
103 struct list_head {
104 struct list_head *next;
105 struct list_head *prev;
106 };
107
108 struct node_slab {
109 struct list_head list; /* must be the first member */
110 struct list_head freelist;
111 int used;
112 };
113
114 struct fuse {
115 struct fuse_session *se;
116 struct node_table name_table;
117 struct node_table id_table;
118 struct list_head lru_table;
119 fuse_ino_t ctr;
120 unsigned int generation;
121 unsigned int hidectr;
122 pthread_mutex_t lock;
123 struct fuse_config conf;
124 int intr_installed;
125 struct fuse_fs *fs;
126 struct lock_queue_element *lockq;
127 int pagesize;
128 struct list_head partial_slabs;
129 struct list_head full_slabs;
130 pthread_t prune_thread;
131 };
132
133 struct lock {
134 int type;
135 off_t start;
136 off_t end;
137 pid_t pid;
138 uint64_t owner;
139 struct lock *next;
140 };
141
142 struct node {
143 struct node *name_next;
144 struct node *id_next;
145 fuse_ino_t nodeid;
146 unsigned int generation;
147 int refctr;
148 struct node *parent;
149 char *name;
150 uint64_t nlookup;
151 int open_count;
152 struct timespec stat_updated;
153 struct timespec mtime;
154 off_t size;
155 struct lock *locks;
156 unsigned int is_hidden : 1;
157 unsigned int cache_valid : 1;
158 int treelock;
159 char inline_name[32];
160 };
161
162 #define TREELOCK_WRITE -1
163 #define TREELOCK_WAIT_OFFSET INT_MIN
164
165 struct node_lru {
166 struct node node;
167 struct list_head lru;
168 struct timespec forget_time;
169 };
170
171 struct fuse_direntry {
172 struct stat stat;
173 char *name;
174 struct fuse_direntry *next;
175 };
176
177 struct fuse_dh {
178 pthread_mutex_t lock;
179 struct fuse *fuse;
180 fuse_req_t req;
181 char *contents;
182 struct fuse_direntry *first;
183 struct fuse_direntry **last;
184 unsigned len;
185 unsigned size;
186 unsigned needlen;
187 int filled;
188 uint64_t fh;
189 int error;
190 fuse_ino_t nodeid;
191 };
192
193 struct fuse_context_i {
194 struct fuse_context ctx;
195 fuse_req_t req;
196 };
197
198 /* Defined by FUSE_REGISTER_MODULE() in lib/modules/subdir.c and iconv.c. */
199 extern fuse_module_factory_t fuse_module_subdir_factory;
200 #ifdef HAVE_ICONV
201 extern fuse_module_factory_t fuse_module_iconv_factory;
202 #endif
203
204 static pthread_key_t fuse_context_key;
205 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
206 static int fuse_context_ref;
207 static struct fuse_module *fuse_modules = NULL;
208
209 static int fuse_register_module(const char *name,
210 fuse_module_factory_t factory,
211 struct fusemod_so *so)
212 {
213 struct fuse_module *mod;
214
215 mod = calloc(1, sizeof(struct fuse_module));
216 if (!mod) {
217 fprintf(stderr, "fuse: failed to allocate module\n");
218 return -1;
219 }
220 mod->name = strdup(name);
221 if (!mod->name) {
222 fprintf(stderr, "fuse: failed to allocate module name\n");
223 free(mod);
224 return -1;
225 }
226 mod->factory = factory;
227 mod->ctr = 0;
228 mod->so = so;
229 if (mod->so)
230 mod->so->ctr++;
231 mod->next = fuse_modules;
232 fuse_modules = mod;
233
234 return 0;
235 }
236
237 static void fuse_unregister_module(struct fuse_module *m)
238 {
239 struct fuse_module **mp;
240 for (mp = &fuse_modules; *mp; mp = &(*mp)->next) {
241 if (*mp == m) {
242 *mp = (*mp)->next;
243 break;
244 }
245 }
246 free(m->name);
247 free(m);
248 }
249
250 static int fuse_load_so_module(const char *module)
251 {
252 int ret = -1;
253 char *tmp;
254 struct fusemod_so *so;
255 fuse_module_factory_t factory;
256
257 tmp = malloc(strlen(module) + 64);
258 if (!tmp) {
259 fprintf(stderr, "fuse: memory allocation failed\n");
260 return -1;
261 }
262 sprintf(tmp, "libfusemod_%s.so", module);
263 so = calloc(1, sizeof(struct fusemod_so));
264 if (!so) {
265 fprintf(stderr, "fuse: failed to allocate module so\n");
266 goto out;
267 }
268
269 so->handle = dlopen(tmp, RTLD_NOW);
270 if (so->handle == NULL) {
271 fprintf(stderr, "fuse: dlopen(%s) failed: %s\n",
272 tmp, dlerror());
273 goto out_free_so;
274 }
275
276 sprintf(tmp, "fuse_module_%s_factory", module);
277 *(void**)(&factory) = dlsym(so->handle, tmp);
278 if (factory == NULL) {
279 fprintf(stderr, "fuse: symbol <%s> not found in module: %s\n",
280 tmp, dlerror());
281 goto out_dlclose;
282 }
283 ret = fuse_register_module(module, factory, so);
284 if (ret)
285 goto out_dlclose;
286
287 out:
288 free(tmp);
289 return ret;
290
291 out_dlclose:
292 dlclose(so->handle);
293 out_free_so:
294 free(so);
295 goto out;
296 }
297
298 static struct fuse_module *fuse_find_module(const char *module)
299 {
300 struct fuse_module *m;
301 for (m = fuse_modules; m; m = m->next) {
302 if (strcmp(module, m->name) == 0) {
303 m->ctr++;
304 break;
305 }
306 }
307 return m;
308 }
309
310 static struct fuse_module *fuse_get_module(const char *module)
311 {
312 struct fuse_module *m;
313
314 pthread_mutex_lock(&fuse_context_lock);
315 m = fuse_find_module(module);
316 if (!m) {
317 int err = fuse_load_so_module(module);
318 if (!err)
319 m = fuse_find_module(module);
320 }
321 pthread_mutex_unlock(&fuse_context_lock);
322 return m;
323 }
324
325 static void fuse_put_module(struct fuse_module *m)
326 {
327 pthread_mutex_lock(&fuse_context_lock);
328 if (m->so)
329 assert(m->ctr > 0);
330 /* Builtin modules may already have m->ctr == 0 */
331 if (m->ctr > 0)
332 m->ctr--;
333 if (!m->ctr && m->so) {
334 struct fusemod_so *so = m->so;
335 assert(so->ctr > 0);
336 so->ctr--;
337 if (!so->ctr) {
338 struct fuse_module **mp;
339 for (mp = &fuse_modules; *mp;) {
340 if ((*mp)->so == so)
341 fuse_unregister_module(*mp);
342 else
343 mp = &(*mp)->next;
344 }
345 dlclose(so->handle);
346 free(so);
347 }
348 } else if (!m->ctr) {
349 fuse_unregister_module(m);
350 }
351 pthread_mutex_unlock(&fuse_context_lock);
352 }
353
354 static void init_list_head(struct list_head *list)
355 {
356 list->next = list;
357 list->prev = list;
358 }
359
360 static int list_empty(const struct list_head *head)
361 {
362 return head->next == head;
363 }
364
365 static void list_add(struct list_head *new, struct list_head *prev,
366 struct list_head *next)
367 {
368 next->prev = new;
369 new->next = next;
370 new->prev = prev;
371 prev->next = new;
372 }
373
374 static inline void list_add_head(struct list_head *new, struct list_head *head)
375 {
376 list_add(new, head, head->next);
377 }
378
379 static inline void list_add_tail(struct list_head *new, struct list_head *head)
380 {
381 list_add(new, head->prev, head);
382 }
383
384 static inline void list_del(struct list_head *entry)
385 {
386 struct list_head *prev = entry->prev;
387 struct list_head *next = entry->next;
388
389 next->prev = prev;
390 prev->next = next;
391 }
392
393 static inline int lru_enabled(struct fuse *f)
394 {
395 return f->conf.remember > 0;
396 }
397
398 static struct node_lru *node_lru(struct node *node)
399 {
400 return (struct node_lru *) node;
401 }
402
403 static size_t get_node_size(struct fuse *f)
404 {
405 if (lru_enabled(f))
406 return sizeof(struct node_lru);
407 else
408 return sizeof(struct node);
409 }
410
411 #ifdef FUSE_NODE_SLAB
412 static struct node_slab *list_to_slab(struct list_head *head)
413 {
414 return (struct node_slab *) head;
415 }
416
417 static struct node_slab *node_to_slab(struct fuse *f, struct node *node)
418 {
419 return (struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
420 }
421
422 static int alloc_slab(struct fuse *f)
423 {
424 void *mem;
425 struct node_slab *slab;
426 char *start;
427 size_t num;
428 size_t i;
429 size_t node_size = get_node_size(f);
430
431 mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
432 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
433
434 if (mem == MAP_FAILED)
435 return -1;
436
437 slab = mem;
438 init_list_head(&slab->freelist);
439 slab->used = 0;
440 num = (f->pagesize - sizeof(struct node_slab)) / node_size;
441
442 start = (char *) mem + f->pagesize - num * node_size;
443 for (i = 0; i < num; i++) {
444 struct list_head *n;
445
446 n = (struct list_head *) (start + i * node_size);
447 list_add_tail(n, &slab->freelist);
448 }
449 list_add_tail(&slab->list, &f->partial_slabs);
450
451 return 0;
452 }
453
454 static struct node *alloc_node(struct fuse *f)
455 {
456 struct node_slab *slab;
457 struct list_head *node;
458
459 if (list_empty(&f->partial_slabs)) {
460 int res = alloc_slab(f);
461 if (res != 0)
462 return NULL;
463 }
464 slab = list_to_slab(f->partial_slabs.next);
465 slab->used++;
466 node = slab->freelist.next;
467 list_del(node);
468 if (list_empty(&slab->freelist)) {
469 list_del(&slab->list);
470 list_add_tail(&slab->list, &f->full_slabs);
471 }
472 memset(node, 0, sizeof(struct node));
473
474 return (struct node *) node;
475 }
476
477 static void free_slab(struct fuse *f, struct node_slab *slab)
478 {
479 int res;
480
481 list_del(&slab->list);
482 res = munmap(slab, f->pagesize);
483 if (res == -1)
484 fprintf(stderr, "fuse warning: munmap(%p) failed\n", slab);
485 }
486
487 static void free_node_mem(struct fuse *f, struct node *node)
488 {
489 struct node_slab *slab = node_to_slab(f, node);
490 struct list_head *n = (struct list_head *) node;
491
492 slab->used--;
493 if (slab->used) {
494 if (list_empty(&slab->freelist)) {
495 list_del(&slab->list);
496 list_add_tail(&slab->list, &f->partial_slabs);
497 }
498 list_add_head(n, &slab->freelist);
499 } else {
500 free_slab(f, slab);
501 }
502 }
503 #else
504 static struct node *alloc_node(struct fuse *f)
505 {
506 return (struct node *) calloc(1, get_node_size(f));
507 }
508
509 static void free_node_mem(struct fuse *f, struct node *node)
510 {
511 (void) f;
512 free(node);
513 }
514 #endif
515
516 static size_t id_hash(struct fuse *f, fuse_ino_t ino)
517 {
518 uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
519 uint64_t oldhash = hash % (f->id_table.size / 2);
520
521 if (oldhash >= f->id_table.split)
522 return oldhash;
523 else
524 return hash;
525 }
526
527 static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
528 {
529 size_t hash = id_hash(f, nodeid);
530 struct node *node;
531
532 for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
533 if (node->nodeid == nodeid)
534 return node;
535
536 return NULL;
537 }
538
539 static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
540 {
541 struct node *node = get_node_nocheck(f, nodeid);
542 if (!node) {
543 fprintf(stderr, "fuse internal error: node %llu not found\n",
544 (unsigned long long) nodeid);
545 abort();
546 }
547 return node;
548 }
549
550 static void curr_time(struct timespec *now);
551 static double diff_timespec(const struct timespec *t1,
552 const struct timespec *t2);
553
554 static void remove_node_lru(struct node *node)
555 {
556 struct node_lru *lnode = node_lru(node);
557 list_del(&lnode->lru);
558 init_list_head(&lnode->lru);
559 }
560
561 static void set_forget_time(struct fuse *f, struct node *node)
562 {
563 struct node_lru *lnode = node_lru(node);
564
565 list_del(&lnode->lru);
566 list_add_tail(&lnode->lru, &f->lru_table);
567 curr_time(&lnode->forget_time);
568 }
569
570 static void free_node(struct fuse *f, struct node *node)
571 {
572 if (node->name != node->inline_name)
573 free(node->name);
574 free_node_mem(f, node);
575 }
576
577 static void node_table_reduce(struct node_table *t)
578 {
579 size_t newsize = t->size / 2;
580 void *newarray;
581
582 if (newsize < NODE_TABLE_MIN_SIZE)
583 return;
584
585 newarray = realloc(t->array, sizeof(struct node *) * newsize);
586 if (newarray != NULL)
587 t->array = newarray;
588
589 t->size = newsize;
590 t->split = t->size / 2;
591 }
592
593 static void remerge_id(struct fuse *f)
594 {
595 struct node_table *t = &f->id_table;
596 int iter;
597
598 if (t->split == 0)
599 node_table_reduce(t);
600
601 for (iter = 8; t->split > 0 && iter; iter--) {
602 struct node **upper;
603
604 t->split--;
605 upper = &t->array[t->split + t->size / 2];
606 if (*upper) {
607 struct node **nodep;
608
609 for (nodep = &t->array[t->split]; *nodep;
610 nodep = &(*nodep)->id_next);
611
612 *nodep = *upper;
613 *upper = NULL;
614 break;
615 }
616 }
617 }
618
619 static void unhash_id(struct fuse *f, struct node *node)
620 {
621 struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
622
623 for (; *nodep != NULL; nodep = &(*nodep)->id_next)
624 if (*nodep == node) {
625 *nodep = node->id_next;
626 f->id_table.use--;
627
628 if(f->id_table.use < f->id_table.size / 4)
629 remerge_id(f);
630 return;
631 }
632 }
633
634 static int node_table_resize(struct node_table *t)
635 {
636 size_t newsize = t->size * 2;
637 void *newarray;
638
639 newarray = realloc(t->array, sizeof(struct node *) * newsize);
640 if (newarray == NULL)
641 return -1;
642
643 t->array = newarray;
644 memset(t->array + t->size, 0, t->size * sizeof(struct node *));
645 t->size = newsize;
646 t->split = 0;
647
648 return 0;
649 }
650
651 static void rehash_id(struct fuse *f)
652 {
653 struct node_table *t = &f->id_table;
654 struct node **nodep;
655 struct node **next;
656 size_t hash;
657
658 if (t->split == t->size / 2)
659 return;
660
661 hash = t->split;
662 t->split++;
663 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
664 struct node *node = *nodep;
665 size_t newhash = id_hash(f, node->nodeid);
666
667 if (newhash != hash) {
668 next = nodep;
669 *nodep = node->id_next;
670 node->id_next = t->array[newhash];
671 t->array[newhash] = node;
672 } else {
673 next = &node->id_next;
674 }
675 }
676 if (t->split == t->size / 2)
677 node_table_resize(t);
678 }
679
680 static void hash_id(struct fuse *f, struct node *node)
681 {
682 size_t hash = id_hash(f, node->nodeid);
683 node->id_next = f->id_table.array[hash];
684 f->id_table.array[hash] = node;
685 f->id_table.use++;
686
687 if (f->id_table.use >= f->id_table.size / 2)
688 rehash_id(f);
689 }
690
691 static size_t name_hash(struct fuse *f, fuse_ino_t parent,
692 const char *name)
693 {
694 uint64_t hash = parent;
695 uint64_t oldhash;
696
697 for (; *name; name++)
698 hash = hash * 31 + (unsigned char) *name;
699
700 hash %= f->name_table.size;
701 oldhash = hash % (f->name_table.size / 2);
702 if (oldhash >= f->name_table.split)
703 return oldhash;
704 else
705 return hash;
706 }
707
708 static void unref_node(struct fuse *f, struct node *node);
709
710 static void remerge_name(struct fuse *f)
711 {
712 struct node_table *t = &f->name_table;
713 int iter;
714
715 if (t->split == 0)
716 node_table_reduce(t);
717
718 for (iter = 8; t->split > 0 && iter; iter--) {
719 struct node **upper;
720
721 t->split--;
722 upper = &t->array[t->split + t->size / 2];
723 if (*upper) {
724 struct node **nodep;
725
726 for (nodep = &t->array[t->split]; *nodep;
727 nodep = &(*nodep)->name_next);
728
729 *nodep = *upper;
730 *upper = NULL;
731 break;
732 }
733 }
734 }
735
736 static void unhash_name(struct fuse *f, struct node *node)
737 {
738 if (node->name) {
739 size_t hash = name_hash(f, node->parent->nodeid, node->name);
740 struct node **nodep = &f->name_table.array[hash];
741
742 for (; *nodep != NULL; nodep = &(*nodep)->name_next)
743 if (*nodep == node) {
744 *nodep = node->name_next;
745 node->name_next = NULL;
746 unref_node(f, node->parent);
747 if (node->name != node->inline_name)
748 free(node->name);
749 node->name = NULL;
750 node->parent = NULL;
751 f->name_table.use--;
752
753 if (f->name_table.use < f->name_table.size / 4)
754 remerge_name(f);
755 return;
756 }
757 fprintf(stderr,
758 "fuse internal error: unable to unhash node: %llu\n",
759 (unsigned long long) node->nodeid);
760 abort();
761 }
762 }
763
764 static void rehash_name(struct fuse *f)
765 {
766 struct node_table *t = &f->name_table;
767 struct node **nodep;
768 struct node **next;
769 size_t hash;
770
771 if (t->split == t->size / 2)
772 return;
773
774 hash = t->split;
775 t->split++;
776 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
777 struct node *node = *nodep;
778 size_t newhash = name_hash(f, node->parent->nodeid, node->name);
779
780 if (newhash != hash) {
781 next = nodep;
782 *nodep = node->name_next;
783 node->name_next = t->array[newhash];
784 t->array[newhash] = node;
785 } else {
786 next = &node->name_next;
787 }
788 }
789 if (t->split == t->size / 2)
790 node_table_resize(t);
791 }
792
793 static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
794 const char *name)
795 {
796 size_t hash = name_hash(f, parentid, name);
797 struct node *parent = get_node(f, parentid);
798 if (strlen(name) < sizeof(node->inline_name)) {
799 strcpy(node->inline_name, name);
800 node->name = node->inline_name;
801 } else {
802 node->name = strdup(name);
803 if (node->name == NULL)
804 return -1;
805 }
806
807 parent->refctr ++;
808 node->parent = parent;
809 node->name_next = f->name_table.array[hash];
810 f->name_table.array[hash] = node;
811 f->name_table.use++;
812
813 if (f->name_table.use >= f->name_table.size / 2)
814 rehash_name(f);
815
816 return 0;
817 }
818
819 static void delete_node(struct fuse *f, struct node *node)
820 {
821 if (f->conf.debug)
822 fprintf(stderr, "DELETE: %llu\n",
823 (unsigned long long) node->nodeid);
824
825 assert(node->treelock == 0);
826 unhash_name(f, node);
827 if (lru_enabled(f))
828 remove_node_lru(node);
829 unhash_id(f, node);
830 free_node(f, node);
831 }
832
833 static void unref_node(struct fuse *f, struct node *node)
834 {
835 assert(node->refctr > 0);
836 node->refctr --;
837 if (!node->refctr)
838 delete_node(f, node);
839 }
840
841 static fuse_ino_t next_id(struct fuse *f)
842 {
843 do {
844 f->ctr = (f->ctr + 1) & 0xffffffff;
845 if (!f->ctr)
846 f->generation ++;
847 } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
848 get_node_nocheck(f, f->ctr) != NULL);
849 return f->ctr;
850 }
851
852 static struct node *lookup_node(struct fuse *f, fuse_ino_t parent,
853 const char *name)
854 {
855 size_t hash = name_hash(f, parent, name);
856 struct node *node;
857
858 for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
859 if (node->parent->nodeid == parent &&
860 strcmp(node->name, name) == 0)
861 return node;
862
863 return NULL;
864 }
865
866 static void inc_nlookup(struct node *node)
867 {
868 if (!node->nlookup)
869 node->refctr++;
870 node->nlookup++;
871 }
872
873 static struct node *find_node(struct fuse *f, fuse_ino_t parent,
874 const char *name)
875 {
876 struct node *node;
877
878 pthread_mutex_lock(&f->lock);
879 if (!name)
880 node = get_node(f, parent);
881 else
882 node = lookup_node(f, parent, name);
883 if (node == NULL) {
884 node = alloc_node(f);
885 if (node == NULL)
886 goto out_err;
887
888 node->nodeid = next_id(f);
889 node->generation = f->generation;
890 if (f->conf.remember)
891 inc_nlookup(node);
892
893 if (hash_name(f, node, parent, name) == -1) {
894 free_node(f, node);
895 node = NULL;
896 goto out_err;
897 }
898 hash_id(f, node);
899 if (lru_enabled(f)) {
900 struct node_lru *lnode = node_lru(node);
901 init_list_head(&lnode->lru);
902 }
903 } else if (lru_enabled(f) && node->nlookup == 1) {
904 remove_node_lru(node);
905 }
906 inc_nlookup(node);
907 out_err:
908 pthread_mutex_unlock(&f->lock);
909 return node;
910 }
911
912 static int lookup_path_in_cache(struct fuse *f,
913 const char *path, fuse_ino_t *inop)
914 {
915 char *tmp = strdup(path);
916 if (!tmp)
917 return -ENOMEM;
918
919 pthread_mutex_lock(&f->lock);
920 fuse_ino_t ino = FUSE_ROOT_ID;
921
922 int err = 0;
923 char *save_ptr;
924 char *path_element = strtok_r(tmp, "/", &save_ptr);
925 while (path_element != NULL) {
926 struct node *node = lookup_node(f, ino, path_element);
927 if (node == NULL) {
928 err = -ENOENT;
929 break;
930 }
931 ino = node->nodeid;
932 path_element = strtok_r(NULL, "/", &save_ptr);
933 }
934 pthread_mutex_unlock(&f->lock);
935 free(tmp);
936
937 if (!err)
938 *inop = ino;
939 return err;
940 }
941
942 static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
943 {
944 size_t len = strlen(name);
945
946 if (s - len <= *buf) {
947 unsigned pathlen = *bufsize - (s - *buf);
948 unsigned newbufsize = *bufsize;
949 char *newbuf;
950
951 while (newbufsize < pathlen + len + 1) {
952 if (newbufsize >= 0x80000000)
953 newbufsize = 0xffffffff;
954 else
955 newbufsize *= 2;
956 }
957
958 newbuf = realloc(*buf, newbufsize);
959 if (newbuf == NULL)
960 return NULL;
961
962 *buf = newbuf;
963 s = newbuf + newbufsize - pathlen;
964 memmove(s, newbuf + *bufsize - pathlen, pathlen);
965 *bufsize = newbufsize;
966 }
967 s -= len;
968 strncpy(s, name, len);
969 s--;
970 *s = '/';
971
972 return s;
973 }
974
975 static void unlock_path(struct fuse *f, fuse_ino_t nodeid, struct node *wnode,
976 struct node *end)
977 {
978 struct node *node;
979
980 if (wnode) {
981 assert(wnode->treelock == TREELOCK_WRITE);
982 wnode->treelock = 0;
983 }
984
985 for (node = get_node(f, nodeid);
986 node != end && node->nodeid != FUSE_ROOT_ID; node = node->parent) {
987 assert(node->treelock != 0);
988 assert(node->treelock != TREELOCK_WAIT_OFFSET);
989 assert(node->treelock != TREELOCK_WRITE);
990 node->treelock--;
991 if (node->treelock == TREELOCK_WAIT_OFFSET)
992 node->treelock = 0;
993 }
994 }
995
996 static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
997 char **path, struct node **wnodep, bool need_lock)
998 {
999 unsigned bufsize = 256;
1000 char *buf;
1001 char *s;
1002 struct node *node;
1003 struct node *wnode = NULL;
1004 int err;
1005
1006 *path = NULL;
1007
1008 err = -ENOMEM;
1009 buf = malloc(bufsize);
1010 if (buf == NULL)
1011 goto out_err;
1012
1013 s = buf + bufsize - 1;
1014 *s = '\0';
1015
1016 if (name != NULL) {
1017 s = add_name(&buf, &bufsize, s, name);
1018 err = -ENOMEM;
1019 if (s == NULL)
1020 goto out_free;
1021 }
1022
1023 if (wnodep) {
1024 assert(need_lock);
1025 wnode = lookup_node(f, nodeid, name);
1026 if (wnode) {
1027 if (wnode->treelock != 0) {
1028 if (wnode->treelock > 0)
1029 wnode->treelock += TREELOCK_WAIT_OFFSET;
1030 err = -EAGAIN;
1031 goto out_free;
1032 }
1033 wnode->treelock = TREELOCK_WRITE;
1034 }
1035 }
1036
1037 for (node = get_node(f, nodeid); node->nodeid != FUSE_ROOT_ID;
1038 node = node->parent) {
1039 err = -ENOENT;
1040 if (node->name == NULL || node->parent == NULL)
1041 goto out_unlock;
1042
1043 err = -ENOMEM;
1044 s = add_name(&buf, &bufsize, s, node->name);
1045 if (s == NULL)
1046 goto out_unlock;
1047
1048 if (need_lock) {
1049 err = -EAGAIN;
1050 if (node->treelock < 0)
1051 goto out_unlock;
1052
1053 node->treelock++;
1054 }
1055 }
1056
1057 if (s[0])
1058 memmove(buf, s, bufsize - (s - buf));
1059 else
1060 strcpy(buf, "/");
1061
1062 *path = buf;
1063 if (wnodep)
1064 *wnodep = wnode;
1065
1066 return 0;
1067
1068 out_unlock:
1069 if (need_lock)
1070 unlock_path(f, nodeid, wnode, node);
1071 out_free:
1072 free(buf);
1073
1074 out_err:
1075 return err;
1076 }
1077
1078 static void queue_element_unlock(struct fuse *f, struct lock_queue_element *qe)
1079 {
1080 struct node *wnode;
1081
1082 if (qe->first_locked) {
1083 wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1084 unlock_path(f, qe->nodeid1, wnode, NULL);
1085 qe->first_locked = false;
1086 }
1087 if (qe->second_locked) {
1088 wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1089 unlock_path(f, qe->nodeid2, wnode, NULL);
1090 qe->second_locked = false;
1091 }
1092 }
1093
1094 static void queue_element_wakeup(struct fuse *f, struct lock_queue_element *qe)
1095 {
1096 int err;
1097 bool first = (qe == f->lockq);
1098
1099 if (!qe->path1) {
1100 /* Just waiting for it to be unlocked */
1101 if (get_node(f, qe->nodeid1)->treelock == 0)
1102 pthread_cond_signal(&qe->cond);
1103
1104 return;
1105 }
1106
1107 if (!qe->first_locked) {
1108 err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1109 qe->wnode1, true);
1110 if (!err)
1111 qe->first_locked = true;
1112 else if (err != -EAGAIN)
1113 goto err_unlock;
1114 }
1115 if (!qe->second_locked && qe->path2) {
1116 err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1117 qe->wnode2, true);
1118 if (!err)
1119 qe->second_locked = true;
1120 else if (err != -EAGAIN)
1121 goto err_unlock;
1122 }
1123
1124 if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1125 err = 0;
1126 goto done;
1127 }
1128
1129 /*
1130 * Only let the first element be partially locked otherwise there could
1131 * be a deadlock.
1132 *
1133 * But do allow the first element to be partially locked to prevent
1134 * starvation.
1135 */
1136 if (!first)
1137 queue_element_unlock(f, qe);
1138
1139 /* keep trying */
1140 return;
1141
1142 err_unlock:
1143 queue_element_unlock(f, qe);
1144 done:
1145 qe->err = err;
1146 qe->done = true;
1147 pthread_cond_signal(&qe->cond);
1148 }
1149
1150 static void wake_up_queued(struct fuse *f)
1151 {
1152 struct lock_queue_element *qe;
1153
1154 for (qe = f->lockq; qe != NULL; qe = qe->next)
1155 queue_element_wakeup(f, qe);
1156 }
1157
1158 static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid,
1159 const char *name, bool wr)
1160 {
1161 if (f->conf.debug) {
1162 struct node *wnode = NULL;
1163
1164 if (wr)
1165 wnode = lookup_node(f, nodeid, name);
1166
1167 if (wnode) {
1168 fprintf(stderr, "%s %llu (w)\n",
1169 msg, (unsigned long long) wnode->nodeid);
1170 } else {
1171 fprintf(stderr, "%s %llu\n",
1172 msg, (unsigned long long) nodeid);
1173 }
1174 }
1175 }
1176
1177 static void queue_path(struct fuse *f, struct lock_queue_element *qe)
1178 {
1179 struct lock_queue_element **qp;
1180
1181 qe->done = false;
1182 qe->first_locked = false;
1183 qe->second_locked = false;
1184 pthread_cond_init(&qe->cond, NULL);
1185 qe->next = NULL;
1186 for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1187 *qp = qe;
1188 }
1189
1190 static void dequeue_path(struct fuse *f, struct lock_queue_element *qe)
1191 {
1192 struct lock_queue_element **qp;
1193
1194 pthread_cond_destroy(&qe->cond);
1195 for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1196 *qp = qe->next;
1197 }
1198
1199 static int wait_path(struct fuse *f, struct lock_queue_element *qe)
1200 {
1201 queue_path(f, qe);
1202
1203 do {
1204 pthread_cond_wait(&qe->cond, &f->lock);
1205 } while (!qe->done);
1206
1207 dequeue_path(f, qe);
1208
1209 return qe->err;
1210 }
1211
1212 static int get_path_common(struct fuse *f, fuse_ino_t nodeid, const char *name,
1213 char **path, struct node **wnode)
1214 {
1215 int err;
1216
1217 pthread_mutex_lock(&f->lock);
1218 err = try_get_path(f, nodeid, name, path, wnode, true);
1219 if (err == -EAGAIN) {
1220 struct lock_queue_element qe = {
1221 .nodeid1 = nodeid,
1222 .name1 = name,
1223 .path1 = path,
1224 .wnode1 = wnode,
1225 };
1226 debug_path(f, "QUEUE PATH", nodeid, name, !!wnode);
1227 err = wait_path(f, &qe);
1228 debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode);
1229 }
1230 pthread_mutex_unlock(&f->lock);
1231
1232 return err;
1233 }
1234
1235 static int get_path(struct fuse *f, fuse_ino_t nodeid, char **path)
1236 {
1237 return get_path_common(f, nodeid, NULL, path, NULL);
1238 }
1239
1240 static int get_path_nullok(struct fuse *f, fuse_ino_t nodeid, char **path)
1241 {
1242 int err = 0;
1243
1244 if (f->conf.nullpath_ok) {
1245 *path = NULL;
1246 } else {
1247 err = get_path_common(f, nodeid, NULL, path, NULL);
1248 if (err == -ENOENT)
1249 err = 0;
1250 }
1251
1252 return err;
1253 }
1254
1255 static int get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name,
1256 char **path)
1257 {
1258 return get_path_common(f, nodeid, name, path, NULL);
1259 }
1260
1261 static int get_path_wrlock(struct fuse *f, fuse_ino_t nodeid, const char *name,
1262 char **path, struct node **wnode)
1263 {
1264 return get_path_common(f, nodeid, name, path, wnode);
1265 }
1266
1267 #if defined(__FreeBSD__)
1268 #define CHECK_DIR_LOOP
1269 #endif
1270
1271 #if defined(CHECK_DIR_LOOP)
1272 static int check_dir_loop(struct fuse *f,
1273 fuse_ino_t nodeid1, const char *name1,
1274 fuse_ino_t nodeid2, const char *name2)
1275 {
1276 struct node *node, *node1, *node2;
1277 fuse_ino_t id1, id2;
1278
1279 node1 = lookup_node(f, nodeid1, name1);
1280 id1 = node1 ? node1->nodeid : nodeid1;
1281
1282 node2 = lookup_node(f, nodeid2, name2);
1283 id2 = node2 ? node2->nodeid : nodeid2;
1284
1285 for (node = get_node(f, id2); node->nodeid != FUSE_ROOT_ID;
1286 node = node->parent) {
1287 if (node->name == NULL || node->parent == NULL)
1288 break;
1289
1290 if (node->nodeid != id2 && node->nodeid == id1)
1291 return -EINVAL;
1292 }
1293
1294 if (node2)
1295 {
1296 for (node = get_node(f, id1); node->nodeid != FUSE_ROOT_ID;
1297 node = node->parent) {
1298 if (node->name == NULL || node->parent == NULL)
1299 break;
1300
1301 if (node->nodeid != id1 && node->nodeid == id2)
1302 return -ENOTEMPTY;
1303 }
1304 }
1305
1306 return 0;
1307 }
1308 #endif
1309
1310 static int try_get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1311 fuse_ino_t nodeid2, const char *name2,
1312 char **path1, char **path2,
1313 struct node **wnode1, struct node **wnode2)
1314 {
1315 int err;
1316
1317 /* FIXME: locking two paths needs deadlock checking */
1318 err = try_get_path(f, nodeid1, name1, path1, wnode1, true);
1319 if (!err) {
1320 err = try_get_path(f, nodeid2, name2, path2, wnode2, true);
1321 if (err) {
1322 struct node *wn1 = wnode1 ? *wnode1 : NULL;
1323
1324 unlock_path(f, nodeid1, wn1, NULL);
1325 free(*path1);
1326 }
1327 }
1328 return err;
1329 }
1330
1331 static int get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1332 fuse_ino_t nodeid2, const char *name2,
1333 char **path1, char **path2,
1334 struct node **wnode1, struct node **wnode2)
1335 {
1336 int err;
1337
1338 pthread_mutex_lock(&f->lock);
1339
1340 #if defined(CHECK_DIR_LOOP)
1341 if (name1)
1342 {
1343 // called during rename; perform dir loop check
1344 err = check_dir_loop(f, nodeid1, name1, nodeid2, name2);
1345 if (err)
1346 goto out_unlock;
1347 }
1348 #endif
1349
1350 err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1351 path1, path2, wnode1, wnode2);
1352 if (err == -EAGAIN) {
1353 struct lock_queue_element qe = {
1354 .nodeid1 = nodeid1,
1355 .name1 = name1,
1356 .path1 = path1,
1357 .wnode1 = wnode1,
1358 .nodeid2 = nodeid2,
1359 .name2 = name2,
1360 .path2 = path2,
1361 .wnode2 = wnode2,
1362 };
1363
1364 debug_path(f, "QUEUE PATH1", nodeid1, name1, !!wnode1);
1365 debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1366 err = wait_path(f, &qe);
1367 debug_path(f, "DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1368 debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1369 }
1370
1371 #if defined(CHECK_DIR_LOOP)
1372 out_unlock:
1373 #endif
1374 pthread_mutex_unlock(&f->lock);
1375
1376 return err;
1377 }
1378
1379 static void free_path_wrlock(struct fuse *f, fuse_ino_t nodeid,
1380 struct node *wnode, char *path)
1381 {
1382 pthread_mutex_lock(&f->lock);
1383 unlock_path(f, nodeid, wnode, NULL);
1384 if (f->lockq)
1385 wake_up_queued(f);
1386 pthread_mutex_unlock(&f->lock);
1387 free(path);
1388 }
1389
1390 static void free_path(struct fuse *f, fuse_ino_t nodeid, char *path)
1391 {
1392 if (path)
1393 free_path_wrlock(f, nodeid, NULL, path);
1394 }
1395
1396 static void free_path2(struct fuse *f, fuse_ino_t nodeid1, fuse_ino_t nodeid2,
1397 struct node *wnode1, struct node *wnode2,
1398 char *path1, char *path2)
1399 {
1400 pthread_mutex_lock(&f->lock);
1401 unlock_path(f, nodeid1, wnode1, NULL);
1402 unlock_path(f, nodeid2, wnode2, NULL);
1403 wake_up_queued(f);
1404 pthread_mutex_unlock(&f->lock);
1405 free(path1);
1406 free(path2);
1407 }
1408
1409 static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
1410 {
1411 struct node *node;
1412 if (nodeid == FUSE_ROOT_ID)
1413 return;
1414 pthread_mutex_lock(&f->lock);
1415 node = get_node(f, nodeid);
1416
1417 /*
1418 * Node may still be locked due to interrupt idiocy in open,
1419 * create and opendir
1420 */
1421 while (node->nlookup == nlookup && node->treelock) {
1422 struct lock_queue_element qe = {
1423 .nodeid1 = nodeid,
1424 };
1425
1426 debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false);
1427 queue_path(f, &qe);
1428
1429 do {
1430 pthread_cond_wait(&qe.cond, &f->lock);
1431 } while (node->nlookup == nlookup && node->treelock);
1432
1433 dequeue_path(f, &qe);
1434 debug_path(f, "DEQUEUE_PATH (forget)", nodeid, NULL, false);
1435 }
1436
1437 assert(node->nlookup >= nlookup);
1438 node->nlookup -= nlookup;
1439 if (!node->nlookup) {
1440 unref_node(f, node);
1441 } else if (lru_enabled(f) && node->nlookup == 1) {
1442 set_forget_time(f, node);
1443 }
1444 pthread_mutex_unlock(&f->lock);
1445 }
1446
1447 static void unlink_node(struct fuse *f, struct node *node)
1448 {
1449 if (f->conf.remember) {
1450 assert(node->nlookup > 1);
1451 node->nlookup--;
1452 }
1453 unhash_name(f, node);
1454 }
1455
1456 static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name)
1457 {
1458 struct node *node;
1459
1460 pthread_mutex_lock(&f->lock);
1461 node = lookup_node(f, dir, name);
1462 if (node != NULL)
1463 unlink_node(f, node);
1464 pthread_mutex_unlock(&f->lock);
1465 }
1466
1467 static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1468 fuse_ino_t newdir, const char *newname, int hide)
1469 {
1470 struct node *node;
1471 struct node *newnode;
1472 int err = 0;
1473
1474 pthread_mutex_lock(&f->lock);
1475 node = lookup_node(f, olddir, oldname);
1476 newnode = lookup_node(f, newdir, newname);
1477 if (node == NULL)
1478 goto out;
1479
1480 if (newnode != NULL) {
1481 if (hide) {
1482 fprintf(stderr, "fuse: hidden file got created during hiding\n");
1483 err = -EBUSY;
1484 goto out;
1485 }
1486 unlink_node(f, newnode);
1487 }
1488
1489 unhash_name(f, node);
1490 if (hash_name(f, node, newdir, newname) == -1) {
1491 err = -ENOMEM;
1492 goto out;
1493 }
1494
1495 if (hide)
1496 node->is_hidden = 1;
1497
1498 out:
1499 pthread_mutex_unlock(&f->lock);
1500 return err;
1501 }
1502
1503 static int exchange_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1504 fuse_ino_t newdir, const char *newname)
1505 {
1506 struct node *oldnode;
1507 struct node *newnode;
1508 int err;
1509
1510 pthread_mutex_lock(&f->lock);
1511 oldnode = lookup_node(f, olddir, oldname);
1512 newnode = lookup_node(f, newdir, newname);
1513
1514 if (oldnode)
1515 unhash_name(f, oldnode);
1516 if (newnode)
1517 unhash_name(f, newnode);
1518
1519 err = -ENOMEM;
1520 if (oldnode) {
1521 if (hash_name(f, oldnode, newdir, newname) == -1)
1522 goto out;
1523 }
1524 if (newnode) {
1525 if (hash_name(f, newnode, olddir, oldname) == -1)
1526 goto out;
1527 }
1528 err = 0;
1529 out:
1530 pthread_mutex_unlock(&f->lock);
1531 return err;
1532 }
1533
1534 static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
1535 {
1536 if (!f->conf.use_ino)
1537 stbuf->st_ino = nodeid;
1538 if (f->conf.set_mode)
1539 stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1540 (0777 & ~f->conf.umask);
1541 if (f->conf.set_uid)
1542 stbuf->st_uid = f->conf.uid;
1543 if (f->conf.set_gid)
1544 stbuf->st_gid = f->conf.gid;
1545 }
1546
1547 static struct fuse *req_fuse(fuse_req_t req)
1548 {
1549 return (struct fuse *) fuse_req_userdata(req);
1550 }
1551
1552 static void fuse_intr_sighandler(int sig)
1553 {
1554 (void) sig;
1555 /* Nothing to do */
1556 }
1557
1558 struct fuse_intr_data {
1559 pthread_t id;
1560 pthread_cond_t cond;
1561 int finished;
1562 };
1563
1564 static void fuse_interrupt(fuse_req_t req, void *d_)
1565 {
1566 struct fuse_intr_data *d = d_;
1567 struct fuse *f = req_fuse(req);
1568
1569 if (d->id == pthread_self())
1570 return;
1571
1572 pthread_mutex_lock(&f->lock);
1573 while (!d->finished) {
1574 struct timeval now;
1575 struct timespec timeout;
1576
1577 pthread_kill(d->id, f->conf.intr_signal);
1578 gettimeofday(&now, NULL);
1579 timeout.tv_sec = now.tv_sec + 1;
1580 timeout.tv_nsec = now.tv_usec * 1000;
1581 pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1582 }
1583 pthread_mutex_unlock(&f->lock);
1584 }
1585
1586 static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
1587 struct fuse_intr_data *d)
1588 {
1589 pthread_mutex_lock(&f->lock);
1590 d->finished = 1;
1591 pthread_cond_broadcast(&d->cond);
1592 pthread_mutex_unlock(&f->lock);
1593 fuse_req_interrupt_func(req, NULL, NULL);
1594 pthread_cond_destroy(&d->cond);
1595 }
1596
1597 static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
1598 {
1599 d->id = pthread_self();
1600 pthread_cond_init(&d->cond, NULL);
1601 d->finished = 0;
1602 fuse_req_interrupt_func(req, fuse_interrupt, d);
1603 }
1604
1605 static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
1606 struct fuse_intr_data *d)
1607 {
1608 if (f->conf.intr)
1609 fuse_do_finish_interrupt(f, req, d);
1610 }
1611
1612 static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
1613 struct fuse_intr_data *d)
1614 {
1615 if (f->conf.intr)
1616 fuse_do_prepare_interrupt(req, d);
1617 }
1618
1619 static const char* file_info_string(struct fuse_file_info *fi,
1620 char* buf, size_t len)
1621 {
1622 if(fi == NULL)
1623 return "NULL";
1624 snprintf(buf, len, "%llu", (unsigned long long) fi->fh);
1625 return buf;
1626 }
1627
1628 int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
1629 struct fuse_file_info *fi)
1630 {
1631 fuse_get_context()->private_data = fs->user_data;
1632 if (fs->op.getattr) {
1633 if (fs->debug) {
1634 char buf[10];
1635 fprintf(stderr, "getattr[%s] %s\n",
1636 file_info_string(fi, buf, sizeof(buf)),
1637 path);
1638 }
1639 return fs->op.getattr(path, buf, fi);
1640 } else {
1641 return -ENOSYS;
1642 }
1643 }
1644
1645 int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
1646 const char *newpath, unsigned int flags)
1647 {
1648 fuse_get_context()->private_data = fs->user_data;
1649 if (fs->op.rename) {
1650 if (fs->debug)
1651 fprintf(stderr, "rename %s %s 0x%x\n", oldpath, newpath,
1652 flags);
1653
1654 return fs->op.rename(oldpath, newpath, flags);
1655 } else {
1656 return -ENOSYS;
1657 }
1658 }
1659
1660 int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
1661 {
1662 fuse_get_context()->private_data = fs->user_data;
1663 if (fs->op.unlink) {
1664 if (fs->debug)
1665 fprintf(stderr, "unlink %s\n", path);
1666
1667 return fs->op.unlink(path);
1668 } else {
1669 return -ENOSYS;
1670 }
1671 }
1672
1673 int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
1674 {
1675 fuse_get_context()->private_data = fs->user_data;
1676 if (fs->op.rmdir) {
1677 if (fs->debug)
1678 fprintf(stderr, "rmdir %s\n", path);
1679
1680 return fs->op.rmdir(path);
1681 } else {
1682 return -ENOSYS;
1683 }
1684 }
1685
1686 int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
1687 {
1688 fuse_get_context()->private_data = fs->user_data;
1689 if (fs->op.symlink) {
1690 if (fs->debug)
1691 fprintf(stderr, "symlink %s %s\n", linkname, path);
1692
1693 return fs->op.symlink(linkname, path);
1694 } else {
1695 return -ENOSYS;
1696 }
1697 }
1698
1699 int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
1700 {
1701 fuse_get_context()->private_data = fs->user_data;
1702 if (fs->op.link) {
1703 if (fs->debug)
1704 fprintf(stderr, "link %s %s\n", oldpath, newpath);
1705
1706 return fs->op.link(oldpath, newpath);
1707 } else {
1708 return -ENOSYS;
1709 }
1710 }
1711
1712 int fuse_fs_release(struct fuse_fs *fs, const char *path,
1713 struct fuse_file_info *fi)
1714 {
1715 fuse_get_context()->private_data = fs->user_data;
1716 if (fs->op.release) {
1717 if (fs->debug)
1718 fprintf(stderr, "release%s[%llu] flags: 0x%x\n",
1719 fi->flush ? "+flush" : "",
1720 (unsigned long long) fi->fh, fi->flags);
1721
1722 return fs->op.release(path, fi);
1723 } else {
1724 return 0;
1725 }
1726 }
1727
1728 int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
1729 struct fuse_file_info *fi)
1730 {
1731 fuse_get_context()->private_data = fs->user_data;
1732 if (fs->op.opendir) {
1733 int err;
1734
1735 if (fs->debug)
1736 fprintf(stderr, "opendir flags: 0x%x %s\n", fi->flags,
1737 path);
1738
1739 err = fs->op.opendir(path, fi);
1740
1741 if (fs->debug && !err)
1742 fprintf(stderr, " opendir[%llu] flags: 0x%x %s\n",
1743 (unsigned long long) fi->fh, fi->flags, path);
1744
1745 return err;
1746 } else {
1747 return 0;
1748 }
1749 }
1750
1751 int fuse_fs_open(struct fuse_fs *fs, const char *path,
1752 struct fuse_file_info *fi)
1753 {
1754 fuse_get_context()->private_data = fs->user_data;
1755 if (fs->op.open) {
1756 int err;
1757
1758 if (fs->debug)
1759 fprintf(stderr, "open flags: 0x%x %s\n", fi->flags,
1760 path);
1761
1762 err = fs->op.open(path, fi);
1763
1764 if (fs->debug && !err)
1765 fprintf(stderr, " open[%llu] flags: 0x%x %s\n",
1766 (unsigned long long) fi->fh, fi->flags, path);
1767
1768 return err;
1769 } else {
1770 return 0;
1771 }
1772 }
1773
1774 static void fuse_free_buf(struct fuse_bufvec *buf)
1775 {
1776 if (buf != NULL) {
1777 size_t i;
1778
1779 for (i = 0; i < buf->count; i++)
1780 if (!(buf->buf[0].flags & FUSE_BUF_IS_FD))
1781 free(buf->buf[i].mem);
1782 free(buf);
1783 }
1784 }
1785
1786 int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
1787 struct fuse_bufvec **bufp, size_t size, off_t off,
1788 struct fuse_file_info *fi)
1789 {
1790 fuse_get_context()->private_data = fs->user_data;
1791 if (fs->op.read || fs->op.read_buf) {
1792 int res;
1793
1794 if (fs->debug)
1795 fprintf(stderr,
1796 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1797 (unsigned long long) fi->fh,
1798 size, (unsigned long long) off, fi->flags);
1799
1800 if (fs->op.read_buf) {
1801 res = fs->op.read_buf(path, bufp, size, off, fi);
1802 } else {
1803 struct fuse_bufvec *buf;
1804 void *mem;
1805
1806 buf = malloc(sizeof(struct fuse_bufvec));
1807 if (buf == NULL)
1808 return -ENOMEM;
1809
1810 mem = malloc(size);
1811 if (mem == NULL) {
1812 free(buf);
1813 return -ENOMEM;
1814 }
1815 *buf = FUSE_BUFVEC_INIT(size);
1816 buf->buf[0].mem = mem;
1817 *bufp = buf;
1818
1819 res = fs->op.read(path, mem, size, off, fi);
1820 if (res >= 0)
1821 buf->buf[0].size = res;
1822 }
1823
1824 if (fs->debug && res >= 0)
1825 fprintf(stderr, " read[%llu] %zu bytes from %llu\n",
1826 (unsigned long long) fi->fh,
1827 fuse_buf_size(*bufp),
1828 (unsigned long long) off);
1829 if (res >= 0 && fuse_buf_size(*bufp) > size)
1830 fprintf(stderr, "fuse: read too many bytes\n");
1831
1832 if (res < 0)
1833 return res;
1834
1835 return 0;
1836 } else {
1837 return -ENOSYS;
1838 }
1839 }
1840
1841 int fuse_fs_read(struct fuse_fs *fs, const char *path, char *mem, size_t size,
1842 off_t off, struct fuse_file_info *fi)
1843 {
1844 fuse_get_context()->private_data = fs->user_data;
1845 if (fs->op.read || fs->op.read_buf) {
1846 int res;
1847
1848 if (fs->debug)
1849 fprintf(stderr,
1850 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1851 (unsigned long long) fi->fh,
1852 size, (unsigned long long) off, fi->flags);
1853
1854 if (fs->op.read_buf) {
1855 struct fuse_bufvec *buf = NULL;
1856
1857 res = fs->op.read_buf(path, &buf, size, off, fi);
1858 if (res == 0) {
1859 struct fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
1860
1861 dst.buf[0].mem = mem;
1862 res = fuse_buf_copy(&dst, buf, 0);
1863 }
1864 fuse_free_buf(buf);
1865 } else {
1866 res = fs->op.read(path, mem, size, off, fi);
1867 }
1868
1869 if (fs->debug && res >= 0)
1870 fprintf(stderr, " read[%llu] %u bytes from %llu\n",
1871 (unsigned long long) fi->fh,
1872 res,
1873 (unsigned long long) off);
1874 if (res >= 0 && res > (int) size)
1875 fprintf(stderr, "fuse: read too many bytes\n");
1876
1877 return res;
1878 } else {
1879 return -ENOSYS;
1880 }
1881 }
1882
1883 int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
1884 struct fuse_bufvec *buf, off_t off,
1885 struct fuse_file_info *fi)
1886 {
1887 fuse_get_context()->private_data = fs->user_data;
1888 if (fs->op.write_buf || fs->op.write) {
1889 int res;
1890 size_t size = fuse_buf_size(buf);
1891
1892 assert(buf->idx == 0 && buf->off == 0);
1893 if (fs->debug)
1894 fprintf(stderr,
1895 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1896 fi->writepage ? "page" : "",
1897 (unsigned long long) fi->fh,
1898 size,
1899 (unsigned long long) off,
1900 fi->flags);
1901
1902 if (fs->op.write_buf) {
1903 res = fs->op.write_buf(path, buf, off, fi);
1904 } else {
1905 void *mem = NULL;
1906 struct fuse_buf *flatbuf;
1907 struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
1908
1909 if (buf->count == 1 &&
1910 !(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
1911 flatbuf = &buf->buf[0];
1912 } else {
1913 res = -ENOMEM;
1914 mem = malloc(size);
1915 if (mem == NULL)
1916 goto out;
1917
1918 tmp.buf[0].mem = mem;
1919 res = fuse_buf_copy(&tmp, buf, 0);
1920 if (res <= 0)
1921 goto out_free;
1922
1923 tmp.buf[0].size = res;
1924 flatbuf = &tmp.buf[0];
1925 }
1926
1927 res = fs->op.write(path, flatbuf->mem, flatbuf->size,
1928 off, fi);
1929 out_free:
1930 free(mem);
1931 }
1932 out:
1933 if (fs->debug && res >= 0)
1934 fprintf(stderr, " write%s[%llu] %u bytes to %llu\n",
1935 fi->writepage ? "page" : "",
1936 (unsigned long long) fi->fh, res,
1937 (unsigned long long) off);
1938 if (res > (int) size)
1939 fprintf(stderr, "fuse: wrote too many bytes\n");
1940
1941 return res;
1942 } else {
1943 return -ENOSYS;
1944 }
1945 }
1946
1947 int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *mem,
1948 size_t size, off_t off, struct fuse_file_info *fi)
1949 {
1950 struct fuse_bufvec bufv = FUSE_BUFVEC_INIT(size);
1951
1952 bufv.buf[0].mem = (void *) mem;
1953
1954 return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1955 }
1956
1957 int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
1958 struct fuse_file_info *fi)
1959 {
1960 fuse_get_context()->private_data = fs->user_data;
1961 if (fs->op.fsync) {
1962 if (fs->debug)
1963 fprintf(stderr, "fsync[%llu] datasync: %i\n",
1964 (unsigned long long) fi->fh, datasync);
1965
1966 return fs->op.fsync(path, datasync, fi);
1967 } else {
1968 return -ENOSYS;
1969 }
1970 }
1971
1972 int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
1973 struct fuse_file_info *fi)
1974 {
1975 fuse_get_context()->private_data = fs->user_data;
1976 if (fs->op.fsyncdir) {
1977 if (fs->debug)
1978 fprintf(stderr, "fsyncdir[%llu] datasync: %i\n",
1979 (unsigned long long) fi->fh, datasync);
1980
1981 return fs->op.fsyncdir(path, datasync, fi);
1982 } else {
1983 return -ENOSYS;
1984 }
1985 }
1986
1987 int fuse_fs_flush(struct fuse_fs *fs, const char *path,
1988 struct fuse_file_info *fi)
1989 {
1990 fuse_get_context()->private_data = fs->user_data;
1991 if (fs->op.flush) {
1992 if (fs->debug)
1993 fprintf(stderr, "flush[%llu]\n",
1994 (unsigned long long) fi->fh);
1995
1996 return fs->op.flush(path, fi);
1997 } else {
1998 return -ENOSYS;
1999 }
2000 }
2001
2002 int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
2003 {
2004 fuse_get_context()->private_data = fs->user_data;
2005 if (fs->op.statfs) {
2006 if (fs->debug)
2007 fprintf(stderr, "statfs %s\n", path);
2008
2009 return fs->op.statfs(path, buf);
2010 } else {
2011 buf->f_namemax = 255;
2012 buf->f_bsize = 512;
2013 return 0;
2014 }
2015 }
2016
2017 int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
2018 struct fuse_file_info *fi)
2019 {
2020 fuse_get_context()->private_data = fs->user_data;
2021 if (fs->op.releasedir) {
2022 if (fs->debug)
2023 fprintf(stderr, "releasedir[%llu] flags: 0x%x\n",
2024 (unsigned long long) fi->fh, fi->flags);
2025
2026 return fs->op.releasedir(path, fi);
2027 } else {
2028 return 0;
2029 }
2030 }
2031
2032 int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
2033 fuse_fill_dir_t filler, off_t off,
2034 struct fuse_file_info *fi,
2035 enum fuse_readdir_flags flags)
2036 {
2037 fuse_get_context()->private_data = fs->user_data;
2038 if (fs->op.readdir) {
2039 if (fs->debug) {
2040 fprintf(stderr, "readdir%s[%llu] from %llu\n",
2041 (flags & FUSE_READDIR_PLUS) ? "plus" : "",
2042 (unsigned long long) fi->fh,
2043 (unsigned long long) off);
2044 }
2045
2046 return fs->op.readdir(path, buf, filler, off, fi, flags);
2047 } else {
2048 return -ENOSYS;
2049 }
2050 }
2051
2052 int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
2053 struct fuse_file_info *fi)
2054 {
2055 fuse_get_context()->private_data = fs->user_data;
2056 if (fs->op.create) {
2057 int err;
2058
2059 if (fs->debug)
2060 fprintf(stderr,
2061 "create flags: 0x%x %s 0%o umask=0%03o\n",
2062 fi->flags, path, mode,
2063 fuse_get_context()->umask);
2064
2065 err = fs->op.create(path, mode, fi);
2066
2067 if (fs->debug && !err)
2068 fprintf(stderr, " create[%llu] flags: 0x%x %s\n",
2069 (unsigned long long) fi->fh, fi->flags, path);
2070
2071 return err;
2072 } else {
2073 return -ENOSYS;
2074 }
2075 }
2076
2077 int fuse_fs_lock(struct fuse_fs *fs, const char *path,
2078 struct fuse_file_info *fi, int cmd, struct flock *lock)
2079 {
2080 fuse_get_context()->private_data = fs->user_data;
2081 if (fs->op.lock) {
2082 if (fs->debug)
2083 fprintf(stderr, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2084 (unsigned long long) fi->fh,
2085 (cmd == F_GETLK ? "F_GETLK" :
2086 (cmd == F_SETLK ? "F_SETLK" :
2087 (cmd == F_SETLKW ? "F_SETLKW" : "???"))),
2088 (lock->l_type == F_RDLCK ? "F_RDLCK" :
2089 (lock->l_type == F_WRLCK ? "F_WRLCK" :
2090 (lock->l_type == F_UNLCK ? "F_UNLCK" :
2091 "???"))),
2092 (unsigned long long) lock->l_start,
2093 (unsigned long long) lock->l_len,
2094 (unsigned long long) lock->l_pid);
2095
2096 return fs->op.lock(path, fi, cmd, lock);
2097 } else {
2098 return -ENOSYS;
2099 }
2100 }
2101
2102 int fuse_fs_flock(struct fuse_fs *fs, const char *path,
2103 struct fuse_file_info *fi, int op)
2104 {
2105 fuse_get_context()->private_data = fs->user_data;
2106 if (fs->op.flock) {
2107 if (fs->debug) {
2108 int xop = op & ~LOCK_NB;
2109
2110 fprintf(stderr, "lock[%llu] %s%s\n",
2111 (unsigned long long) fi->fh,
2112 xop == LOCK_SH ? "LOCK_SH" :
2113 (xop == LOCK_EX ? "LOCK_EX" :
2114 (xop == LOCK_UN ? "LOCK_UN" : "???")),
2115 (op & LOCK_NB) ? "|LOCK_NB" : "");
2116 }
2117 return fs->op.flock(path, fi, op);
2118 } else {
2119 return -ENOSYS;
2120 }
2121 }
2122
2123 int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid,
2124 gid_t gid, struct fuse_file_info *fi)
2125 {
2126 fuse_get_context()->private_data = fs->user_data;
2127 if (fs->op.chown) {
2128 if (fs->debug) {
2129 char buf[10];
2130 fprintf(stderr, "chown[%s] %s %lu %lu\n",
2131 file_info_string(fi, buf, sizeof(buf)),
2132 path, (unsigned long) uid, (unsigned long) gid);
2133 }
2134 return fs->op.chown(path, uid, gid, fi);
2135 } else {
2136 return -ENOSYS;
2137 }
2138 }
2139
2140 int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
2141 struct fuse_file_info *fi)
2142 {
2143 fuse_get_context()->private_data = fs->user_data;
2144 if (fs->op.truncate) {
2145 if (fs->debug) {
2146 char buf[10];
2147 fprintf(stderr, "truncate[%s] %llu\n",
2148 file_info_string(fi, buf, sizeof(buf)),
2149 (unsigned long long) size);
2150 }
2151 return fs->op.truncate(path, size, fi);
2152 } else {
2153 return -ENOSYS;
2154 }
2155 }
2156
2157 int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
2158 const struct timespec tv[2], struct fuse_file_info *fi)
2159 {
2160 fuse_get_context()->private_data = fs->user_data;
2161 if (fs->op.utimens) {
2162 if (fs->debug) {
2163 char buf[10];
2164 fprintf(stderr, "utimens[%s] %s %li.%09lu %li.%09lu\n",
2165 file_info_string(fi, buf, sizeof(buf)),
2166 path, tv[0].tv_sec, tv[0].tv_nsec,
2167 tv[1].tv_sec, tv[1].tv_nsec);
2168 }
2169 return fs->op.utimens(path, tv, fi);
2170 } else {
2171 return -ENOSYS;
2172 }
2173 }
2174
2175 int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
2176 {
2177 fuse_get_context()->private_data = fs->user_data;
2178 if (fs->op.access) {
2179 if (fs->debug)
2180 fprintf(stderr, "access %s 0%o\n", path, mask);
2181
2182 return fs->op.access(path, mask);
2183 } else {
2184 return -ENOSYS;
2185 }
2186 }
2187
2188 int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
2189 size_t len)
2190 {
2191 fuse_get_context()->private_data = fs->user_data;
2192 if (fs->op.readlink) {
2193 if (fs->debug)
2194 fprintf(stderr, "readlink %s %lu\n", path,
2195 (unsigned long) len);
2196
2197 return fs->op.readlink(path, buf, len);
2198 } else {
2199 return -ENOSYS;
2200 }
2201 }
2202
2203 int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
2204 dev_t rdev)
2205 {
2206 fuse_get_context()->private_data = fs->user_data;
2207 if (fs->op.mknod) {
2208 if (fs->debug)
2209 fprintf(stderr, "mknod %s 0%o 0x%llx umask=0%03o\n",
2210 path, mode, (unsigned long long) rdev,
2211 fuse_get_context()->umask);
2212
2213 return fs->op.mknod(path, mode, rdev);
2214 } else {
2215 return -ENOSYS;
2216 }
2217 }
2218
2219 int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
2220 {
2221 fuse_get_context()->private_data = fs->user_data;
2222 if (fs->op.mkdir) {
2223 if (fs->debug)
2224 fprintf(stderr, "mkdir %s 0%o umask=0%03o\n",
2225 path, mode, fuse_get_context()->umask);
2226
2227 return fs->op.mkdir(path, mode);
2228 } else {
2229 return -ENOSYS;
2230 }
2231 }
2232
2233 int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
2234 const char *value, size_t size, int flags)
2235 {
2236 fuse_get_context()->private_data = fs->user_data;
2237 if (fs->op.setxattr) {
2238 if (fs->debug)
2239 fprintf(stderr, "setxattr %s %s %lu 0x%x\n",
2240 path, name, (unsigned long) size, flags);
2241
2242 return fs->op.setxattr(path, name, value, size, flags);
2243 } else {
2244 return -ENOSYS;
2245 }
2246 }
2247
2248 int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
2249 char *value, size_t size)
2250 {
2251 fuse_get_context()->private_data = fs->user_data;
2252 if (fs->op.getxattr) {
2253 if (fs->debug)
2254 fprintf(stderr, "getxattr %s %s %lu\n",
2255 path, name, (unsigned long) size);
2256
2257 return fs->op.getxattr(path, name, value, size);
2258 } else {
2259 return -ENOSYS;
2260 }
2261 }
2262
2263 int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
2264 size_t size)
2265 {
2266 fuse_get_context()->private_data = fs->user_data;
2267 if (fs->op.listxattr) {
2268 if (fs->debug)
2269 fprintf(stderr, "listxattr %s %lu\n",
2270 path, (unsigned long) size);
2271
2272 return fs->op.listxattr(path, list, size);
2273 } else {
2274 return -ENOSYS;
2275 }
2276 }
2277
2278 int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
2279 uint64_t *idx)
2280 {
2281 fuse_get_context()->private_data = fs->user_data;
2282 if (fs->op.bmap) {
2283 if (fs->debug)
2284 fprintf(stderr, "bmap %s blocksize: %lu index: %llu\n",
2285 path, (unsigned long) blocksize,
2286 (unsigned long long) *idx);
2287
2288 return fs->op.bmap(path, blocksize, idx);
2289 } else {
2290 return -ENOSYS;
2291 }
2292 }
2293
2294 int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
2295 {
2296 fuse_get_context()->private_data = fs->user_data;
2297 if (fs->op.removexattr) {
2298 if (fs->debug)
2299 fprintf(stderr, "removexattr %s %s\n", path, name);
2300
2301 return fs->op.removexattr(path, name);
2302 } else {
2303 return -ENOSYS;
2304 }
2305 }
2306
2307 int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
2308 struct fuse_file_info *fi, unsigned int flags, void *data)
2309 {
2310 fuse_get_context()->private_data = fs->user_data;
2311 if (fs->op.ioctl) {
2312 if (fs->debug)
2313 fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n",
2314 (unsigned long long) fi->fh, cmd, flags);
2315
2316 return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2317 } else
2318 return -ENOSYS;
2319 }
2320
2321 int fuse_fs_poll(struct fuse_fs *fs, const char *path,
2322 struct fuse_file_info *fi, struct fuse_pollhandle *ph,
2323 unsigned *reventsp)
2324 {
2325 fuse_get_context()->private_data = fs->user_data;
2326 if (fs->op.poll) {
2327 int res;
2328
2329 if (fs->debug)
2330 fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n",
2331 (unsigned long long) fi->fh, ph,
2332 fi->poll_events);
2333
2334 res = fs->op.poll(path, fi, ph, reventsp);
2335
2336 if (fs->debug && !res)
2337 fprintf(stderr, " poll[%llu] revents: 0x%x\n",
2338 (unsigned long long) fi->fh, *reventsp);
2339
2340 return res;
2341 } else
2342 return -ENOSYS;
2343 }
2344
2345 int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
2346 off_t offset, off_t length, struct fuse_file_info *fi)
2347 {
2348 fuse_get_context()->private_data = fs->user_data;
2349 if (fs->op.fallocate) {
2350 if (fs->debug)
2351 fprintf(stderr, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2352 path,
2353 mode,
2354 (unsigned long long) offset,
2355 (unsigned long long) length);
2356
2357 return fs->op.fallocate(path, mode, offset, length, fi);
2358 } else
2359 return -ENOSYS;
2360 }
2361
2362 static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
2363 {
2364 struct node *node;
2365 int isopen = 0;
2366 pthread_mutex_lock(&f->lock);
2367 node = lookup_node(f, dir, name);
2368 if (node && node->open_count > 0)
2369 isopen = 1;
2370 pthread_mutex_unlock(&f->lock);
2371 return isopen;
2372 }
2373
2374 static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
2375 char *newname, size_t bufsize)
2376 {
2377 struct stat buf;
2378 struct node *node;
2379 struct node *newnode;
2380 char *newpath;
2381 int res;
2382 int failctr = 10;
2383
2384 do {
2385 pthread_mutex_lock(&f->lock);
2386 node = lookup_node(f, dir, oldname);
2387 if (node == NULL) {
2388 pthread_mutex_unlock(&f->lock);
2389 return NULL;
2390 }
2391 do {
2392 f->hidectr ++;
2393 snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
2394 (unsigned int) node->nodeid, f->hidectr);
2395 newnode = lookup_node(f, dir, newname);
2396 } while(newnode);
2397
2398 res = try_get_path(f, dir, newname, &newpath, NULL, false);
2399 pthread_mutex_unlock(&f->lock);
2400 if (res)
2401 break;
2402
2403 memset(&buf, 0, sizeof(buf));
2404 res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
2405 if (res == -ENOENT)
2406 break;
2407 free(newpath);
2408 newpath = NULL;
2409 } while(res == 0 && --failctr);
2410
2411 return newpath;
2412 }
2413
2414 static int hide_node(struct fuse *f, const char *oldpath,
2415 fuse_ino_t dir, const char *oldname)
2416 {
2417 char newname[64];
2418 char *newpath;
2419 int err = -EBUSY;
2420
2421 newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
2422 if (newpath) {
2423 err = fuse_fs_rename(f->fs, oldpath, newpath, 0);
2424 if (!err)
2425 err = rename_node(f, dir, oldname, dir, newname, 1);
2426 free(newpath);
2427 }
2428 return err;
2429 }
2430
2431 static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
2432 {
2433 return stbuf->st_mtime == ts->tv_sec &&
2434 ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2435 }
2436
2437 #ifndef CLOCK_MONOTONIC
2438 #define CLOCK_MONOTONIC CLOCK_REALTIME
2439 #endif
2440
2441 static void curr_time(struct timespec *now)
2442 {
2443 static clockid_t clockid = CLOCK_MONOTONIC;
2444 int res = clock_gettime(clockid, now);
2445 if (res == -1 && errno == EINVAL) {
2446 clockid = CLOCK_REALTIME;
2447 res = clock_gettime(clockid, now);
2448 }
2449 if (res == -1) {
2450 perror("fuse: clock_gettime");
2451 abort();
2452 }
2453 }
2454
2455 static void update_stat(struct node *node, const struct stat *stbuf)
2456 {
2457 if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2458 stbuf->st_size != node->size))
2459 node->cache_valid = 0;
2460 node->mtime.tv_sec = stbuf->st_mtime;
2461 node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2462 node->size = stbuf->st_size;
2463 curr_time(&node->stat_updated);
2464 }
2465
2466 static int do_lookup(struct fuse *f, fuse_ino_t nodeid, const char *name,
2467 struct fuse_entry_param *e)
2468 {
2469 struct node *node;
2470
2471 node = find_node(f, nodeid, name);
2472 if (node == NULL)
2473 return -ENOMEM;
2474
2475 e->ino = node->nodeid;
2476 e->generation = node->generation;
2477 e->entry_timeout = f->conf.entry_timeout;
2478 e->attr_timeout = f->conf.attr_timeout;
2479 if (f->conf.auto_cache) {
2480 pthread_mutex_lock(&f->lock);
2481 update_stat(node, &e->attr);
2482 pthread_mutex_unlock(&f->lock);
2483 }
2484 set_stat(f, e->ino, &e->attr);
2485 return 0;
2486 }
2487
2488 static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
2489 const char *name, const char *path,
2490 struct fuse_entry_param *e, struct fuse_file_info *fi)
2491 {
2492 int res;
2493
2494 memset(e, 0, sizeof(struct fuse_entry_param));
2495 res = fuse_fs_getattr(f->fs, path, &e->attr, fi);
2496 if (res == 0) {
2497 res = do_lookup(f, nodeid, name, e);
2498 if (res == 0 && f->conf.debug) {
2499 fprintf(stderr, " NODEID: %llu\n",
2500 (unsigned long long) e->ino);
2501 }
2502 }
2503 return res;
2504 }
2505
2506 static struct fuse_context_i *fuse_get_context_internal(void)
2507 {
2508 return (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2509 }
2510
2511 static struct fuse_context_i *fuse_create_context(struct fuse *f)
2512 {
2513 struct fuse_context_i *c = fuse_get_context_internal();
2514 if (c == NULL) {
2515 c = (struct fuse_context_i *)
2516 calloc(1, sizeof(struct fuse_context_i));
2517 if (c == NULL) {
2518 /* This is hard to deal with properly, so just
2519 abort. If memory is so low that the
2520 context cannot be allocated, there's not
2521 much hope for the filesystem anyway */
2522 fprintf(stderr, "fuse: failed to allocate thread specific data\n");
2523 abort();
2524 }
2525 pthread_setspecific(fuse_context_key, c);
2526 } else {
2527 memset(c, 0, sizeof(*c));
2528 }
2529 c->ctx.fuse = f;
2530
2531 return c;
2532 }
2533
2534 static void fuse_freecontext(void *data)
2535 {
2536 free(data);
2537 }
2538
2539 static int fuse_create_context_key(void)
2540 {
2541 int err = 0;
2542 pthread_mutex_lock(&fuse_context_lock);
2543 if (!fuse_context_ref) {
2544 err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2545 if (err) {
2546 fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
2547 strerror(err));
2548 pthread_mutex_unlock(&fuse_context_lock);
2549 return -1;
2550 }
2551 }
2552 fuse_context_ref++;
2553 pthread_mutex_unlock(&fuse_context_lock);
2554 return 0;
2555 }
2556
2557 static void fuse_delete_context_key(void)
2558 {
2559 pthread_mutex_lock(&fuse_context_lock);
2560 fuse_context_ref--;
2561 if (!fuse_context_ref) {
2562 free(pthread_getspecific(fuse_context_key));
2563 pthread_key_delete(fuse_context_key);
2564 }
2565 pthread_mutex_unlock(&fuse_context_lock);
2566 }
2567
2568 static struct fuse *req_fuse_prepare(fuse_req_t req)
2569 {
2570 struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2571 const struct fuse_ctx *ctx = fuse_req_ctx(req);
2572 c->req = req;
2573 c->ctx.uid = ctx->uid;
2574 c->ctx.gid = ctx->gid;
2575 c->ctx.pid = ctx->pid;
2576 c->ctx.umask = ctx->umask;
2577 return c->ctx.fuse;
2578 }
2579
2580 static inline void reply_err(fuse_req_t req, int err)
2581 {
2582 /* fuse_reply_err() uses non-negated errno values */
2583 fuse_reply_err(req, -err);
2584 }
2585
2586 static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
2587 int err)
2588 {
2589 if (!err) {
2590 struct fuse *f = req_fuse(req);
2591 if (fuse_reply_entry(req, e) == -ENOENT) {
2592 /* Skip forget for negative result */
2593 if (e->ino != 0)
2594 forget_node(f, e->ino, 1);
2595 }
2596 } else
2597 reply_err(req, err);
2598 }
2599
2600 void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn,
2601 struct fuse_config *cfg)
2602 {
2603 fuse_get_context()->private_data = fs->user_data;
2604 if (!fs->op.write_buf)
2605 conn->want &= ~FUSE_CAP_SPLICE_READ;
2606 if (!fs->op.lock)
2607 conn->want &= ~FUSE_CAP_POSIX_LOCKS;
2608 if (!fs->op.flock)
2609 conn->want &= ~FUSE_CAP_FLOCK_LOCKS;
2610 if (fs->op.init)
2611 fs->user_data = fs->op.init(conn, cfg);
2612 }
2613
2614 static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
2615 {
2616 struct fuse *f = (struct fuse *) data;
2617
2618 fuse_create_context(f);
2619 if(conn->capable & FUSE_CAP_EXPORT_SUPPORT)
2620 conn->want |= FUSE_CAP_EXPORT_SUPPORT;
2621 fuse_fs_init(f->fs, conn, &f->conf);
2622 }
2623
2624 void fuse_fs_destroy(struct fuse_fs *fs)
2625 {
2626 fuse_get_context()->private_data = fs->user_data;
2627 if (fs->op.destroy)
2628 fs->op.destroy(fs->user_data);
2629 if (fs->m)
2630 fuse_put_module(fs->m);
2631 free(fs);
2632 }
2633
2634 static void fuse_lib_destroy(void *data)
2635 {
2636 struct fuse *f = (struct fuse *) data;
2637
2638 fuse_create_context(f);
2639 fuse_fs_destroy(f->fs);
2640 f->fs = NULL;
2641 }
2642
2643 static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
2644 const char *name)
2645 {
2646 struct fuse *f = req_fuse_prepare(req);
2647 struct fuse_entry_param e;
2648 char *path;
2649 int err;
2650 struct node *dot = NULL;
2651
2652 if (name[0] == '.') {
2653 int len = strlen(name);
2654
2655 if (len == 1 || (name[1] == '.' && len == 2)) {
2656 pthread_mutex_lock(&f->lock);
2657 if (len == 1) {
2658 if (f->conf.debug)
2659 fprintf(stderr, "LOOKUP-DOT\n");
2660 dot = get_node_nocheck(f, parent);
2661 if (dot == NULL) {
2662 pthread_mutex_unlock(&f->lock);
2663 reply_entry(req, &e, -ESTALE);
2664 return;
2665 }
2666 dot->refctr++;
2667 } else {
2668 if (f->conf.debug)
2669 fprintf(stderr, "LOOKUP-DOTDOT\n");
2670 parent = get_node(f, parent)->parent->nodeid;
2671 }
2672 pthread_mutex_unlock(&f->lock);
2673 name = NULL;
2674 }
2675 }
2676
2677 err = get_path_name(f, parent, name, &path);
2678 if (!err) {
2679 struct fuse_intr_data d;
2680 if (f->conf.debug)
2681 fprintf(stderr, "LOOKUP %s\n", path);
2682 fuse_prepare_interrupt(f, req, &d);
2683 err = lookup_path(f, parent, name, path, &e, NULL);
2684 if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2685 e.ino = 0;
2686 e.entry_timeout = f->conf.negative_timeout;
2687 err = 0;
2688 }
2689 fuse_finish_interrupt(f, req, &d);
2690 free_path(f, parent, path);
2691 }
2692 if (dot) {
2693 pthread_mutex_lock(&f->lock);
2694 unref_node(f, dot);
2695 pthread_mutex_unlock(&f->lock);
2696 }
2697 reply_entry(req, &e, err);
2698 }
2699
2700 static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup)
2701 {
2702 if (f->conf.debug)
2703 fprintf(stderr, "FORGET %llu/%llu\n", (unsigned long long)ino,
2704 (unsigned long long) nlookup);
2705 forget_node(f, ino, nlookup);
2706 }
2707
2708 static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino, uint64_t nlookup)
2709 {
2710 do_forget(req_fuse(req), ino, nlookup);
2711 fuse_reply_none(req);
2712 }
2713
2714 static void fuse_lib_forget_multi(fuse_req_t req, size_t count,
2715 struct fuse_forget_data *forgets)
2716 {
2717 struct fuse *f = req_fuse(req);
2718 size_t i;
2719
2720 for (i = 0; i < count; i++)
2721 do_forget(f, forgets[i].ino, forgets[i].nlookup);
2722
2723 fuse_reply_none(req);
2724 }
2725
2726
2727 static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
2728 struct fuse_file_info *fi)
2729 {
2730 struct fuse *f = req_fuse_prepare(req);
2731 struct stat buf;
2732 char *path;
2733 int err;
2734
2735 memset(&buf, 0, sizeof(buf));
2736
2737 if (fi != NULL)
2738 err = get_path_nullok(f, ino, &path);
2739 else
2740 err = get_path(f, ino, &path);
2741 if (!err) {
2742 struct fuse_intr_data d;
2743 fuse_prepare_interrupt(f, req, &d);
2744 err = fuse_fs_getattr(f->fs, path, &buf, fi);
2745 fuse_finish_interrupt(f, req, &d);
2746 free_path(f, ino, path);
2747 }
2748 if (!err) {
2749 struct node *node;
2750
2751 pthread_mutex_lock(&f->lock);
2752 node = get_node(f, ino);
2753 if (node->is_hidden && buf.st_nlink > 0)
2754 buf.st_nlink--;
2755 if (f->conf.auto_cache)
2756 update_stat(node, &buf);
2757 pthread_mutex_unlock(&f->lock);
2758 set_stat(f, ino, &buf);
2759 fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2760 } else
2761 reply_err(req, err);
2762 }
2763
2764 int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
2765 struct fuse_file_info *fi)
2766 {
2767 fuse_get_context()->private_data = fs->user_data;
2768 if (fs->op.chmod) {
2769 if (fs->debug) {
2770 char buf[10];
2771 fprintf(stderr, "chmod[%s] %s %llo\n",
2772 file_info_string(fi, buf, sizeof(buf)),
2773 path, (unsigned long long) mode);
2774 }
2775 return fs->op.chmod(path, mode, fi);
2776 }
2777 else
2778 return -ENOSYS;
2779 }
2780
2781 static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
2782 int valid, struct fuse_file_info *fi)
2783 {
2784 struct fuse *f = req_fuse_prepare(req);
2785 struct stat buf;
2786 char *path;
2787 int err;
2788
2789 memset(&buf, 0, sizeof(buf));
2790 if (fi != NULL)
2791 err = get_path_nullok(f, ino, &path);
2792 else
2793 err = get_path(f, ino, &path);
2794 if (!err) {
2795 struct fuse_intr_data d;
2796 fuse_prepare_interrupt(f, req, &d);
2797 err = 0;
2798 if (!err && (valid & FUSE_SET_ATTR_MODE))
2799 err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
2800 if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2801 uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2802 attr->st_uid : (uid_t) -1;
2803 gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2804 attr->st_gid : (gid_t) -1;
2805 err = fuse_fs_chown(f->fs, path, uid, gid, fi);
2806 }
2807 if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2808 err = fuse_fs_truncate(f->fs, path,
2809 attr->st_size, fi);
2810 }
2811 #ifdef HAVE_UTIMENSAT
2812 if (!err &&
2813 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2814 struct timespec tv[2];
2815
2816 tv[0].tv_sec = 0;
2817 tv[1].tv_sec = 0;
2818 tv[0].tv_nsec = UTIME_OMIT;
2819 tv[1].tv_nsec = UTIME_OMIT;
2820
2821 if (valid & FUSE_SET_ATTR_ATIME_NOW)
2822 tv[0].tv_nsec = UTIME_NOW;
2823 else if (valid & FUSE_SET_ATTR_ATIME)
2824 tv[0] = attr->st_atim;
2825
2826 if (valid & FUSE_SET_ATTR_MTIME_NOW)
2827 tv[1].tv_nsec = UTIME_NOW;
2828 else if (valid & FUSE_SET_ATTR_MTIME)
2829 tv[1] = attr->st_mtim;
2830
2831 err = fuse_fs_utimens(f->fs, path, tv, fi);
2832 } else
2833 #endif
2834 if (!err &&
2835 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2836 (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2837 struct timespec tv[2];
2838 tv[0].tv_sec = attr->st_atime;
2839 tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2840 tv[1].tv_sec = attr->st_mtime;
2841 tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2842 err = fuse_fs_utimens(f->fs, path, tv, fi);
2843 }
2844 if (!err) {
2845 err = fuse_fs_getattr(f->fs, path, &buf, fi);
2846 }
2847 fuse_finish_interrupt(f, req, &d);
2848 free_path(f, ino, path);
2849 }
2850 if (!err) {
2851 if (f->conf.auto_cache) {
2852 pthread_mutex_lock(&f->lock);
2853 update_stat(get_node(f, ino), &buf);
2854 pthread_mutex_unlock(&f->lock);
2855 }
2856 set_stat(f, ino, &buf);
2857 fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2858 } else
2859 reply_err(req, err);
2860 }
2861
2862 static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
2863 {
2864 struct fuse *f = req_fuse_prepare(req);
2865 char *path;
2866 int err;
2867
2868 err = get_path(f, ino, &path);
2869 if (!err) {
2870 struct fuse_intr_data d;
2871
2872 fuse_prepare_interrupt(f, req, &d);
2873 err = fuse_fs_access(f->fs, path, mask);
2874 fuse_finish_interrupt(f, req, &d);
2875 free_path(f, ino, path);
2876 }
2877 reply_err(req, err);
2878 }
2879
2880 static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
2881 {
2882 struct fuse *f = req_fuse_prepare(req);
2883 char linkname[PATH_MAX + 1];
2884 char *path;
2885 int err;
2886
2887 err = get_path(f, ino, &path);
2888 if (!err) {
2889 struct fuse_intr_data d;
2890 fuse_prepare_interrupt(f, req, &d);
2891 err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
2892 fuse_finish_interrupt(f, req, &d);
2893 free_path(f, ino, path);
2894 }
2895 if (!err) {
2896 linkname[PATH_MAX] = '\0';
2897 fuse_reply_readlink(req, linkname);
2898 } else
2899 reply_err(req, err);
2900 }
2901
2902 static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
2903 mode_t mode, dev_t rdev)
2904 {
2905 struct fuse *f = req_fuse_prepare(req);
2906 struct fuse_entry_param e;
2907 char *path;
2908 int err;
2909
2910 err = get_path_name(f, parent, name, &path);
2911 if (!err) {
2912 struct fuse_intr_data d;
2913
2914 fuse_prepare_interrupt(f, req, &d);
2915 err = -ENOSYS;
2916 if (S_ISREG(mode)) {
2917 struct fuse_file_info fi;
2918
2919 memset(&fi, 0, sizeof(fi));
2920 fi.flags = O_CREAT | O_EXCL | O_WRONLY;
2921 err = fuse_fs_create(f->fs, path, mode, &fi);
2922 if (!err) {
2923 err = lookup_path(f, parent, name, path, &e,
2924 &fi);
2925 fuse_fs_release(f->fs, path, &fi);
2926 }
2927 }
2928 if (err == -ENOSYS) {
2929 err = fuse_fs_mknod(f->fs, path, mode, rdev);
2930 if (!err)
2931 err = lookup_path(f, parent, name, path, &e,
2932 NULL);
2933 }
2934 fuse_finish_interrupt(f, req, &d);
2935 free_path(f, parent, path);
2936 }
2937 reply_entry(req, &e, err);
2938 }
2939
2940 static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
2941 mode_t mode)
2942 {
2943 struct fuse *f = req_fuse_prepare(req);
2944 struct fuse_entry_param e;
2945 char *path;
2946 int err;
2947
2948 err = get_path_name(f, parent, name, &path);
2949 if (!err) {
2950 struct fuse_intr_data d;
2951
2952 fuse_prepare_interrupt(f, req, &d);
2953 err = fuse_fs_mkdir(f->fs, path, mode);
2954 if (!err)
2955 err = lookup_path(f, parent, name, path, &e, NULL);
2956 fuse_finish_interrupt(f, req, &d);
2957 free_path(f, parent, path);
2958 }
2959 reply_entry(req, &e, err);
2960 }
2961
2962 static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
2963 const char *name)
2964 {
2965 struct fuse *f = req_fuse_prepare(req);
2966 struct node *wnode;
2967 char *path;
2968 int err;
2969
2970 err = get_path_wrlock(f, parent, name, &path, &wnode);
2971 if (!err) {
2972 struct fuse_intr_data d;
2973
2974 fuse_prepare_interrupt(f, req, &d);
2975 if (!f->conf.hard_remove && is_open(f, parent, name)) {
2976 err = hide_node(f, path, parent, name);
2977 } else {
2978 err = fuse_fs_unlink(f->fs, path);
2979 if (!err)
2980 remove_node(f, parent, name);
2981 }
2982 fuse_finish_interrupt(f, req, &d);
2983 free_path_wrlock(f, parent, wnode, path);
2984 }
2985 reply_err(req, err);
2986 }
2987
2988 static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
2989 {
2990 struct fuse *f = req_fuse_prepare(req);
2991 struct node *wnode;
2992 char *path;
2993 int err;
2994
2995 err = get_path_wrlock(f, parent, name, &path, &wnode);
2996 if (!err) {
2997 struct fuse_intr_data d;
2998
2999 fuse_prepare_interrupt(f, req, &d);
3000 err = fuse_fs_rmdir(f->fs, path);
3001 fuse_finish_interrupt(f, req, &d);
3002 if (!err)
3003 remove_node(f, parent, name);
3004 free_path_wrlock(f, parent, wnode, path);
3005 }
3006 reply_err(req, err);
3007 }
3008
3009 static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
3010 fuse_ino_t parent, const char *name)
3011 {
3012 struct fuse *f = req_fuse_prepare(req);
3013 struct fuse_entry_param e;
3014 char *path;
3015 int err;
3016
3017 err = get_path_name(f, parent, name, &path);
3018 if (!err) {
3019 struct fuse_intr_data d;
3020
3021 fuse_prepare_interrupt(f, req, &d);
3022 err = fuse_fs_symlink(f->fs, linkname, path);
3023 if (!err)
3024 err = lookup_path(f, parent, name, path, &e, NULL);
3025 fuse_finish_interrupt(f, req, &d);
3026 free_path(f, parent, path);
3027 }
3028 reply_entry(req, &e, err);
3029 }
3030
3031 static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
3032 const char *oldname, fuse_ino_t newdir,
3033 const char *newname, unsigned int flags)
3034 {
3035 struct fuse *f = req_fuse_prepare(req);
3036 char *oldpath;
3037 char *newpath;
3038 struct node *wnode1;
3039 struct node *wnode2;
3040 int err;
3041
3042 err = get_path2(f, olddir, oldname, newdir, newname,
3043 &oldpath, &newpath, &wnode1, &wnode2);
3044 if (!err) {
3045 struct fuse_intr_data d;
3046 err = 0;
3047 fuse_prepare_interrupt(f, req, &d);
3048 if (!f->conf.hard_remove && !(flags & RENAME_EXCHANGE) &&
3049 is_open(f, newdir, newname))
3050 err = hide_node(f, newpath, newdir, newname);
3051 if (!err) {
3052 err = fuse_fs_rename(f->fs, oldpath, newpath, flags);
3053 if (!err) {
3054 if (flags & RENAME_EXCHANGE) {
3055 err = exchange_node(f, olddir, oldname,
3056 newdir, newname);
3057 } else {
3058 err = rename_node(f, olddir, oldname,
3059 newdir, newname, 0);
3060 }
3061 }
3062 }
3063 fuse_finish_interrupt(f, req, &d);
3064 free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3065 }
3066 reply_err(req, err);
3067 }
3068
3069 static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
3070 const char *newname)
3071 {
3072 struct fuse *f = req_fuse_prepare(req);
3073 struct fuse_entry_param e;
3074 char *oldpath;
3075 char *newpath;
3076 int err;
3077
3078 err = get_path2(f, ino, NULL, newparent, newname,
3079 &oldpath, &newpath, NULL, NULL);
3080 if (!err) {
3081 struct fuse_intr_data d;
3082
3083 fuse_prepare_interrupt(f, req, &d);
3084 err = fuse_fs_link(f->fs, oldpath, newpath);
3085 if (!err)
3086 err = lookup_path(f, newparent, newname, newpath,
3087 &e, NULL);
3088 fuse_finish_interrupt(f, req, &d);
3089 free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3090 }
3091 reply_entry(req, &e, err);
3092 }
3093
3094 static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
3095 struct fuse_file_info *fi)
3096 {
3097 struct node *node;
3098 int unlink_hidden = 0;
3099
3100 fuse_fs_release(f->fs, path, fi);
3101
3102 pthread_mutex_lock(&f->lock);
3103 node = get_node(f, ino);
3104 assert(node->open_count > 0);
3105 --node->open_count;
3106 if (node->is_hidden && !node->open_count) {
3107 unlink_hidden = 1;
3108 node->is_hidden = 0;
3109 }
3110 pthread_mutex_unlock(&f->lock);
3111
3112 if(unlink_hidden) {
3113 if (path) {
3114 fuse_fs_unlink(f->fs, path);
3115 } else if (f->conf.nullpath_ok) {
3116 char *unlinkpath;
3117
3118 if (get_path(f, ino, &unlinkpath) == 0)
3119 fuse_fs_unlink(f->fs, unlinkpath);
3120
3121 free_path(f, ino, unlinkpath);
3122 }
3123 }
3124 }
3125
3126 static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
3127 const char *name, mode_t mode,
3128 struct fuse_file_info *fi)
3129 {
3130 struct fuse *f = req_fuse_prepare(req);
3131 struct fuse_intr_data d;
3132 struct fuse_entry_param e;
3133 char *path;
3134 int err;
3135
3136 err = get_path_name(f, parent, name, &path);
3137 if (!err) {
3138 fuse_prepare_interrupt(f, req, &d);
3139 err = fuse_fs_create(f->fs, path, mode, fi);
3140 if (!err) {
3141 err = lookup_path(f, parent, name, path, &e, fi);
3142 if (err)
3143 fuse_fs_release(f->fs, path, fi);
3144 else if (!S_ISREG(e.attr.st_mode)) {
3145 err = -EIO;
3146 fuse_fs_release(f->fs, path, fi);
3147 forget_node(f, e.ino, 1);
3148 } else {
3149 if (f->conf.direct_io)
3150 fi->direct_io = 1;
3151 if (f->conf.kernel_cache)
3152 fi->keep_cache = 1;
3153
3154 }
3155 }
3156 fuse_finish_interrupt(f, req, &d);
3157 }
3158 if (!err) {
3159 pthread_mutex_lock(&f->lock);
3160 get_node(f, e.ino)->open_count++;
3161 pthread_mutex_unlock(&f->lock);
3162 if (fuse_reply_create(req, &e, fi) == -ENOENT) {
3163 /* The open syscall was interrupted, so it
3164 must be cancelled */
3165 fuse_do_release(f, e.ino, path, fi);
3166 forget_node(f, e.ino, 1);
3167 }
3168 } else {
3169 reply_err(req, err);
3170 }
3171
3172 free_path(f, parent, path);
3173 }
3174
3175 static double diff_timespec(const struct timespec *t1,
3176 const struct timespec *t2)
3177 {
3178 return (t1->tv_sec - t2->tv_sec) +
3179 ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
3180 }
3181
3182 static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
3183 struct fuse_file_info *fi)
3184 {
3185 struct node *node;
3186
3187 pthread_mutex_lock(&f->lock);
3188 node = get_node(f, ino);
3189 if (node->cache_valid) {
3190 struct timespec now;
3191
3192 curr_time(&now);
3193 if (diff_timespec(&now, &node->stat_updated) >
3194 f->conf.ac_attr_timeout) {
3195 struct stat stbuf;
3196 int err;
3197 pthread_mutex_unlock(&f->lock);
3198 err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
3199 pthread_mutex_lock(&f->lock);
3200 if (!err)
3201 update_stat(node, &stbuf);
3202 else
3203 node->cache_valid = 0;
3204 }
3205 }
3206 if (node->cache_valid)
3207 fi->keep_cache = 1;
3208
3209 node->cache_valid = 1;
3210 pthread_mutex_unlock(&f->lock);
3211 }
3212
3213 static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
3214 struct fuse_file_info *fi)
3215 {
3216 struct fuse *f = req_fuse_prepare(req);
3217 struct fuse_intr_data d;
3218 char *path;
3219 int err;
3220
3221 err = get_path(f, ino, &path);
3222 if (!err) {
3223 fuse_prepare_interrupt(f, req, &d);
3224 err = fuse_fs_open(f->fs, path, fi);
3225 if (!err) {
3226 if (f->conf.direct_io)
3227 fi->direct_io = 1;
3228 if (f->conf.kernel_cache)
3229 fi->keep_cache = 1;
3230
3231 if (f->conf.auto_cache)
3232 open_auto_cache(f, ino, path, fi);
3233 }
3234 fuse_finish_interrupt(f, req, &d);
3235 }
3236 if (!err) {
3237 pthread_mutex_lock(&f->lock);
3238 get_node(f, ino)->open_count++;
3239 pthread_mutex_unlock(&f->lock);
3240 if (fuse_reply_open(req, fi) == -ENOENT) {
3241 /* The open syscall was interrupted, so it
3242 must be cancelled */
3243 fuse_do_release(f, ino, path, fi);
3244 }
3245 } else
3246 reply_err(req, err);
3247
3248 free_path(f, ino, path);
3249 }
3250
3251 static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
3252 off_t off, struct fuse_file_info *fi)
3253 {
3254 struct fuse *f = req_fuse_prepare(req);
3255 struct fuse_bufvec *buf = NULL;
3256 char *path;
3257 int res;
3258
3259 res = get_path_nullok(f, ino, &path);
3260 if (res == 0) {
3261 struct fuse_intr_data d;
3262
3263 fuse_prepare_interrupt(f, req, &d);
3264 res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3265 fuse_finish_interrupt(f, req, &d);
3266 free_path(f, ino, path);
3267 }
3268
3269 if (res == 0)
3270 fuse_reply_data(req, buf, FUSE_BUF_SPLICE_MOVE);
3271 else
3272 reply_err(req, res);
3273
3274 fuse_free_buf(buf);
3275 }
3276
3277 static void fuse_lib_write_buf(fuse_req_t req, fuse_ino_t ino,
3278 struct fuse_bufvec *buf, off_t off,
3279 struct fuse_file_info *fi)
3280 {
3281 struct fuse *f = req_fuse_prepare(req);
3282 char *path;
3283 int res;
3284
3285 res = get_path_nullok(f, ino, &path);
3286 if (res == 0) {
3287 struct fuse_intr_data d;
3288
3289 fuse_prepare_interrupt(f, req, &d);
3290 res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3291 fuse_finish_interrupt(f, req, &d);
3292 free_path(f, ino, path);
3293 }
3294
3295 if (res >= 0)
3296 fuse_reply_write(req, res);
3297 else
3298 reply_err(req, res);
3299 }
3300
3301 static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
3302 struct fuse_file_info *fi)
3303 {
3304 struct fuse *f = req_fuse_prepare(req);
3305 char *path;
3306 int err;
3307
3308 err = get_path_nullok(f, ino, &path);
3309 if (!err) {
3310 struct fuse_intr_data d;
3311
3312 fuse_prepare_interrupt(f, req, &d);
3313 err = fuse_fs_fsync(f->fs, path, datasync, fi);
3314 fuse_finish_interrupt(f, req, &d);
3315 free_path(f, ino, path);
3316 }
3317 reply_err(req, err);
3318 }
3319
3320 static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
3321 struct fuse_file_info *fi)
3322 {
3323 struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
3324 memset(fi, 0, sizeof(struct fuse_file_info));
3325 fi->fh = dh->fh;
3326 return dh;
3327 }
3328
3329 static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
3330 struct fuse_file_info *llfi)
3331 {
3332 struct fuse *f = req_fuse_prepare(req);
3333 struct fuse_intr_data d;
3334 struct fuse_dh *dh;
3335 struct fuse_file_info fi;
3336 char *path;
3337 int err;
3338
3339 dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
3340 if (dh == NULL) {
3341 reply_err(req, -ENOMEM);
3342 return;
3343 }
3344 memset(dh, 0, sizeof(struct fuse_dh));
3345 dh->fuse = f;
3346 dh->contents = NULL;
3347 dh->first = NULL;
3348 dh->len = 0;
3349 dh->filled = 0;
3350 dh->nodeid = ino;
3351 fuse_mutex_init(&dh->lock);
3352
3353 llfi->fh = (uintptr_t) dh;
3354
3355 memset(&fi, 0, sizeof(fi));
3356 fi.flags = llfi->flags;
3357
3358 err = get_path(f, ino, &path);
3359 if (!err) {
3360 fuse_prepare_interrupt(f, req, &d);
3361 err = fuse_fs_opendir(f->fs, path, &fi);
3362 fuse_finish_interrupt(f, req, &d);
3363 dh->fh = fi.fh;
3364 }
3365 if (!err) {
3366 if (fuse_reply_open(req, llfi) == -ENOENT) {
3367 /* The opendir syscall was interrupted, so it
3368 must be cancelled */
3369 fuse_fs_releasedir(f->fs, path, &fi);
3370 pthread_mutex_destroy(&dh->lock);
3371 free(dh);
3372 }
3373 } else {
3374 reply_err(req, err);
3375 pthread_mutex_destroy(&dh->lock);
3376 free(dh);
3377 }
3378 free_path(f, ino, path);
3379 }
3380
3381 static int extend_contents(struct fuse_dh *dh, unsigned minsize)
3382 {
3383 if (minsize > dh->size) {
3384 char *newptr;
3385 unsigned newsize = dh->size;
3386 if (!newsize)
3387 newsize = 1024;
3388 while (newsize < minsize) {
3389 if (newsize >= 0x80000000)
3390 newsize = 0xffffffff;
3391 else
3392 newsize *= 2;
3393 }
3394
3395 newptr = (char *) realloc(dh->contents, newsize);
3396 if (!newptr) {
3397 dh->error = -ENOMEM;
3398 return -1;
3399 }
3400 dh->contents = newptr;
3401 dh->size = newsize;
3402 }
3403 return 0;
3404 }
3405
3406 static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name,
3407 struct stat *st)
3408 {
3409 struct fuse_direntry *de;
3410
3411 de = malloc(sizeof(struct fuse_direntry));
3412 if (!de) {
3413 dh->error = -ENOMEM;
3414 return -1;
3415 }
3416 de->name = strdup(name);
3417 if (!de->name) {
3418 dh->error = -ENOMEM;
3419 free(de);
3420 return -1;
3421 }
3422 de->stat = *st;
3423 de->next = NULL;
3424
3425 *dh->last = de;
3426 dh->last = &de->next;
3427
3428 return 0;
3429 }
3430
3431 static fuse_ino_t lookup_nodeid(struct fuse *f, fuse_ino_t parent,
3432 const char *name)
3433 {
3434 struct node *node;
3435 fuse_ino_t res = FUSE_UNKNOWN_INO;
3436
3437 pthread_mutex_lock(&f->lock);
3438 node = lookup_node(f, parent, name);
3439 if (node)
3440 res = node->nodeid;
3441 pthread_mutex_unlock(&f->lock);
3442
3443 return res;
3444 }
3445
3446 static int fill_dir(void *dh_, const char *name, const struct stat *statp,
3447 off_t off, enum fuse_fill_dir_flags flags)
3448 {
3449 struct fuse_dh *dh = (struct fuse_dh *) dh_;
3450 struct stat stbuf;
3451
3452 if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3453 dh->error = -EIO;
3454 return 1;
3455 }
3456
3457 if (statp)
3458 stbuf = *statp;
3459 else {
3460 memset(&stbuf, 0, sizeof(stbuf));
3461 stbuf.st_ino = FUSE_UNKNOWN_INO;
3462 }
3463
3464 if (!dh->fuse->conf.use_ino) {
3465 stbuf.st_ino = FUSE_UNKNOWN_INO;
3466 if (dh->fuse->conf.readdir_ino) {
3467 stbuf.st_ino = (ino_t)
3468 lookup_nodeid(dh->fuse, dh->nodeid, name);
3469 }
3470 }
3471
3472 if (off) {
3473 size_t newlen;
3474
3475 if (dh->filled) {
3476 dh->error = -EIO;
3477 return 1;
3478 }
3479
3480 if (dh->first) {
3481 dh->error = -EIO;
3482 return 1;
3483 }
3484
3485 if (extend_contents(dh, dh->needlen) == -1)
3486 return 1;
3487
3488 newlen = dh->len +
3489 fuse_add_direntry(dh->req, dh->contents + dh->len,
3490 dh->needlen - dh->len, name,
3491 &stbuf, off);
3492 if (newlen > dh->needlen)
3493 return 1;
3494
3495 dh->len = newlen;
3496 } else {
3497 dh->filled = 1;
3498
3499 if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3500 return 1;
3501 }
3502 return 0;
3503 }
3504
3505 static int is_dot_or_dotdot(const char *name)
3506 {
3507 return name[0] == '.' && (name[1] == '\0' ||
3508 (name[1] == '.' && name[2] == '\0'));
3509 }
3510
3511 static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
3512 off_t off, enum fuse_fill_dir_flags flags)
3513 {
3514 struct fuse_dh *dh = (struct fuse_dh *) dh_;
3515 struct fuse_entry_param e = {
3516 /* ino=0 tells the kernel to ignore readdirplus stat info */
3517 .ino = 0,
3518 };
3519 struct fuse *f = dh->fuse;
3520 int res;
3521
3522 if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3523 dh->error = -EIO;
3524 return 1;
3525 }
3526
3527 if (off && statp && (flags & FUSE_FILL_DIR_PLUS)) {
3528 e.attr = *statp;
3529
3530 if (!is_dot_or_dotdot(name)) {
3531 res = do_lookup(f, dh->nodeid, name, &e);
3532 if (res) {
3533 dh->error = res;
3534 return 1;
3535 }
3536 }
3537 } else {
3538 e.attr.st_ino = FUSE_UNKNOWN_INO;
3539 if (!f->conf.use_ino && f->conf.readdir_ino) {
3540 e.attr.st_ino = (ino_t)
3541 lookup_nodeid(f, dh->nodeid, name);
3542 }
3543 }
3544
3545 if (off) {
3546 size_t newlen;
3547
3548 if (dh->filled) {
3549 dh->error = -EIO;
3550 return 1;
3551 }
3552
3553 if (dh->first) {
3554 dh->error = -EIO;
3555 return 1;
3556 }
3557 if (extend_contents(dh, dh->needlen) == -1)
3558 return 1;
3559
3560 newlen = dh->len +
3561 fuse_add_direntry_plus(dh->req, dh->contents + dh->len,
3562 dh->needlen - dh->len, name,
3563 &e, off);
3564 if (newlen > dh->needlen)
3565 return 1;
3566 dh->len = newlen;
3567 } else {
3568 dh->filled = 1;
3569
3570 if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1)
3571 return 1;
3572 }
3573
3574 return 0;
3575 }
3576
3577 static void free_direntries(struct fuse_direntry *de)
3578 {
3579 while (de) {
3580 struct fuse_direntry *next = de->next;
3581 free(de->name);
3582 free(de);
3583 de = next;
3584 }
3585 }
3586
3587 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3588 size_t size, off_t off, struct fuse_dh *dh,
3589 struct fuse_file_info *fi,
3590 enum fuse_readdir_flags flags)
3591 {
3592 char *path;
3593 int err;
3594
3595 if (f->fs->op.readdir)
3596 err = get_path_nullok(f, ino, &path);
3597 else
3598 err = get_path(f, ino, &path);
3599 if (!err) {
3600 struct fuse_intr_data d;
3601 fuse_fill_dir_t filler = fill_dir;
3602
3603 if (flags & FUSE_READDIR_PLUS)
3604 filler = fill_dir_plus;
3605
3606 free_direntries(dh->first);
3607 dh->first = NULL;
3608 dh->last = &dh->first;
3609 dh->len = 0;
3610 dh->error = 0;
3611 dh->needlen = size;
3612 dh->filled = 0;
3613 dh->req = req;
3614 fuse_prepare_interrupt(f, req, &d);
3615 err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3616 fuse_finish_interrupt(f, req, &d);
3617 dh->req = NULL;
3618 if (!err)
3619 err = dh->error;
3620 if (err)
3621 dh->filled = 0;
3622 free_path(f, ino, path);
3623 }
3624 return err;
3625 }
3626
3627 static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh,
3628 off_t off, enum fuse_readdir_flags flags)
3629 {
3630 off_t pos;
3631 struct fuse_direntry *de = dh->first;
3632
3633 dh->len = 0;
3634
3635 if (extend_contents(dh, dh->needlen) == -1)
3636 return dh->error;
3637
3638 for (pos = 0; pos < off; pos++) {
3639 if (!de)
3640 break;
3641
3642 de = de->next;
3643 }
3644 while (de) {
3645 char *p = dh->contents + dh->len;
3646 unsigned rem = dh->needlen - dh->len;
3647 unsigned thislen;
3648 unsigned newlen;
3649 pos++;
3650
3651 if (flags & FUSE_READDIR_PLUS) {
3652 struct fuse_entry_param e = {
3653 .ino = 0,
3654 .attr = de->stat,
3655 };
3656 thislen = fuse_add_direntry_plus(req, p, rem,
3657 de->name, &e, pos);
3658 } else {
3659 thislen = fuse_add_direntry(req, p, rem,
3660 de->name, &de->stat, pos);
3661 }
3662 newlen = dh->len + thislen;
3663 if (newlen > dh->needlen)
3664 break;
3665 dh->len = newlen;
3666 de = de->next;
3667 }
3668 return 0;
3669 }
3670
3671 static void fuse_readdir_common(fuse_req_t req, fuse_ino_t ino, size_t size,
3672 off_t off, struct fuse_file_info *llfi,
3673 enum fuse_readdir_flags flags)
3674 {
3675 struct fuse *f = req_fuse_prepare(req);
3676 struct fuse_file_info fi;
3677 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3678 int err;
3679
3680 pthread_mutex_lock(&dh->lock);
3681 /* According to SUS, directory contents need to be refreshed on
3682 rewinddir() */
3683 if (!off)
3684 dh->filled = 0;
3685
3686 if (!dh->filled) {
3687 err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3688 if (err) {
3689 reply_err(req, err);
3690 goto out;
3691 }
3692 }
3693 if (dh->filled) {
3694 dh->needlen = size;
3695 err = readdir_fill_from_list(req, dh, off, flags);
3696 if (err) {
3697 reply_err(req, err);
3698 goto out;
3699 }
3700 }
3701 fuse_reply_buf(req, dh->contents, dh->len);
3702 out:
3703 pthread_mutex_unlock(&dh->lock);
3704 }
3705
3706 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3707 off_t off, struct fuse_file_info *llfi)
3708 {
3709 fuse_readdir_common(req, ino, size, off, llfi, 0);
3710 }
3711
3712 static void fuse_lib_readdirplus(fuse_req_t req, fuse_ino_t ino, size_t size,
3713 off_t off, struct fuse_file_info *llfi)
3714 {
3715 fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3716 }
3717
3718 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3719 struct fuse_file_info *llfi)
3720 {
3721 struct fuse *f = req_fuse_prepare(req);
3722 struct fuse_intr_data d;
3723 struct fuse_file_info fi;
3724 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3725 char *path;
3726
3727 get_path_nullok(f, ino, &path);
3728
3729 fuse_prepare_interrupt(f, req, &d);
3730 fuse_fs_releasedir(f->fs, path, &fi);
3731 fuse_finish_interrupt(f, req, &d);
3732 free_path(f, ino, path);
3733
3734 pthread_mutex_lock(&dh->lock);
3735 pthread_mutex_unlock(&dh->lock);
3736 pthread_mutex_destroy(&dh->lock);
3737 free_direntries(dh->first);
3738 free(dh->contents);
3739 free(dh);
3740 reply_err(req, 0);
3741 }
3742
3743 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3744 struct fuse_file_info *llfi)
3745 {
3746 struct fuse *f = req_fuse_prepare(req);
3747 struct fuse_file_info fi;
3748 char *path;
3749 int err;
3750
3751 get_dirhandle(llfi, &fi);
3752
3753 err = get_path_nullok(f, ino, &path);
3754 if (!err) {
3755 struct fuse_intr_data d;
3756 fuse_prepare_interrupt(f, req, &d);
3757 err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3758 fuse_finish_interrupt(f, req, &d);
3759 free_path(f, ino, path);
3760 }
3761 reply_err(req, err);
3762 }
3763
3764 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3765 {
3766 struct fuse *f = req_fuse_prepare(req);
3767 struct statvfs buf;
3768 char *path = NULL;
3769 int err = 0;
3770
3771 memset(&buf, 0, sizeof(buf));
3772 if (ino)
3773 err = get_path(f, ino, &path);
3774
3775 if (!err) {
3776 struct fuse_intr_data d;
3777 fuse_prepare_interrupt(f, req, &d);
3778 err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3779 fuse_finish_interrupt(f, req, &d);
3780 free_path(f, ino, path);
3781 }
3782
3783 if (!err)
3784 fuse_reply_statfs(req, &buf);
3785 else
3786 reply_err(req, err);
3787 }
3788
3789 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3790 const char *value, size_t size, int flags)
3791 {
3792 struct fuse *f = req_fuse_prepare(req);
3793 char *path;
3794 int err;
3795
3796 err = get_path(f, ino, &path);
3797 if (!err) {
3798 struct fuse_intr_data d;
3799 fuse_prepare_interrupt(f, req, &d);
3800 err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3801 fuse_finish_interrupt(f, req, &d);
3802 free_path(f, ino, path);
3803 }
3804 reply_err(req, err);
3805 }
3806
3807 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3808 const char *name, char *value, size_t size)
3809 {
3810 int err;
3811 char *path;
3812
3813 err = get_path(f, ino, &path);
3814 if (!err) {
3815 struct fuse_intr_data d;
3816 fuse_prepare_interrupt(f, req, &d);
3817 err = fuse_fs_getxattr(f->fs, path, name, value, size);
3818 fuse_finish_interrupt(f, req, &d);
3819 free_path(f, ino, path);
3820 }
3821 return err;
3822 }
3823
3824 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3825 size_t size)
3826 {
3827 struct fuse *f = req_fuse_prepare(req);
3828 int res;
3829
3830 if (size) {
3831 char *value = (char *) malloc(size);
3832 if (value == NULL) {
3833 reply_err(req, -ENOMEM);
3834 return;
3835 }
3836 res = common_getxattr(f, req, ino, name, value, size);
3837 if (res > 0)
3838 fuse_reply_buf(req, value, res);
3839 else
3840 reply_err(req, res);
3841 free(value);
3842 } else {
3843 res = common_getxattr(f, req, ino, name, NULL, 0);
3844 if (res >= 0)
3845 fuse_reply_xattr(req, res);
3846 else
3847 reply_err(req, res);
3848 }
3849 }
3850
3851 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3852 char *list, size_t size)
3853 {
3854 char *path;
3855 int err;
3856
3857 err = get_path(f, ino, &path);
3858 if (!err) {
3859 struct fuse_intr_data d;
3860 fuse_prepare_interrupt(f, req, &d);
3861 err = fuse_fs_listxattr(f->fs, path, list, size);
3862 fuse_finish_interrupt(f, req, &d);
3863 free_path(f, ino, path);
3864 }
3865 return err;
3866 }
3867
3868 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3869 {
3870 struct fuse *f = req_fuse_prepare(req);
3871 int res;
3872
3873 if (size) {
3874 char *list = (char *) malloc(size);
3875 if (list == NULL) {
3876 reply_err(req, -ENOMEM);
3877 return;
3878 }
3879 res = common_listxattr(f, req, ino, list, size);
3880 if (res > 0)
3881 fuse_reply_buf(req, list, res);
3882 else
3883 reply_err(req, res);
3884 free(list);
3885 } else {
3886 res = common_listxattr(f, req, ino, NULL, 0);
3887 if (res >= 0)
3888 fuse_reply_xattr(req, res);
3889 else
3890 reply_err(req, res);
3891 }
3892 }
3893
3894 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3895 const char *name)
3896 {
3897 struct fuse *f = req_fuse_prepare(req);
3898 char *path;
3899 int err;
3900
3901 err = get_path(f, ino, &path);
3902 if (!err) {
3903 struct fuse_intr_data d;
3904 fuse_prepare_interrupt(f, req, &d);
3905 err = fuse_fs_removexattr(f->fs, path, name);
3906 fuse_finish_interrupt(f, req, &d);
3907 free_path(f, ino, path);
3908 }
3909 reply_err(req, err);
3910 }
3911
3912 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3913 {
3914 struct lock *l;
3915
3916 for (l = node->locks; l; l = l->next)
3917 if (l->owner != lock->owner &&
3918 lock->start <= l->end && l->start <= lock->end &&
3919 (l->type == F_WRLCK || lock->type == F_WRLCK))
3920 break;
3921
3922 return l;
3923 }
3924
3925 static void delete_lock(struct lock **lockp)
3926 {
3927 struct lock *l = *lockp;
3928 *lockp = l->next;
3929 free(l);
3930 }
3931
3932 static void insert_lock(struct lock **pos, struct lock *lock)
3933 {
3934 lock->next = *pos;
3935 *pos = lock;
3936 }
3937
3938 static int locks_insert(struct node *node, struct lock *lock)
3939 {
3940 struct lock **lp;
3941 struct lock *newl1 = NULL;
3942 struct lock *newl2 = NULL;
3943
3944 if (lock->type != F_UNLCK || lock->start != 0 ||
3945 lock->end != OFFSET_MAX) {
3946 newl1 = malloc(sizeof(struct lock));
3947 newl2 = malloc(sizeof(struct lock));
3948
3949 if (!newl1 || !newl2) {
3950 free(newl1);
3951 free(newl2);
3952 return -ENOLCK;
3953 }
3954 }
3955
3956 for (lp = &node->locks; *lp;) {
3957 struct lock *l = *lp;
3958 if (l->owner != lock->owner)
3959 goto skip;
3960
3961 if (lock->type == l->type) {
3962 if (l->end < lock->start - 1)
3963 goto skip;
3964 if (lock->end < l->start - 1)
3965 break;
3966 if (l->start <= lock->start && lock->end <= l->end)
3967 goto out;
3968 if (l->start < lock->start)
3969 lock->start = l->start;
3970 if (lock->end < l->end)
3971 lock->end = l->end;
3972 goto delete;
3973 } else {
3974 if (l->end < lock->start)
3975 goto skip;
3976 if (lock->end < l->start)
3977 break;
3978 if (lock->start <= l->start && l->end <= lock->end)
3979 goto delete;
3980 if (l->end <= lock->end) {
3981 l->end = lock->start - 1;
3982 goto skip;
3983 }
3984 if (lock->start <= l->start) {
3985 l->start = lock->end + 1;
3986 break;
3987 }
3988 *newl2 = *l;
3989 newl2->start = lock->end + 1;
3990 l->end = lock->start - 1;
3991 insert_lock(&l->next, newl2);
3992 newl2 = NULL;
3993 }
3994 skip:
3995 lp = &l->next;
3996 continue;
3997
3998 delete:
3999 delete_lock(lp);
4000 }
4001 if (lock->type != F_UNLCK) {
4002 *newl1 = *lock;
4003 insert_lock(lp, newl1);
4004 newl1 = NULL;
4005 }
4006 out:
4007 free(newl1);
4008 free(newl2);
4009 return 0;
4010 }
4011
4012 static void flock_to_lock(struct flock *flock, struct lock *lock)
4013 {
4014 memset(lock, 0, sizeof(struct lock));
4015 lock->type = flock->l_type;
4016 lock->start = flock->l_start;
4017 lock->end =
4018 flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4019 lock->pid = flock->l_pid;
4020 }
4021
4022 static void lock_to_flock(struct lock *lock, struct flock *flock)
4023 {
4024 flock->l_type = lock->type;
4025 flock->l_start = lock->start;
4026 flock->l_len =
4027 (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4028 flock->l_pid = lock->pid;
4029 }
4030
4031 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
4032 const char *path, struct fuse_file_info *fi)
4033 {
4034 struct fuse_intr_data d;
4035 struct flock lock;
4036 struct lock l;
4037 int err;
4038 int errlock;
4039
4040 fuse_prepare_interrupt(f, req, &d);
4041 memset(&lock, 0, sizeof(lock));
4042 lock.l_type = F_UNLCK;
4043 lock.l_whence = SEEK_SET;
4044 err = fuse_fs_flush(f->fs, path, fi);
4045 errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4046 fuse_finish_interrupt(f, req, &d);
4047
4048 if (errlock != -ENOSYS) {
4049 flock_to_lock(&lock, &l);
4050 l.owner = fi->lock_owner;
4051 pthread_mutex_lock(&f->lock);
4052 locks_insert(get_node(f, ino), &l);
4053 pthread_mutex_unlock(&f->lock);
4054
4055 /* if op.lock() is defined FLUSH is needed regardless
4056 of op.flush() */
4057 if (err == -ENOSYS)
4058 err = 0;
4059 }
4060 return err;
4061 }
4062
4063 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
4064 struct fuse_file_info *fi)
4065 {
4066 struct fuse *f = req_fuse_prepare(req);
4067 struct fuse_intr_data d;
4068 char *path;
4069 int err = 0;
4070
4071 get_path_nullok(f, ino, &path);
4072 if (fi->flush) {
4073 err = fuse_flush_common(f, req, ino, path, fi);
4074 if (err == -ENOSYS)
4075 err = 0;
4076 }
4077
4078 fuse_prepare_interrupt(f, req, &d);
4079 fuse_do_release(f, ino, path, fi);
4080 fuse_finish_interrupt(f, req, &d);
4081 free_path(f, ino, path);
4082
4083 reply_err(req, err);
4084 }
4085
4086 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
4087 struct fuse_file_info *fi)
4088 {
4089 struct fuse *f = req_fuse_prepare(req);
4090 char *path;
4091 int err;
4092
4093 get_path_nullok(f, ino, &path);
4094 err = fuse_flush_common(f, req, ino, path, fi);
4095 free_path(f, ino, path);
4096
4097 reply_err(req, err);
4098 }
4099
4100 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
4101 struct fuse_file_info *fi, struct flock *lock,
4102 int cmd)
4103 {
4104 struct fuse *f = req_fuse_prepare(req);
4105 char *path;
4106 int err;
4107
4108 err = get_path_nullok(f, ino, &path);
4109 if (!err) {
4110 struct fuse_intr_data d;
4111 fuse_prepare_interrupt(f, req, &d);
4112 err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4113 fuse_finish_interrupt(f, req, &d);
4114 free_path(f, ino, path);
4115 }
4116 return err;
4117 }
4118
4119 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
4120 struct fuse_file_info *fi, struct flock *lock)
4121 {
4122 int err;
4123 struct lock l;
4124 struct lock *conflict;
4125 struct fuse *f = req_fuse(req);
4126
4127 flock_to_lock(lock, &l);
4128 l.owner = fi->lock_owner;
4129 pthread_mutex_lock(&f->lock);
4130 conflict = locks_conflict(get_node(f, ino), &l);
4131 if (conflict)
4132 lock_to_flock(conflict, lock);
4133 pthread_mutex_unlock(&f->lock);
4134 if (!conflict)
4135 err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4136 else
4137 err = 0;
4138
4139 if (!err)
4140 fuse_reply_lock(req, lock);
4141 else
4142 reply_err(req, err);
4143 }
4144
4145 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
4146 struct fuse_file_info *fi, struct flock *lock,
4147 int sleep)
4148 {
4149 int err = fuse_lock_common(req, ino, fi, lock,
4150 sleep ? F_SETLKW : F_SETLK);
4151 if (!err) {
4152 struct fuse *f = req_fuse(req);
4153 struct lock l;
4154 flock_to_lock(lock, &l);
4155 l.owner = fi->lock_owner;
4156 pthread_mutex_lock(&f->lock);
4157 locks_insert(get_node(f, ino), &l);
4158 pthread_mutex_unlock(&f->lock);
4159 }
4160 reply_err(req, err);
4161 }
4162
4163 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
4164 struct fuse_file_info *fi, int op)
4165 {
4166 struct fuse *f = req_fuse_prepare(req);
4167 char *path;
4168 int err;
4169
4170 err = get_path_nullok(f, ino, &path);
4171 if (err == 0) {
4172 struct fuse_intr_data d;
4173 fuse_prepare_interrupt(f, req, &d);
4174 err = fuse_fs_flock(f->fs, path, fi, op);
4175 fuse_finish_interrupt(f, req, &d);
4176 free_path(f, ino, path);
4177 }
4178 reply_err(req, err);
4179 }
4180
4181 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
4182 uint64_t idx)
4183 {
4184 struct fuse *f = req_fuse_prepare(req);
4185 struct fuse_intr_data d;
4186 char *path;
4187 int err;
4188
4189 err = get_path(f, ino, &path);
4190 if (!err) {
4191 fuse_prepare_interrupt(f, req, &d);
4192 err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4193 fuse_finish_interrupt(f, req, &d);
4194 free_path(f, ino, path);
4195 }
4196 if (!err)
4197 fuse_reply_bmap(req, idx);
4198 else
4199 reply_err(req, err);
4200 }
4201
4202 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
4203 struct fuse_file_info *llfi, unsigned int flags,
4204 const void *in_buf, size_t in_bufsz,
4205 size_t out_bufsz)
4206 {
4207 struct fuse *f = req_fuse_prepare(req);
4208 struct fuse_intr_data d;
4209 struct fuse_file_info fi;
4210 char *path, *out_buf = NULL;
4211 int err;
4212
4213 err = -EPERM;
4214 if (flags & FUSE_IOCTL_UNRESTRICTED)
4215 goto err;
4216
4217 if (flags & FUSE_IOCTL_DIR)
4218 get_dirhandle(llfi, &fi);
4219 else
4220 fi = *llfi;
4221
4222 if (out_bufsz) {
4223 err = -ENOMEM;
4224 out_buf = malloc(out_bufsz);
4225 if (!out_buf)
4226 goto err;
4227 }
4228
4229 assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4230 if (out_buf && in_bufsz)
4231 memcpy(out_buf, in_buf, in_bufsz);
4232
4233 err = get_path_nullok(f, ino, &path);
4234 if (err)
4235 goto err;
4236
4237 fuse_prepare_interrupt(f, req, &d);
4238
4239 err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4240 out_buf ?: (void *)in_buf);
4241
4242 fuse_finish_interrupt(f, req, &d);
4243 free_path(f, ino, path);
4244
4245 fuse_reply_ioctl(req, err, out_buf, out_bufsz);
4246 goto out;
4247 err:
4248 reply_err(req, err);
4249 out:
4250 free(out_buf);
4251 }
4252
4253 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
4254 struct fuse_file_info *fi, struct fuse_pollhandle *ph)
4255 {
4256 struct fuse *f = req_fuse_prepare(req);
4257 struct fuse_intr_data d;
4258 char *path;
4259 int err;
4260 unsigned revents = 0;
4261
4262 err = get_path_nullok(f, ino, &path);
4263 if (!err) {
4264 fuse_prepare_interrupt(f, req, &d);
4265 err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4266 fuse_finish_interrupt(f, req, &d);
4267 free_path(f, ino, path);
4268 }
4269 if (!err)
4270 fuse_reply_poll(req, revents);
4271 else
4272 reply_err(req, err);
4273 }
4274
4275 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
4276 off_t offset, off_t length, struct fuse_file_info *fi)
4277 {
4278 struct fuse *f = req_fuse_prepare(req);
4279 struct fuse_intr_data d;
4280 char *path;
4281 int err;
4282
4283 err = get_path_nullok(f, ino, &path);
4284 if (!err) {
4285 fuse_prepare_interrupt(f, req, &d);
4286 err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4287 fuse_finish_interrupt(f, req, &d);
4288 free_path(f, ino, path);
4289 }
4290 reply_err(req, err);
4291 }
4292
4293 static int clean_delay(struct fuse *f)
4294 {
4295 /*
4296 * This is calculating the delay between clean runs. To
4297 * reduce the number of cleans we are doing them 10 times
4298 * within the remember window.
4299 */
4300 int min_sleep = 60;
4301 int max_sleep = 3600;
4302 int sleep_time = f->conf.remember / 10;
4303
4304 if (sleep_time > max_sleep)
4305 return max_sleep;
4306 if (sleep_time < min_sleep)
4307 return min_sleep;
4308 return sleep_time;
4309 }
4310
4311 int fuse_clean_cache(struct fuse *f)
4312 {
4313 struct node_lru *lnode;
4314 struct list_head *curr, *next;
4315 struct node *node;
4316 struct timespec now;
4317
4318 pthread_mutex_lock(&f->lock);
4319
4320 curr_time(&now);
4321
4322 for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4323 double age;
4324
4325 next = curr->next;
4326 lnode = list_entry(curr, struct node_lru, lru);
4327 node = &lnode->node;
4328
4329 age = diff_timespec(&now, &lnode->forget_time);
4330 if (age <= f->conf.remember)
4331 break;
4332
4333 assert(node->nlookup == 1);
4334
4335 /* Don't forget active directories */
4336 if (node->refctr > 1)
4337 continue;
4338
4339 node->nlookup = 0;
4340 unhash_name(f, node);
4341 unref_node(f, node);
4342 }
4343 pthread_mutex_unlock(&f->lock);
4344
4345 return clean_delay(f);
4346 }
4347
4348 static struct fuse_lowlevel_ops fuse_path_ops = {
4349 .init = fuse_lib_init,
4350 .destroy = fuse_lib_destroy,
4351 .lookup = fuse_lib_lookup,
4352 .forget = fuse_lib_forget,
4353 .forget_multi = fuse_lib_forget_multi,
4354 .getattr = fuse_lib_getattr,
4355 .setattr = fuse_lib_setattr,
4356 .access = fuse_lib_access,
4357 .readlink = fuse_lib_readlink,
4358 .mknod = fuse_lib_mknod,
4359 .mkdir = fuse_lib_mkdir,
4360 .unlink = fuse_lib_unlink,
4361 .rmdir = fuse_lib_rmdir,
4362 .symlink = fuse_lib_symlink,
4363 .rename = fuse_lib_rename,
4364 .link = fuse_lib_link,
4365 .create = fuse_lib_create,
4366 .open = fuse_lib_open,
4367 .read = fuse_lib_read,
4368 .write_buf = fuse_lib_write_buf,
4369 .flush = fuse_lib_flush,
4370 .release = fuse_lib_release,
4371 .fsync = fuse_lib_fsync,
4372 .opendir = fuse_lib_opendir,
4373 .readdir = fuse_lib_readdir,
4374 .readdirplus = fuse_lib_readdirplus,
4375 .releasedir = fuse_lib_releasedir,
4376 .fsyncdir = fuse_lib_fsyncdir,
4377 .statfs = fuse_lib_statfs,
4378 .setxattr = fuse_lib_setxattr,
4379 .getxattr = fuse_lib_getxattr,
4380 .listxattr = fuse_lib_listxattr,
4381 .removexattr = fuse_lib_removexattr,
4382 .getlk = fuse_lib_getlk,
4383 .setlk = fuse_lib_setlk,
4384 .flock = fuse_lib_flock,
4385 .bmap = fuse_lib_bmap,
4386 .ioctl = fuse_lib_ioctl,
4387 .poll = fuse_lib_poll,
4388 .fallocate = fuse_lib_fallocate,
4389 };
4390
4391 int fuse_notify_poll(struct fuse_pollhandle *ph)
4392 {
4393 return fuse_lowlevel_notify_poll(ph);
4394 }
4395
4396 struct fuse_session *fuse_get_session(struct fuse *f)
4397 {
4398 return f->se;
4399 }
4400
4401 static int fuse_session_loop_remember(struct fuse *f)
4402 {
4403 struct fuse_session *se = f->se;
4404 int res = 0;
4405 struct timespec now;
4406 time_t next_clean;
4407 struct pollfd fds = {
4408 .fd = se->fd,
4409 .events = POLLIN
4410 };
4411 struct fuse_buf fbuf = {
4412 .mem = NULL,
4413 };
4414
4415 curr_time(&now);
4416 next_clean = now.tv_sec;
4417 while (!fuse_session_exited(se)) {
4418 unsigned timeout;
4419
4420 curr_time(&now);
4421 if (now.tv_sec < next_clean)
4422 timeout = next_clean - now.tv_sec;
4423 else
4424 timeout = 0;
4425
4426 res = poll(&fds, 1, timeout * 1000);
4427 if (res == -1) {
4428 if (errno == -EINTR)
4429 continue;
4430 else
4431 break;
4432 } else if (res > 0) {
4433 res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4434
4435 if (res == -EINTR)
4436 continue;
4437 if (res <= 0)
4438 break;
4439
4440 fuse_session_process_buf_int(se, &fbuf, NULL);
4441 } else {
4442 timeout = fuse_clean_cache(f);
4443 curr_time(&now);
4444 next_clean = now.tv_sec + timeout;
4445 }
4446 }
4447
4448 free(fbuf.mem);
4449 fuse_session_reset(se);
4450 return res < 0 ? -1 : 0;
4451 }
4452
4453 int fuse_loop(struct fuse *f)
4454 {
4455 if (!f)
4456 return -1;
4457
4458 if (lru_enabled(f))
4459 return fuse_session_loop_remember(f);
4460
4461 return fuse_session_loop(f->se);
4462 }
4463
4464 FUSE_SYMVER(".symver fuse_loop_mt_32,fuse_loop_mt@@FUSE_3.2");
4465 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
4466 {
4467 if (f == NULL)
4468 return -1;
4469
4470 int res = fuse_start_cleanup_thread(f);
4471 if (res)
4472 return -1;
4473
4474 res = fuse_session_loop_mt_32(fuse_get_session(f), config);
4475 fuse_stop_cleanup_thread(f);
4476 return res;
4477 }
4478
4479 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
4480 FUSE_SYMVER(".symver fuse_loop_mt_31,fuse_loop_mt@FUSE_3.0");
4481 int fuse_loop_mt_31(struct fuse *f, int clone_fd)
4482 {
4483 struct fuse_loop_config config;
4484 config.clone_fd = clone_fd;
4485 config.max_idle_threads = 10;
4486 return fuse_loop_mt_32(f, &config);
4487 }
4488
4489 void fuse_exit(struct fuse *f)
4490 {
4491 fuse_session_exit(f->se);
4492 }
4493
4494 struct fuse_context *fuse_get_context(void)
4495 {
4496 struct fuse_context_i *c = fuse_get_context_internal();
4497
4498 if (c)
4499 return &c->ctx;
4500 else
4501 return NULL;
4502 }
4503
4504 int fuse_getgroups(int size, gid_t list[])
4505 {
4506 struct fuse_context_i *c = fuse_get_context_internal();
4507 if (!c)
4508 return -EINVAL;
4509
4510 return fuse_req_getgroups(c->req, size, list);
4511 }
4512
4513 int fuse_interrupted(void)
4514 {
4515 struct fuse_context_i *c = fuse_get_context_internal();
4516
4517 if (c)
4518 return fuse_req_interrupted(c->req);
4519 else
4520 return 0;
4521 }
4522
4523 int fuse_invalidate_path(struct fuse *f, const char *path) {
4524 fuse_ino_t ino;
4525 int err = lookup_path_in_cache(f, path, &ino);
4526 if (err) {
4527 return err;
4528 }
4529
4530 return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
4531 }
4532
4533 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4534
4535 static const struct fuse_opt fuse_lib_opts[] = {
4536 FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
4537 FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
4538 FUSE_LIB_OPT("debug", debug, 1),
4539 FUSE_LIB_OPT("-d", debug, 1),
4540 FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
4541 FUSE_LIB_OPT("auto_cache", auto_cache, 1),
4542 FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
4543 FUSE_LIB_OPT("umask=", set_mode, 1),
4544 FUSE_LIB_OPT("umask=%o", umask, 0),
4545 FUSE_LIB_OPT("uid=", set_uid, 1),
4546 FUSE_LIB_OPT("uid=%d", uid, 0),
4547 FUSE_LIB_OPT("gid=", set_gid, 1),
4548 FUSE_LIB_OPT("gid=%d", gid, 0),
4549 FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
4550 FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
4551 FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
4552 FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
4553 FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
4554 FUSE_LIB_OPT("noforget", remember, -1),
4555 FUSE_LIB_OPT("remember=%u", remember, 0),
4556 FUSE_LIB_OPT("modules=%s", modules, 0),
4557 FUSE_OPT_END
4558 };
4559
4560 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4561 struct fuse_args *outargs)
4562 {
4563 (void) arg; (void) outargs; (void) data; (void) key;
4564
4565 /* Pass through unknown options */
4566 return 1;
4567 }
4568
4569
4570 static const struct fuse_opt fuse_help_opts[] = {
4571 FUSE_LIB_OPT("modules=%s", modules, 1),
4572 FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP),
4573 FUSE_OPT_END
4574 };
4575
4576 static void print_module_help(const char *name,
4577 fuse_module_factory_t *fac)
4578 {
4579 struct fuse_args a = FUSE_ARGS_INIT(0, NULL);
4580 if (fuse_opt_add_arg(&a, "") == -1 ||
4581 fuse_opt_add_arg(&a, "-h") == -1)
4582 return;
4583 printf("\nOptions for %s module:\n", name);
4584 (*fac)(&a, NULL);
4585 }
4586
4587 void fuse_lib_help(struct fuse_args *args)
4588 {
4589 /* These are not all options, but only the ones that
4590 may be of interest to an end-user */
4591 printf(
4592 " -o kernel_cache cache files in kernel\n"
4593 " -o [no]auto_cache enable caching based on modification times (off)\n"
4594 " -o umask=M set file permissions (octal)\n"
4595 " -o uid=N set file owner\n"
4596 " -o gid=N set file group\n"
4597 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4598 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4599 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4600 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4601 " -o noforget never forget cached inodes\n"
4602 " -o remember=T remember cached inodes for T seconds (0s)\n"
4603 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4604
4605
4606 /* Print low-level help */
4607 fuse_lowlevel_help();
4608
4609 /* Print help for builtin modules */
4610 print_module_help("subdir", &fuse_module_subdir_factory);
4611 #ifdef HAVE_ICONV
4612 print_module_help("iconv", &fuse_module_iconv_factory);
4613 #endif
4614
4615 /* Parse command line options in case we need to
4616 activate more modules */
4617 struct fuse_config conf = { .modules = NULL };
4618 if (fuse_opt_parse(args, &conf, fuse_help_opts,
4619 fuse_lib_opt_proc) == -1
4620 || !conf.modules)
4621 return;
4622
4623 char *module;
4624 char *next;
4625 struct fuse_module *m;
4626
4627 // Iterate over all modules
4628 for (module = conf.modules; module; module = next) {
4629 char *p;
4630 for (p = module; *p && *p != ':'; p++);
4631 next = *p ? p + 1 : NULL;
4632 *p = '\0';
4633
4634 m = fuse_get_module(module);
4635 if (m)
4636 print_module_help(module, &m->factory);
4637 }
4638 }
4639
4640
4641
4642 static int fuse_init_intr_signal(int signum, int *installed)
4643 {
4644 struct sigaction old_sa;
4645
4646 if (sigaction(signum, NULL, &old_sa) == -1) {
4647 perror("fuse: cannot get old signal handler");
4648 return -1;
4649 }
4650
4651 if (old_sa.sa_handler == SIG_DFL) {
4652 struct sigaction sa;
4653
4654 memset(&sa, 0, sizeof(struct sigaction));
4655 sa.sa_handler = fuse_intr_sighandler;
4656 sigemptyset(&sa.sa_mask);
4657
4658 if (sigaction(signum, &sa, NULL) == -1) {
4659 perror("fuse: cannot set interrupt signal handler");
4660 return -1;
4661 }
4662 *installed = 1;
4663 }
4664 return 0;
4665 }
4666
4667 static void fuse_restore_intr_signal(int signum)
4668 {
4669 struct sigaction sa;
4670
4671 memset(&sa, 0, sizeof(struct sigaction));
4672 sa.sa_handler = SIG_DFL;
4673 sigaction(signum, &sa, NULL);
4674 }
4675
4676
4677 static int fuse_push_module(struct fuse *f, const char *module,
4678 struct fuse_args *args)
4679 {
4680 struct fuse_fs *fs[2] = { f->fs, NULL };
4681 struct fuse_fs *newfs;
4682 struct fuse_module *m = fuse_get_module(module);
4683
4684 if (!m)
4685 return -1;
4686
4687 newfs = m->factory(args, fs);
4688 if (!newfs) {
4689 fuse_put_module(m);
4690 return -1;
4691 }
4692 newfs->m = m;
4693 f->fs = newfs;
4694 return 0;
4695 }
4696
4697 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4698 void *user_data)
4699 {
4700 struct fuse_fs *fs;
4701
4702 if (sizeof(struct fuse_operations) < op_size) {
4703 fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
4704 op_size = sizeof(struct fuse_operations);
4705 }
4706
4707 fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4708 if (!fs) {
4709 fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
4710 return NULL;
4711 }
4712
4713 fs->user_data = user_data;
4714 if (op)
4715 memcpy(&fs->op, op, op_size);
4716 return fs;
4717 }
4718
4719 static int node_table_init(struct node_table *t)
4720 {
4721 t->size = NODE_TABLE_MIN_SIZE;
4722 t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4723 if (t->array == NULL) {
4724 fprintf(stderr, "fuse: memory allocation failed\n");
4725 return -1;
4726 }
4727 t->use = 0;
4728 t->split = 0;
4729
4730 return 0;
4731 }
4732
4733 static void *fuse_prune_nodes(void *fuse)
4734 {
4735 struct fuse *f = fuse;
4736 int sleep_time;
4737
4738 while(1) {
4739 sleep_time = fuse_clean_cache(f);
4740 sleep(sleep_time);
4741 }
4742 return NULL;
4743 }
4744
4745 int fuse_start_cleanup_thread(struct fuse *f)
4746 {
4747 if (lru_enabled(f))
4748 return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4749
4750 return 0;
4751 }
4752
4753 void fuse_stop_cleanup_thread(struct fuse *f)
4754 {
4755 if (lru_enabled(f)) {
4756 pthread_mutex_lock(&f->lock);
4757 pthread_cancel(f->prune_thread);
4758 pthread_mutex_unlock(&f->lock);
4759 pthread_join(f->prune_thread, NULL);
4760 }
4761 }
4762
4763
4764 FUSE_SYMVER(".symver fuse_new_31,fuse_new@@FUSE_3.1");
4765 struct fuse *fuse_new_31(struct fuse_args *args,
4766 const struct fuse_operations *op,
4767 size_t op_size, void *user_data)
4768 {
4769 struct fuse *f;
4770 struct node *root;
4771 struct fuse_fs *fs;
4772 struct fuse_lowlevel_ops llop = fuse_path_ops;
4773
4774 f = (struct fuse *) calloc(1, sizeof(struct fuse));
4775 if (f == NULL) {
4776 fprintf(stderr, "fuse: failed to allocate fuse object\n");
4777 goto out;
4778 }
4779
4780 f->conf.entry_timeout = 1.0;
4781 f->conf.attr_timeout = 1.0;
4782 f->conf.negative_timeout = 0.0;
4783 f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4784
4785 /* Parse options */
4786 if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4787 fuse_lib_opt_proc) == -1)
4788 goto out_free;
4789
4790 pthread_mutex_lock(&fuse_context_lock);
4791 static int builtin_modules_registered = 0;
4792 /* Have the builtin modules already been registered? */
4793 if (builtin_modules_registered == 0) {
4794 /* If not, register them. */
4795 fuse_register_module("subdir", fuse_module_subdir_factory, NULL);
4796 #ifdef HAVE_ICONV
4797 fuse_register_module("iconv", fuse_module_iconv_factory, NULL);
4798 #endif
4799 builtin_modules_registered= 1;
4800 }
4801 pthread_mutex_unlock(&fuse_context_lock);
4802
4803 if (fuse_create_context_key() == -1)
4804 goto out_free;
4805
4806 fs = fuse_fs_new(op, op_size, user_data);
4807 if (!fs)
4808 goto out_delete_context_key;
4809
4810 f->fs = fs;
4811
4812 /* Oh f**k, this is ugly! */
4813 if (!fs->op.lock) {
4814 llop.getlk = NULL;
4815 llop.setlk = NULL;
4816 }
4817
4818 f->pagesize = getpagesize();
4819 init_list_head(&f->partial_slabs);
4820 init_list_head(&f->full_slabs);
4821 init_list_head(&f->lru_table);
4822
4823 if (f->conf.modules) {
4824 char *module;
4825 char *next;
4826
4827 for (module = f->conf.modules; module; module = next) {
4828 char *p;
4829 for (p = module; *p && *p != ':'; p++);
4830 next = *p ? p + 1 : NULL;
4831 *p = '\0';
4832 if (module[0] &&
4833 fuse_push_module(f, module, args) == -1)
4834 goto out_free_fs;
4835 }
4836 }
4837
4838 if (!f->conf.ac_attr_timeout_set)
4839 f->conf.ac_attr_timeout = f->conf.attr_timeout;
4840
4841 #if defined(__FreeBSD__) || defined(__NetBSD__)
4842 /*
4843 * In FreeBSD, we always use these settings as inode numbers
4844 * are needed to make getcwd(3) work.
4845 */
4846 f->conf.readdir_ino = 1;
4847 #endif
4848
4849 f->se = fuse_session_new(args, &llop, sizeof(llop), f);
4850 if (f->se == NULL)
4851 goto out_free_fs;
4852
4853 if (f->conf.debug) {
4854 fprintf(stderr, "nullpath_ok: %i\n", f->conf.nullpath_ok);
4855 }
4856
4857 /* Trace topmost layer by default */
4858 f->fs->debug = f->conf.debug;
4859 f->ctr = 0;
4860 f->generation = 0;
4861 if (node_table_init(&f->name_table) == -1)
4862 goto out_free_session;
4863
4864 if (node_table_init(&f->id_table) == -1)
4865 goto out_free_name_table;
4866
4867 fuse_mutex_init(&f->lock);
4868
4869 root = alloc_node(f);
4870 if (root == NULL) {
4871 fprintf(stderr, "fuse: memory allocation failed\n");
4872 goto out_free_id_table;
4873 }
4874 if (lru_enabled(f)) {
4875 struct node_lru *lnode = node_lru(root);
4876 init_list_head(&lnode->lru);
4877 }
4878
4879 strcpy(root->inline_name, "/");
4880 root->name = root->inline_name;
4881
4882 if (f->conf.intr &&
4883 fuse_init_intr_signal(f->conf.intr_signal,
4884 &f->intr_installed) == -1)
4885 goto out_free_root;
4886
4887 root->parent = NULL;
4888 root->nodeid = FUSE_ROOT_ID;
4889 inc_nlookup(root);
4890 hash_id(f, root);
4891
4892 return f;
4893
4894 out_free_root:
4895 free(root);
4896 out_free_id_table:
4897 free(f->id_table.array);
4898 out_free_name_table:
4899 free(f->name_table.array);
4900 out_free_session:
4901 fuse_session_destroy(f->se);
4902 out_free_fs:
4903 if (f->fs->m)
4904 fuse_put_module(f->fs->m);
4905 free(f->fs);
4906 free(f->conf.modules);
4907 out_delete_context_key:
4908 fuse_delete_context_key();
4909 out_free:
4910 free(f);
4911 out:
4912 return NULL;
4913 }
4914
4915 /* Emulates 3.0-style fuse_new(), which processes --help */
4916 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
4917 size_t op_size, void *private_data);
4918 FUSE_SYMVER(".symver fuse_new_30,fuse_new@FUSE_3.0");
4919 struct fuse *fuse_new_30(struct fuse_args *args,
4920 const struct fuse_operations *op,
4921 size_t op_size, void *user_data)
4922 {
4923 struct fuse_config conf;
4924
4925 memset(&conf, 0, sizeof(conf));
4926
4927 const struct fuse_opt opts[] = {
4928 FUSE_LIB_OPT("-h", show_help, 1),
4929 FUSE_LIB_OPT("--help", show_help, 1),
4930 FUSE_OPT_END
4931 };
4932
4933 if (fuse_opt_parse(args, &conf, opts,
4934 fuse_lib_opt_proc) == -1)
4935 return NULL;
4936
4937 if (conf.show_help) {
4938 fuse_lib_help(args);
4939 return NULL;
4940 } else
4941 return fuse_new_31(args, op, op_size, user_data);
4942 }
4943
4944 void fuse_destroy(struct fuse *f)
4945 {
4946 size_t i;
4947
4948 if (f->conf.intr && f->intr_installed)
4949 fuse_restore_intr_signal(f->conf.intr_signal);
4950
4951 if (f->fs) {
4952 fuse_create_context(f);
4953
4954 for (i = 0; i < f->id_table.size; i++) {
4955 struct node *node;
4956
4957 for (node = f->id_table.array[i]; node != NULL;
4958 node = node->id_next) {
4959 if (node->is_hidden) {
4960 char *path;
4961 if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
4962 fuse_fs_unlink(f->fs, path);
4963 free(path);
4964 }
4965 }
4966 }
4967 }
4968 }
4969 for (i = 0; i < f->id_table.size; i++) {
4970 struct node *node;
4971 struct node *next;
4972
4973 for (node = f->id_table.array[i]; node != NULL; node = next) {
4974 next = node->id_next;
4975 free_node(f, node);
4976 f->id_table.use--;
4977 }
4978 }
4979 assert(list_empty(&f->partial_slabs));
4980 assert(list_empty(&f->full_slabs));
4981
4982 while (fuse_modules) {
4983 fuse_put_module(fuse_modules);
4984 }
4985 free(f->id_table.array);
4986 free(f->name_table.array);
4987 pthread_mutex_destroy(&f->lock);
4988 fuse_session_destroy(f->se);
4989 free(f->conf.modules);
4990 free(f);
4991 fuse_delete_context_key();
4992 }
4993
4994 int fuse_mount(struct fuse *f, const char *mountpoint) {
4995 return fuse_session_mount(fuse_get_session(f), mountpoint);
4996 }
4997
4998
4999 void fuse_unmount(struct fuse *f) {
5000 return fuse_session_unmount(fuse_get_session(f));
5001 }
5002
5003 int fuse_version(void)
5004 {
5005 return FUSE_VERSION;
5006 }
5007
5008 const char *fuse_pkgversion(void)
5009 {
5010 return PACKAGE_VERSION;
5011 }
fuse_bufvec::off
size_t off
Definition: fuse_common.h:668
fuse_conn_info::capable
unsigned capable
Definition: fuse_common.h:370
fuse_file_info::fh
uint64_t fh
Definition: fuse_common.h:72
fuse_conn_info
Definition: fuse_common.h:332
fuse_file_info::writepage
unsigned int writepage
Definition: fuse_common.h:43
fuse_reply_write
int fuse_reply_write(fuse_req_t req, size_t count)
Definition: fuse_lowlevel.c:459
fuse_loop_mt_31
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
Definition: fuse.c:4402
fuse_file_info::direct_io
unsigned int direct_io
Definition: fuse_common.h:46
FUSE_BUF_SPLICE_MOVE
Definition: fuse_common.h:595
fuse_file_info::poll_events
uint32_t poll_events
Definition: fuse_common.h:79
fuse_session_reset
void fuse_session_reset(struct fuse_session *se)
Definition: fuse_lowlevel.c:2998
fuse_req_t
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
fuse_fill_dir_t
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
fuse_ino_t
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
fuse_loop_config::max_idle_threads
unsigned int max_idle_threads
Definition: fuse_common.h:103
fuse_ctx::umask
mode_t umask
Definition: fuse_lowlevel.h:125
fuse_exit
void fuse_exit(struct fuse *f)
Definition: fuse.c:4410
FUSE_CAP_POSIX_LOCKS
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:128
fuse_req_ctx
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
Definition: fuse_lowlevel.c:2320
FUSE_READDIR_PLUS
Definition: fuse.h:51
fuse_readdir_flags
fuse_readdir_flags
Definition: fuse.h:42
fuse_entry_param::attr
struct stat attr
Definition: fuse_lowlevel.h:91
fuse_ctx::pid
pid_t pid
Definition: fuse_lowlevel.h:122
fuse_pkgversion
const char * fuse_pkgversion(void)
Definition: fuse.c:4926
fuse_session_unmount
void fuse_session_unmount(struct fuse_session *se)
Definition: fuse_lowlevel.c:2916
fuse_file_info::keep_cache
unsigned int keep_cache
Definition: fuse_common.h:51
FUSE_CAP_SPLICE_READ
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:177
fuse_entry_param
Definition: fuse_lowlevel.h:59
fuse_add_direntry_plus
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
Definition: fuse_lowlevel.c:356
fuse_entry_param::ino
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
fuse_file_info::lock_owner
uint64_t lock_owner
Definition: fuse_common.h:75
fuse_reply_data
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
Definition: fuse_lowlevel.c:819
fuse_reply_ioctl
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
Definition: fuse_lowlevel.c:978
fuse_session_loop
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
fuse_getgroups
int fuse_getgroups(int size, gid_t list[])
Definition: fuse.c:4425
fuse_reply_entry
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
Definition: fuse_lowlevel.c:398
fuse_session_mount
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
Definition: fuse_lowlevel.c:2879
fuse_version
int fuse_version(void)
Definition: fuse.c:4921
FUSE_CAP_FLOCK_LOCKS
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:190
fuse_reply_statfs
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
Definition: fuse_lowlevel.c:841
fuse_file_info
Definition: fuse_common.h:37
fuse_module_factory_t
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
Definition: fuse.h:1195
fuse_buf_size
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
fuse_ctx::uid
uid_t uid
Definition: fuse_lowlevel.h:116
fuse_lowlevel_help
void fuse_lowlevel_help(void)
Definition: fuse_lowlevel.c:2587
fuse_buf_copy
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:281
fuse_req_interrupted
int fuse_req_interrupted(fuse_req_t req)
Definition: fuse_lowlevel.c:2338
fuse_reply_poll
int fuse_reply_poll(fuse_req_t req, unsigned revents)
Definition: fuse_lowlevel.c:1023
fuse_operations
Definition: fuse.h:299
fuse_start_cleanup_thread
int fuse_start_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4666
fuse_invalidate_path
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4444
fuse_file_info::flags
int flags
Definition: fuse_common.h:39
fuse_bufvec
Definition: fuse_common.h:654
fuse_loop_config
Definition: fuse_common.h:86
FUSE_ARGS_INIT
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
fuse_bufvec::idx
size_t idx
Definition: fuse_common.h:663
fuse_ctx
Definition: fuse_lowlevel.h:114
fuse_reply_err
int fuse_reply_err(fuse_req_t req, int err)
Definition: fuse_lowlevel.c:311
fuse_bufvec::count
size_t count
Definition: fuse_common.h:658
fuse_req_userdata
void * fuse_req_userdata(fuse_req_t req)
Definition: fuse_lowlevel.c:2315
fuse_buf::flags
enum fuse_buf_flags flags
Definition: fuse_common.h:622
fuse_lib_help
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4508
fuse_reply_none
void fuse_reply_none(fuse_req_t req)
Definition: fuse_lowlevel.c:316
fuse_file_info::flush
unsigned int flush
Definition: fuse_common.h:56
fuse_session_exited
int fuse_session_exited(struct fuse_session *se)
Definition: fuse_lowlevel.c:3004
fuse_lowlevel_ops::getlk
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
Definition: fuse_lowlevel.h:922
fuse_opt_add_arg
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
fuse_session_destroy
void fuse_session_destroy(struct fuse_session *se)
Definition: fuse_lowlevel.c:2597
fuse_reply_open
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
Definition: fuse_lowlevel.c:450
fuse_module
Definition: fuse_i.h:82
fuse_session_exit
void fuse_session_exit(struct fuse_session *se)
Definition: fuse_lowlevel.c:2993
fuse_reply_readlink
int fuse_reply_readlink(fuse_req_t req, const char *link)
Definition: fuse_lowlevel.c:445
fuse_reply_attr
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
Definition: fuse_lowlevel.c:430
fuse_fs_new
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4618
fuse_lowlevel_ops::setlk
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
Definition: fuse_lowlevel.h:947
fuse_config::show_help
int show_help
Definition: fuse.h:271
fuse_entry_param::generation
uint64_t generation
Definition: fuse_lowlevel.h:82
fuse_destroy
void fuse_destroy(struct fuse *f)
Definition: fuse.c:4865
fuse_req_interrupt_func
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
Definition: fuse_lowlevel.c:2325
fuse_stop_cleanup_thread
void fuse_stop_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4674
fuse_config
Definition: fuse.h:93
fuse_req_getgroups
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
Definition: fuse_lowlevel.c:2986
fuse_clean_cache
int fuse_clean_cache(struct fuse *fuse)
Definition: fuse.c:4232
fuse_reply_lock
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
Definition: fuse_lowlevel.c:863
fuse_lowlevel_ops
Definition: fuse_lowlevel.h:175
fuse_reply_create
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
Definition: fuse_lowlevel.c:414
fuse_get_session
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4317
fuse_loop
int fuse_loop(struct fuse *f)
Definition: fuse.c:4374
fuse_context
Definition: fuse.h:760
fuse_opt
Definition: fuse_opt.h:77
fuse_ctx::gid
gid_t gid
Definition: fuse_lowlevel.h:119
fuse_get_context
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4415
fuse_session_new
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
Definition: fuse_lowlevel.c:2785
FUSE_OPT_KEY
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
fuse_conn_info::want
unsigned want
Definition: fuse_common.h:378
fuse_buf::mem
void * mem
Definition: fuse_common.h:629
fuse_bufvec::buf
struct fuse_buf buf[1]
Definition: fuse_common.h:673
fuse_args
Definition: fuse_opt.h:109
fuse_interrupted
int fuse_interrupted(void)
Definition: fuse.c:4434
fuse_lowlevel_notify_inval_inode
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
Definition: fuse_lowlevel.c:2118
FUSE_OPT_KEY_KEEP
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
fuse_mount
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:4912
FUSE_FILL_DIR_PLUS
Definition: fuse.h:64
fuse_fill_dir_flags
fuse_fill_dir_flags
Definition: fuse.h:54
fuse_buf::size
size_t size
Definition: fuse_common.h:617
FUSE_BUF_IS_FD
Definition: fuse_common.h:544
fuse_entry_param::entry_timeout
double entry_timeout
Definition: fuse_lowlevel.h:103
FUSE_CAP_EXPORT_SUPPORT
#define FUSE_CAP_EXPORT_SUPPORT
Definition: fuse_common.h:144
fuse_reply_bmap
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
Definition: fuse_lowlevel.c:880
fuse_entry_param::attr_timeout
double attr_timeout
Definition: fuse_lowlevel.h:97
FUSE_OPT_END
#define FUSE_OPT_END
Definition: fuse_opt.h:104
fuse_lowlevel_notify_poll
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
Definition: fuse_lowlevel.c:2101
fuse_loop_config::clone_fd
int clone_fd
Definition: fuse_common.h:91
fuse_context::private_data
void * private_data
Definition: fuse.h:774
fuse_lowlevel_ops::init
void(* init)(void *userdata, struct fuse_conn_info *conn)
Definition: fuse_lowlevel.h:192
fuse_buf
Definition: fuse_common.h:613
fuse_unmount
void fuse_unmount(struct fuse *f)
Definition: fuse.c:4917
fuse_opt_parse
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
fuse_reply_buf
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
Definition: fuse_lowlevel.c:469
FUSE_ROOT_ID
#define FUSE_ROOT_ID
Definition: fuse_lowlevel.h:43
fuse_add_direntry
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
Definition: fuse_lowlevel.c:266
fuse_reply_xattr
int fuse_reply_xattr(fuse_req_t req, size_t count)
Definition: fuse_lowlevel.c:853