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