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