Fix nodeid format strings
[fuse.git] / lib / fuse.c
blob5dd5c0957c415ab8aefd10761e2b81aa4c4b93ca
1 /*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU LGPLv2.
6 See the file COPYING.LIB
7 */
10 /* For pthread_rwlock_t */
11 #define _GNU_SOURCE
13 #include "config.h"
14 #include "fuse_i.h"
15 #include "fuse_lowlevel.h"
16 #include "fuse_opt.h"
17 #include "fuse_misc.h"
18 #include "fuse_kernel.h"
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <stddef.h>
24 #include <stdbool.h>
25 #include <unistd.h>
26 #include <time.h>
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <errno.h>
30 #include <signal.h>
31 #include <dlfcn.h>
32 #include <assert.h>
33 #include <poll.h>
34 #include <sys/param.h>
35 #include <sys/uio.h>
36 #include <sys/time.h>
37 #include <sys/mman.h>
39 #define FUSE_NODE_SLAB 1
41 #ifndef MAP_ANONYMOUS
42 #undef FUSE_NODE_SLAB
43 #endif
45 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
47 #define FUSE_UNKNOWN_INO 0xffffffff
48 #define OFFSET_MAX 0x7fffffffffffffffLL
50 #define NODE_TABLE_MIN_SIZE 8192
52 struct fuse_config {
53 unsigned int uid;
54 unsigned int gid;
55 unsigned int umask;
56 double entry_timeout;
57 double negative_timeout;
58 double attr_timeout;
59 double ac_attr_timeout;
60 int ac_attr_timeout_set;
61 int remember;
62 int nopath;
63 int debug;
64 int hard_remove;
65 int use_ino;
66 int readdir_ino;
67 int set_mode;
68 int set_uid;
69 int set_gid;
70 int direct_io;
71 int kernel_cache;
72 int auto_cache;
73 int intr;
74 int intr_signal;
75 int help;
76 char *modules;
79 struct fuse_fs {
80 struct fuse_operations op;
81 struct fuse_module *m;
82 void *user_data;
83 int debug;
86 struct fusemod_so {
87 void *handle;
88 int ctr;
91 struct lock_queue_element {
92 struct lock_queue_element *next;
93 pthread_cond_t cond;
94 fuse_ino_t nodeid1;
95 const char *name1;
96 char **path1;
97 struct node **wnode1;
98 fuse_ino_t nodeid2;
99 const char *name2;
100 char **path2;
101 struct node **wnode2;
102 int err;
103 bool first_locked : 1;
104 bool second_locked : 1;
105 bool done : 1;
108 struct node_table {
109 struct node **array;
110 size_t use;
111 size_t size;
112 size_t split;
115 #define container_of(ptr, type, member) ({ \
116 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
117 (type *)( (char *)__mptr - offsetof(type,member) );})
119 #define list_entry(ptr, type, member) \
120 container_of(ptr, type, member)
122 struct list_head {
123 struct list_head *next;
124 struct list_head *prev;
127 struct node_slab {
128 struct list_head list; /* must be the first member */
129 struct list_head freelist;
130 int used;
133 struct fuse {
134 struct fuse_session *se;
135 struct node_table name_table;
136 struct node_table id_table;
137 struct list_head lru_table;
138 fuse_ino_t ctr;
139 unsigned int generation;
140 unsigned int hidectr;
141 pthread_mutex_t lock;
142 struct fuse_config conf;
143 int intr_installed;
144 struct fuse_fs *fs;
145 struct lock_queue_element *lockq;
146 int pagesize;
147 struct list_head partial_slabs;
148 struct list_head full_slabs;
149 pthread_t prune_thread;
152 struct lock {
153 int type;
154 off_t start;
155 off_t end;
156 pid_t pid;
157 uint64_t owner;
158 struct lock *next;
161 struct node {
162 struct node *name_next;
163 struct node *id_next;
164 fuse_ino_t nodeid;
165 unsigned int generation;
166 int refctr;
167 struct node *parent;
168 char *name;
169 uint64_t nlookup;
170 int open_count;
171 struct timespec stat_updated;
172 struct timespec mtime;
173 off_t size;
174 struct lock *locks;
175 unsigned int is_hidden : 1;
176 unsigned int cache_valid : 1;
177 int treelock;
178 char inline_name[32];
181 #define TREELOCK_WRITE -1
182 #define TREELOCK_WAIT_OFFSET INT_MIN
184 struct node_lru {
185 struct node node;
186 struct list_head lru;
187 struct timespec forget_time;
190 struct fuse_dh {
191 pthread_mutex_t lock;
192 struct fuse *fuse;
193 fuse_req_t req;
194 char *contents;
195 int allocated;
196 unsigned len;
197 unsigned size;
198 unsigned needlen;
199 int filled;
200 uint64_t fh;
201 int error;
202 fuse_ino_t nodeid;
205 struct fuse_context_i {
206 struct fuse_context ctx;
207 fuse_req_t req;
210 static pthread_key_t fuse_context_key;
211 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
212 static int fuse_context_ref;
213 static struct fusemod_so *fuse_current_so;
214 static struct fuse_module *fuse_modules;
216 static int fuse_load_so_name(const char *soname)
218 struct fusemod_so *so;
220 so = calloc(1, sizeof(struct fusemod_so));
221 if (!so) {
222 fprintf(stderr, "fuse: memory allocation failed\n");
223 return -1;
226 fuse_current_so = so;
227 so->handle = dlopen(soname, RTLD_NOW);
228 fuse_current_so = NULL;
229 if (!so->handle) {
230 fprintf(stderr, "fuse: %s\n", dlerror());
231 goto err;
233 if (!so->ctr) {
234 fprintf(stderr, "fuse: %s did not register any modules\n",
235 soname);
236 goto err;
238 return 0;
240 err:
241 if (so->handle)
242 dlclose(so->handle);
243 free(so);
244 return -1;
247 static int fuse_load_so_module(const char *module)
249 int res;
250 char *soname = malloc(strlen(module) + 64);
251 if (!soname) {
252 fprintf(stderr, "fuse: memory allocation failed\n");
253 return -1;
255 sprintf(soname, "libfusemod_%s.so", module);
256 res = fuse_load_so_name(soname);
257 free(soname);
258 return res;
261 static struct fuse_module *fuse_find_module(const char *module)
263 struct fuse_module *m;
264 for (m = fuse_modules; m; m = m->next) {
265 if (strcmp(module, m->name) == 0) {
266 m->ctr++;
267 break;
270 return m;
273 static struct fuse_module *fuse_get_module(const char *module)
275 struct fuse_module *m;
277 pthread_mutex_lock(&fuse_context_lock);
278 m = fuse_find_module(module);
279 if (!m) {
280 int err = fuse_load_so_module(module);
281 if (!err)
282 m = fuse_find_module(module);
284 pthread_mutex_unlock(&fuse_context_lock);
285 return m;
288 static void fuse_put_module(struct fuse_module *m)
290 pthread_mutex_lock(&fuse_context_lock);
291 assert(m->ctr > 0);
292 m->ctr--;
293 if (!m->ctr && m->so) {
294 struct fusemod_so *so = m->so;
295 assert(so->ctr > 0);
296 so->ctr--;
297 if (!so->ctr) {
298 struct fuse_module **mp;
299 for (mp = &fuse_modules; *mp;) {
300 if ((*mp)->so == so)
301 *mp = (*mp)->next;
302 else
303 mp = &(*mp)->next;
305 dlclose(so->handle);
306 free(so);
309 pthread_mutex_unlock(&fuse_context_lock);
312 static void init_list_head(struct list_head *list)
314 list->next = list;
315 list->prev = list;
318 static int list_empty(const struct list_head *head)
320 return head->next == head;
323 static void list_add(struct list_head *new, struct list_head *prev,
324 struct list_head *next)
326 next->prev = new;
327 new->next = next;
328 new->prev = prev;
329 prev->next = new;
332 static inline void list_add_head(struct list_head *new, struct list_head *head)
334 list_add(new, head, head->next);
337 static inline void list_add_tail(struct list_head *new, struct list_head *head)
339 list_add(new, head->prev, head);
342 static inline void list_del(struct list_head *entry)
344 struct list_head *prev = entry->prev;
345 struct list_head *next = entry->next;
347 next->prev = prev;
348 prev->next = next;
351 static inline int lru_enabled(struct fuse *f)
353 return f->conf.remember > 0;
356 static struct node_lru *node_lru(struct node *node)
358 return (struct node_lru *) node;
361 static size_t get_node_size(struct fuse *f)
363 if (lru_enabled(f))
364 return sizeof(struct node_lru);
365 else
366 return sizeof(struct node);
369 #ifdef FUSE_NODE_SLAB
370 static struct node_slab *list_to_slab(struct list_head *head)
372 return (struct node_slab *) head;
375 static struct node_slab *node_to_slab(struct fuse *f, struct node *node)
377 return (struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
380 static int alloc_slab(struct fuse *f)
382 void *mem;
383 struct node_slab *slab;
384 char *start;
385 size_t num;
386 size_t i;
387 size_t node_size = get_node_size(f);
389 mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
390 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
392 if (mem == MAP_FAILED)
393 return -1;
395 slab = mem;
396 init_list_head(&slab->freelist);
397 slab->used = 0;
398 num = (f->pagesize - sizeof(struct node_slab)) / node_size;
400 start = (char *) mem + f->pagesize - num * node_size;
401 for (i = 0; i < num; i++) {
402 struct list_head *n;
404 n = (struct list_head *) (start + i * node_size);
405 list_add_tail(n, &slab->freelist);
407 list_add_tail(&slab->list, &f->partial_slabs);
409 return 0;
412 static struct node *alloc_node(struct fuse *f)
414 struct node_slab *slab;
415 struct list_head *node;
417 if (list_empty(&f->partial_slabs)) {
418 int res = alloc_slab(f);
419 if (res != 0)
420 return NULL;
422 slab = list_to_slab(f->partial_slabs.next);
423 slab->used++;
424 node = slab->freelist.next;
425 list_del(node);
426 if (list_empty(&slab->freelist)) {
427 list_del(&slab->list);
428 list_add_tail(&slab->list, &f->full_slabs);
430 memset(node, 0, sizeof(struct node));
432 return (struct node *) node;
435 static void free_slab(struct fuse *f, struct node_slab *slab)
437 int res;
439 list_del(&slab->list);
440 res = munmap(slab, f->pagesize);
441 if (res == -1)
442 fprintf(stderr, "fuse warning: munmap(%p) failed\n", slab);
445 static void free_node_mem(struct fuse *f, struct node *node)
447 struct node_slab *slab = node_to_slab(f, node);
448 struct list_head *n = (struct list_head *) node;
450 slab->used--;
451 if (slab->used) {
452 if (list_empty(&slab->freelist)) {
453 list_del(&slab->list);
454 list_add_tail(&slab->list, &f->partial_slabs);
456 list_add_head(n, &slab->freelist);
457 } else {
458 free_slab(f, slab);
461 #else
462 static struct node *alloc_node(struct fuse *f)
464 return (struct node *) calloc(1, get_node_size(f));
467 static void free_node_mem(struct fuse *f, struct node *node)
469 (void) f;
470 free(node);
472 #endif
474 static size_t id_hash(struct fuse *f, fuse_ino_t ino)
476 uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
477 uint64_t oldhash = hash % (f->id_table.size / 2);
479 if (oldhash >= f->id_table.split)
480 return oldhash;
481 else
482 return hash;
485 static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
487 size_t hash = id_hash(f, nodeid);
488 struct node *node;
490 for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
491 if (node->nodeid == nodeid)
492 return node;
494 return NULL;
497 static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
499 struct node *node = get_node_nocheck(f, nodeid);
500 if (!node) {
501 fprintf(stderr, "fuse internal error: node %llu not found\n",
502 (unsigned long long) nodeid);
503 abort();
505 return node;
508 static void curr_time(struct timespec *now);
509 static double diff_timespec(const struct timespec *t1,
510 const struct timespec *t2);
512 static void remove_node_lru(struct node *node)
514 struct node_lru *lnode = node_lru(node);
515 list_del(&lnode->lru);
516 init_list_head(&lnode->lru);
519 static void set_forget_time(struct fuse *f, struct node *node)
521 struct node_lru *lnode = node_lru(node);
523 list_del(&lnode->lru);
524 list_add_tail(&lnode->lru, &f->lru_table);
525 curr_time(&lnode->forget_time);
528 static void free_node(struct fuse *f, struct node *node)
530 if (node->name != node->inline_name)
531 free(node->name);
532 free_node_mem(f, node);
535 static void node_table_reduce(struct node_table *t)
537 size_t newsize = t->size / 2;
538 void *newarray;
540 if (newsize < NODE_TABLE_MIN_SIZE)
541 return;
543 newarray = realloc(t->array, sizeof(struct node *) * newsize);
544 if (newarray != NULL)
545 t->array = newarray;
547 t->size = newsize;
548 t->split = t->size / 2;
551 static void remerge_id(struct fuse *f)
553 struct node_table *t = &f->id_table;
554 int iter;
556 if (t->split == 0)
557 node_table_reduce(t);
559 for (iter = 8; t->split > 0 && iter; iter--) {
560 struct node **upper;
562 t->split--;
563 upper = &t->array[t->split + t->size / 2];
564 if (*upper) {
565 struct node **nodep;
567 for (nodep = &t->array[t->split]; *nodep;
568 nodep = &(*nodep)->id_next);
570 *nodep = *upper;
571 *upper = NULL;
572 break;
577 static void unhash_id(struct fuse *f, struct node *node)
579 struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
581 for (; *nodep != NULL; nodep = &(*nodep)->id_next)
582 if (*nodep == node) {
583 *nodep = node->id_next;
584 f->id_table.use--;
586 if(f->id_table.use < f->id_table.size / 4)
587 remerge_id(f);
588 return;
592 static int node_table_resize(struct node_table *t)
594 size_t newsize = t->size * 2;
595 void *newarray;
597 newarray = realloc(t->array, sizeof(struct node *) * newsize);
598 if (newarray == NULL)
599 return -1;
601 t->array = newarray;
602 memset(t->array + t->size, 0, t->size * sizeof(struct node *));
603 t->size = newsize;
604 t->split = 0;
606 return 0;
609 static void rehash_id(struct fuse *f)
611 struct node_table *t = &f->id_table;
612 struct node **nodep;
613 struct node **next;
614 size_t hash;
616 if (t->split == t->size / 2)
617 return;
619 hash = t->split;
620 t->split++;
621 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
622 struct node *node = *nodep;
623 size_t newhash = id_hash(f, node->nodeid);
625 if (newhash != hash) {
626 next = nodep;
627 *nodep = node->id_next;
628 node->id_next = t->array[newhash];
629 t->array[newhash] = node;
630 } else {
631 next = &node->id_next;
634 if (t->split == t->size / 2)
635 node_table_resize(t);
638 static void hash_id(struct fuse *f, struct node *node)
640 size_t hash = id_hash(f, node->nodeid);
641 node->id_next = f->id_table.array[hash];
642 f->id_table.array[hash] = node;
643 f->id_table.use++;
645 if (f->id_table.use >= f->id_table.size / 2)
646 rehash_id(f);
649 static size_t name_hash(struct fuse *f, fuse_ino_t parent,
650 const char *name)
652 uint64_t hash = parent;
653 uint64_t oldhash;
655 for (; *name; name++)
656 hash = hash * 31 + (unsigned char) *name;
658 hash %= f->name_table.size;
659 oldhash = hash % (f->name_table.size / 2);
660 if (oldhash >= f->name_table.split)
661 return oldhash;
662 else
663 return hash;
666 static void unref_node(struct fuse *f, struct node *node);
668 static void remerge_name(struct fuse *f)
670 struct node_table *t = &f->name_table;
671 int iter;
673 if (t->split == 0)
674 node_table_reduce(t);
676 for (iter = 8; t->split > 0 && iter; iter--) {
677 struct node **upper;
679 t->split--;
680 upper = &t->array[t->split + t->size / 2];
681 if (*upper) {
682 struct node **nodep;
684 for (nodep = &t->array[t->split]; *nodep;
685 nodep = &(*nodep)->name_next);
687 *nodep = *upper;
688 *upper = NULL;
689 break;
694 static void unhash_name(struct fuse *f, struct node *node)
696 if (node->name) {
697 size_t hash = name_hash(f, node->parent->nodeid, node->name);
698 struct node **nodep = &f->name_table.array[hash];
700 for (; *nodep != NULL; nodep = &(*nodep)->name_next)
701 if (*nodep == node) {
702 *nodep = node->name_next;
703 node->name_next = NULL;
704 unref_node(f, node->parent);
705 if (node->name != node->inline_name)
706 free(node->name);
707 node->name = NULL;
708 node->parent = NULL;
709 f->name_table.use--;
711 if (f->name_table.use < f->name_table.size / 4)
712 remerge_name(f);
713 return;
715 fprintf(stderr,
716 "fuse internal error: unable to unhash node: %llu\n",
717 (unsigned long long) node->nodeid);
718 abort();
722 static void rehash_name(struct fuse *f)
724 struct node_table *t = &f->name_table;
725 struct node **nodep;
726 struct node **next;
727 size_t hash;
729 if (t->split == t->size / 2)
730 return;
732 hash = t->split;
733 t->split++;
734 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
735 struct node *node = *nodep;
736 size_t newhash = name_hash(f, node->parent->nodeid, node->name);
738 if (newhash != hash) {
739 next = nodep;
740 *nodep = node->name_next;
741 node->name_next = t->array[newhash];
742 t->array[newhash] = node;
743 } else {
744 next = &node->name_next;
747 if (t->split == t->size / 2)
748 node_table_resize(t);
751 static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
752 const char *name)
754 size_t hash = name_hash(f, parentid, name);
755 struct node *parent = get_node(f, parentid);
756 if (strlen(name) < sizeof(node->inline_name)) {
757 strcpy(node->inline_name, name);
758 node->name = node->inline_name;
759 } else {
760 node->name = strdup(name);
761 if (node->name == NULL)
762 return -1;
765 parent->refctr ++;
766 node->parent = parent;
767 node->name_next = f->name_table.array[hash];
768 f->name_table.array[hash] = node;
769 f->name_table.use++;
771 if (f->name_table.use >= f->name_table.size / 2)
772 rehash_name(f);
774 return 0;
777 static void delete_node(struct fuse *f, struct node *node)
779 if (f->conf.debug)
780 fprintf(stderr, "DELETE: %llu\n",
781 (unsigned long long) node->nodeid);
783 assert(node->treelock == 0);
784 unhash_name(f, node);
785 if (lru_enabled(f))
786 remove_node_lru(node);
787 unhash_id(f, node);
788 free_node(f, node);
791 static void unref_node(struct fuse *f, struct node *node)
793 assert(node->refctr > 0);
794 node->refctr --;
795 if (!node->refctr)
796 delete_node(f, node);
799 static fuse_ino_t next_id(struct fuse *f)
801 do {
802 f->ctr = (f->ctr + 1) & 0xffffffff;
803 if (!f->ctr)
804 f->generation ++;
805 } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
806 get_node_nocheck(f, f->ctr) != NULL);
807 return f->ctr;
810 static struct node *lookup_node(struct fuse *f, fuse_ino_t parent,
811 const char *name)
813 size_t hash = name_hash(f, parent, name);
814 struct node *node;
816 for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
817 if (node->parent->nodeid == parent &&
818 strcmp(node->name, name) == 0)
819 return node;
821 return NULL;
824 static void inc_nlookup(struct node *node)
826 if (!node->nlookup)
827 node->refctr++;
828 node->nlookup++;
831 static struct node *find_node(struct fuse *f, fuse_ino_t parent,
832 const char *name)
834 struct node *node;
836 pthread_mutex_lock(&f->lock);
837 if (!name)
838 node = get_node(f, parent);
839 else
840 node = lookup_node(f, parent, name);
841 if (node == NULL) {
842 node = alloc_node(f);
843 if (node == NULL)
844 goto out_err;
846 node->nodeid = next_id(f);
847 node->generation = f->generation;
848 if (f->conf.remember)
849 inc_nlookup(node);
851 if (hash_name(f, node, parent, name) == -1) {
852 free_node(f, node);
853 node = NULL;
854 goto out_err;
856 hash_id(f, node);
857 if (lru_enabled(f)) {
858 struct node_lru *lnode = node_lru(node);
859 init_list_head(&lnode->lru);
861 } else if (lru_enabled(f) && node->nlookup == 1) {
862 remove_node_lru(node);
864 inc_nlookup(node);
865 out_err:
866 pthread_mutex_unlock(&f->lock);
867 return node;
870 static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
872 size_t len = strlen(name);
874 if (s - len <= *buf) {
875 unsigned pathlen = *bufsize - (s - *buf);
876 unsigned newbufsize = *bufsize;
877 char *newbuf;
879 while (newbufsize < pathlen + len + 1) {
880 if (newbufsize >= 0x80000000)
881 newbufsize = 0xffffffff;
882 else
883 newbufsize *= 2;
886 newbuf = realloc(*buf, newbufsize);
887 if (newbuf == NULL)
888 return NULL;
890 *buf = newbuf;
891 s = newbuf + newbufsize - pathlen;
892 memmove(s, newbuf + *bufsize - pathlen, pathlen);
893 *bufsize = newbufsize;
895 s -= len;
896 strncpy(s, name, len);
897 s--;
898 *s = '/';
900 return s;
903 static void unlock_path(struct fuse *f, fuse_ino_t nodeid, struct node *wnode,
904 struct node *end)
906 struct node *node;
908 if (wnode) {
909 assert(wnode->treelock == TREELOCK_WRITE);
910 wnode->treelock = 0;
913 for (node = get_node(f, nodeid);
914 node != end && node->nodeid != FUSE_ROOT_ID; node = node->parent) {
915 assert(node->treelock != 0);
916 assert(node->treelock != TREELOCK_WAIT_OFFSET);
917 assert(node->treelock != TREELOCK_WRITE);
918 node->treelock--;
919 if (node->treelock == TREELOCK_WAIT_OFFSET)
920 node->treelock = 0;
924 static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
925 char **path, struct node **wnodep, bool need_lock)
927 unsigned bufsize = 256;
928 char *buf;
929 char *s;
930 struct node *node;
931 struct node *wnode = NULL;
932 int err;
934 *path = NULL;
936 err = -ENOMEM;
937 buf = malloc(bufsize);
938 if (buf == NULL)
939 goto out_err;
941 s = buf + bufsize - 1;
942 *s = '\0';
944 if (name != NULL) {
945 s = add_name(&buf, &bufsize, s, name);
946 err = -ENOMEM;
947 if (s == NULL)
948 goto out_free;
951 if (wnodep) {
952 assert(need_lock);
953 wnode = lookup_node(f, nodeid, name);
954 if (wnode) {
955 if (wnode->treelock != 0) {
956 if (wnode->treelock > 0)
957 wnode->treelock += TREELOCK_WAIT_OFFSET;
958 err = -EAGAIN;
959 goto out_free;
961 wnode->treelock = TREELOCK_WRITE;
965 for (node = get_node(f, nodeid); node->nodeid != FUSE_ROOT_ID;
966 node = node->parent) {
967 err = -ENOENT;
968 if (node->name == NULL || node->parent == NULL)
969 goto out_unlock;
971 err = -ENOMEM;
972 s = add_name(&buf, &bufsize, s, node->name);
973 if (s == NULL)
974 goto out_unlock;
976 if (need_lock) {
977 err = -EAGAIN;
978 if (node->treelock < 0)
979 goto out_unlock;
981 node->treelock++;
985 if (s[0])
986 memmove(buf, s, bufsize - (s - buf));
987 else
988 strcpy(buf, "/");
990 *path = buf;
991 if (wnodep)
992 *wnodep = wnode;
994 return 0;
996 out_unlock:
997 if (need_lock)
998 unlock_path(f, nodeid, wnode, node);
999 out_free:
1000 free(buf);
1002 out_err:
1003 return err;
1006 static void queue_element_unlock(struct fuse *f, struct lock_queue_element *qe)
1008 struct node *wnode;
1010 if (qe->first_locked) {
1011 wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1012 unlock_path(f, qe->nodeid1, wnode, NULL);
1013 qe->first_locked = false;
1015 if (qe->second_locked) {
1016 wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1017 unlock_path(f, qe->nodeid2, wnode, NULL);
1018 qe->second_locked = false;
1022 static void queue_element_wakeup(struct fuse *f, struct lock_queue_element *qe)
1024 int err;
1025 bool first = (qe == f->lockq);
1027 if (!qe->path1) {
1028 /* Just waiting for it to be unlocked */
1029 if (get_node(f, qe->nodeid1)->treelock == 0)
1030 pthread_cond_signal(&qe->cond);
1032 return;
1035 if (!qe->first_locked) {
1036 err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1037 qe->wnode1, true);
1038 if (!err)
1039 qe->first_locked = true;
1040 else if (err != -EAGAIN)
1041 goto err_unlock;
1043 if (!qe->second_locked && qe->path2) {
1044 err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1045 qe->wnode2, true);
1046 if (!err)
1047 qe->second_locked = true;
1048 else if (err != -EAGAIN)
1049 goto err_unlock;
1052 if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1053 err = 0;
1054 goto done;
1058 * Only let the first element be partially locked otherwise there could
1059 * be a deadlock.
1061 * But do allow the first element to be partially locked to prevent
1062 * starvation.
1064 if (!first)
1065 queue_element_unlock(f, qe);
1067 /* keep trying */
1068 return;
1070 err_unlock:
1071 queue_element_unlock(f, qe);
1072 done:
1073 qe->err = err;
1074 qe->done = true;
1075 pthread_cond_signal(&qe->cond);
1078 static void wake_up_queued(struct fuse *f)
1080 struct lock_queue_element *qe;
1082 for (qe = f->lockq; qe != NULL; qe = qe->next)
1083 queue_element_wakeup(f, qe);
1086 static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid,
1087 const char *name, bool wr)
1089 if (f->conf.debug) {
1090 struct node *wnode = NULL;
1092 if (wr)
1093 wnode = lookup_node(f, nodeid, name);
1095 if (wnode) {
1096 fprintf(stderr, "%s %llu (w)\n",
1097 msg, (unsigned long long) wnode->nodeid);
1098 } else {
1099 fprintf(stderr, "%s %llu\n",
1100 msg, (unsigned long long) nodeid);
1105 static void queue_path(struct fuse *f, struct lock_queue_element *qe)
1107 struct lock_queue_element **qp;
1109 qe->done = false;
1110 qe->first_locked = false;
1111 qe->second_locked = false;
1112 pthread_cond_init(&qe->cond, NULL);
1113 qe->next = NULL;
1114 for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1115 *qp = qe;
1118 static void dequeue_path(struct fuse *f, struct lock_queue_element *qe)
1120 struct lock_queue_element **qp;
1122 pthread_cond_destroy(&qe->cond);
1123 for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1124 *qp = qe->next;
1127 static int wait_path(struct fuse *f, struct lock_queue_element *qe)
1129 queue_path(f, qe);
1131 do {
1132 pthread_cond_wait(&qe->cond, &f->lock);
1133 } while (!qe->done);
1135 dequeue_path(f, qe);
1137 return qe->err;
1140 static int get_path_common(struct fuse *f, fuse_ino_t nodeid, const char *name,
1141 char **path, struct node **wnode)
1143 int err;
1145 pthread_mutex_lock(&f->lock);
1146 err = try_get_path(f, nodeid, name, path, wnode, true);
1147 if (err == -EAGAIN) {
1148 struct lock_queue_element qe = {
1149 .nodeid1 = nodeid,
1150 .name1 = name,
1151 .path1 = path,
1152 .wnode1 = wnode,
1154 debug_path(f, "QUEUE PATH", nodeid, name, !!wnode);
1155 err = wait_path(f, &qe);
1156 debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode);
1158 pthread_mutex_unlock(&f->lock);
1160 return err;
1163 static int get_path(struct fuse *f, fuse_ino_t nodeid, char **path)
1165 return get_path_common(f, nodeid, NULL, path, NULL);
1168 static int get_path_nullok(struct fuse *f, fuse_ino_t nodeid, char **path)
1170 int err = 0;
1172 if (f->conf.nopath) {
1173 *path = NULL;
1174 } else {
1175 err = get_path_common(f, nodeid, NULL, path, NULL);
1176 if (err == -ENOENT)
1177 err = 0;
1180 return err;
1183 static int get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name,
1184 char **path)
1186 return get_path_common(f, nodeid, name, path, NULL);
1189 static int get_path_wrlock(struct fuse *f, fuse_ino_t nodeid, const char *name,
1190 char **path, struct node **wnode)
1192 return get_path_common(f, nodeid, name, path, wnode);
1195 static int try_get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1196 fuse_ino_t nodeid2, const char *name2,
1197 char **path1, char **path2,
1198 struct node **wnode1, struct node **wnode2)
1200 int err;
1202 /* FIXME: locking two paths needs deadlock checking */
1203 err = try_get_path(f, nodeid1, name1, path1, wnode1, true);
1204 if (!err) {
1205 err = try_get_path(f, nodeid2, name2, path2, wnode2, true);
1206 if (err) {
1207 struct node *wn1 = wnode1 ? *wnode1 : NULL;
1209 unlock_path(f, nodeid1, wn1, NULL);
1210 free(*path1);
1213 return err;
1216 static int get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1217 fuse_ino_t nodeid2, const char *name2,
1218 char **path1, char **path2,
1219 struct node **wnode1, struct node **wnode2)
1221 int err;
1223 pthread_mutex_lock(&f->lock);
1224 err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1225 path1, path2, wnode1, wnode2);
1226 if (err == -EAGAIN) {
1227 struct lock_queue_element qe = {
1228 .nodeid1 = nodeid1,
1229 .name1 = name1,
1230 .path1 = path1,
1231 .wnode1 = wnode1,
1232 .nodeid2 = nodeid2,
1233 .name2 = name2,
1234 .path2 = path2,
1235 .wnode2 = wnode2,
1238 debug_path(f, "QUEUE PATH1", nodeid1, name1, !!wnode1);
1239 debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1240 err = wait_path(f, &qe);
1241 debug_path(f, "DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1242 debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1244 pthread_mutex_unlock(&f->lock);
1246 return err;
1249 static void free_path_wrlock(struct fuse *f, fuse_ino_t nodeid,
1250 struct node *wnode, char *path)
1252 pthread_mutex_lock(&f->lock);
1253 unlock_path(f, nodeid, wnode, NULL);
1254 if (f->lockq)
1255 wake_up_queued(f);
1256 pthread_mutex_unlock(&f->lock);
1257 free(path);
1260 static void free_path(struct fuse *f, fuse_ino_t nodeid, char *path)
1262 if (path)
1263 free_path_wrlock(f, nodeid, NULL, path);
1266 static void free_path2(struct fuse *f, fuse_ino_t nodeid1, fuse_ino_t nodeid2,
1267 struct node *wnode1, struct node *wnode2,
1268 char *path1, char *path2)
1270 pthread_mutex_lock(&f->lock);
1271 unlock_path(f, nodeid1, wnode1, NULL);
1272 unlock_path(f, nodeid2, wnode2, NULL);
1273 wake_up_queued(f);
1274 pthread_mutex_unlock(&f->lock);
1275 free(path1);
1276 free(path2);
1279 static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
1281 struct node *node;
1282 if (nodeid == FUSE_ROOT_ID)
1283 return;
1284 pthread_mutex_lock(&f->lock);
1285 node = get_node(f, nodeid);
1288 * Node may still be locked due to interrupt idiocy in open,
1289 * create and opendir
1291 while (node->nlookup == nlookup && node->treelock) {
1292 struct lock_queue_element qe = {
1293 .nodeid1 = nodeid,
1296 debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false);
1297 queue_path(f, &qe);
1299 do {
1300 pthread_cond_wait(&qe.cond, &f->lock);
1301 } while (node->nlookup == nlookup && node->treelock);
1303 dequeue_path(f, &qe);
1304 debug_path(f, "DEQUEUE_PATH (forget)", nodeid, NULL, false);
1307 assert(node->nlookup >= nlookup);
1308 node->nlookup -= nlookup;
1309 if (!node->nlookup) {
1310 unref_node(f, node);
1311 } else if (lru_enabled(f) && node->nlookup == 1) {
1312 set_forget_time(f, node);
1314 pthread_mutex_unlock(&f->lock);
1317 static void unlink_node(struct fuse *f, struct node *node)
1319 if (f->conf.remember) {
1320 assert(node->nlookup > 1);
1321 node->nlookup--;
1323 unhash_name(f, node);
1326 static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name)
1328 struct node *node;
1330 pthread_mutex_lock(&f->lock);
1331 node = lookup_node(f, dir, name);
1332 if (node != NULL)
1333 unlink_node(f, node);
1334 pthread_mutex_unlock(&f->lock);
1337 static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1338 fuse_ino_t newdir, const char *newname, int hide)
1340 struct node *node;
1341 struct node *newnode;
1342 int err = 0;
1344 pthread_mutex_lock(&f->lock);
1345 node = lookup_node(f, olddir, oldname);
1346 newnode = lookup_node(f, newdir, newname);
1347 if (node == NULL)
1348 goto out;
1350 if (newnode != NULL) {
1351 if (hide) {
1352 fprintf(stderr, "fuse: hidden file got created during hiding\n");
1353 err = -EBUSY;
1354 goto out;
1356 unlink_node(f, newnode);
1359 unhash_name(f, node);
1360 if (hash_name(f, node, newdir, newname) == -1) {
1361 err = -ENOMEM;
1362 goto out;
1365 if (hide)
1366 node->is_hidden = 1;
1368 out:
1369 pthread_mutex_unlock(&f->lock);
1370 return err;
1373 static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
1375 if (!f->conf.use_ino)
1376 stbuf->st_ino = nodeid;
1377 if (f->conf.set_mode)
1378 stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1379 (0777 & ~f->conf.umask);
1380 if (f->conf.set_uid)
1381 stbuf->st_uid = f->conf.uid;
1382 if (f->conf.set_gid)
1383 stbuf->st_gid = f->conf.gid;
1386 static struct fuse *req_fuse(fuse_req_t req)
1388 return (struct fuse *) fuse_req_userdata(req);
1391 static void fuse_intr_sighandler(int sig)
1393 (void) sig;
1394 /* Nothing to do */
1397 struct fuse_intr_data {
1398 pthread_t id;
1399 pthread_cond_t cond;
1400 int finished;
1403 static void fuse_interrupt(fuse_req_t req, void *d_)
1405 struct fuse_intr_data *d = d_;
1406 struct fuse *f = req_fuse(req);
1408 if (d->id == pthread_self())
1409 return;
1411 pthread_mutex_lock(&f->lock);
1412 while (!d->finished) {
1413 struct timeval now;
1414 struct timespec timeout;
1416 pthread_kill(d->id, f->conf.intr_signal);
1417 gettimeofday(&now, NULL);
1418 timeout.tv_sec = now.tv_sec + 1;
1419 timeout.tv_nsec = now.tv_usec * 1000;
1420 pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1422 pthread_mutex_unlock(&f->lock);
1425 static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
1426 struct fuse_intr_data *d)
1428 pthread_mutex_lock(&f->lock);
1429 d->finished = 1;
1430 pthread_cond_broadcast(&d->cond);
1431 pthread_mutex_unlock(&f->lock);
1432 fuse_req_interrupt_func(req, NULL, NULL);
1433 pthread_cond_destroy(&d->cond);
1436 static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
1438 d->id = pthread_self();
1439 pthread_cond_init(&d->cond, NULL);
1440 d->finished = 0;
1441 fuse_req_interrupt_func(req, fuse_interrupt, d);
1444 static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
1445 struct fuse_intr_data *d)
1447 if (f->conf.intr)
1448 fuse_do_finish_interrupt(f, req, d);
1451 static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
1452 struct fuse_intr_data *d)
1454 if (f->conf.intr)
1455 fuse_do_prepare_interrupt(req, d);
1458 int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf)
1460 fuse_get_context()->private_data = fs->user_data;
1461 if (fs->op.getattr) {
1462 if (fs->debug)
1463 fprintf(stderr, "getattr %s\n", path);
1465 return fs->op.getattr(path, buf);
1466 } else {
1467 return -ENOSYS;
1471 int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
1472 struct fuse_file_info *fi)
1474 fuse_get_context()->private_data = fs->user_data;
1475 if (fs->op.fgetattr) {
1476 if (fs->debug)
1477 fprintf(stderr, "fgetattr[%llu] %s\n",
1478 (unsigned long long) fi->fh, path);
1480 return fs->op.fgetattr(path, buf, fi);
1481 } else if (path && fs->op.getattr) {
1482 if (fs->debug)
1483 fprintf(stderr, "getattr %s\n", path);
1485 return fs->op.getattr(path, buf);
1486 } else {
1487 return -ENOSYS;
1491 int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
1492 const char *newpath)
1494 fuse_get_context()->private_data = fs->user_data;
1495 if (fs->op.rename) {
1496 if (fs->debug)
1497 fprintf(stderr, "rename %s %s\n", oldpath, newpath);
1499 return fs->op.rename(oldpath, newpath);
1500 } else {
1501 return -ENOSYS;
1505 int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
1507 fuse_get_context()->private_data = fs->user_data;
1508 if (fs->op.unlink) {
1509 if (fs->debug)
1510 fprintf(stderr, "unlink %s\n", path);
1512 return fs->op.unlink(path);
1513 } else {
1514 return -ENOSYS;
1518 int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
1520 fuse_get_context()->private_data = fs->user_data;
1521 if (fs->op.rmdir) {
1522 if (fs->debug)
1523 fprintf(stderr, "rmdir %s\n", path);
1525 return fs->op.rmdir(path);
1526 } else {
1527 return -ENOSYS;
1531 int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
1533 fuse_get_context()->private_data = fs->user_data;
1534 if (fs->op.symlink) {
1535 if (fs->debug)
1536 fprintf(stderr, "symlink %s %s\n", linkname, path);
1538 return fs->op.symlink(linkname, path);
1539 } else {
1540 return -ENOSYS;
1544 int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
1546 fuse_get_context()->private_data = fs->user_data;
1547 if (fs->op.link) {
1548 if (fs->debug)
1549 fprintf(stderr, "link %s %s\n", oldpath, newpath);
1551 return fs->op.link(oldpath, newpath);
1552 } else {
1553 return -ENOSYS;
1557 int fuse_fs_release(struct fuse_fs *fs, const char *path,
1558 struct fuse_file_info *fi)
1560 fuse_get_context()->private_data = fs->user_data;
1561 if (fs->op.release) {
1562 if (fs->debug)
1563 fprintf(stderr, "release%s[%llu] flags: 0x%x\n",
1564 fi->flush ? "+flush" : "",
1565 (unsigned long long) fi->fh, fi->flags);
1567 return fs->op.release(path, fi);
1568 } else {
1569 return 0;
1573 int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
1574 struct fuse_file_info *fi)
1576 fuse_get_context()->private_data = fs->user_data;
1577 if (fs->op.opendir) {
1578 int err;
1580 if (fs->debug)
1581 fprintf(stderr, "opendir flags: 0x%x %s\n", fi->flags,
1582 path);
1584 err = fs->op.opendir(path, fi);
1586 if (fs->debug && !err)
1587 fprintf(stderr, " opendir[%lli] flags: 0x%x %s\n",
1588 (unsigned long long) fi->fh, fi->flags, path);
1590 return err;
1591 } else {
1592 return 0;
1596 int fuse_fs_open(struct fuse_fs *fs, const char *path,
1597 struct fuse_file_info *fi)
1599 fuse_get_context()->private_data = fs->user_data;
1600 if (fs->op.open) {
1601 int err;
1603 if (fs->debug)
1604 fprintf(stderr, "open flags: 0x%x %s\n", fi->flags,
1605 path);
1607 err = fs->op.open(path, fi);
1609 if (fs->debug && !err)
1610 fprintf(stderr, " open[%lli] flags: 0x%x %s\n",
1611 (unsigned long long) fi->fh, fi->flags, path);
1613 return err;
1614 } else {
1615 return 0;
1619 static void fuse_free_buf(struct fuse_bufvec *buf)
1621 if (buf != NULL) {
1622 size_t i;
1624 for (i = 0; i < buf->count; i++)
1625 free(buf->buf[i].mem);
1626 free(buf);
1630 int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
1631 struct fuse_bufvec **bufp, size_t size, off_t off,
1632 struct fuse_file_info *fi)
1634 fuse_get_context()->private_data = fs->user_data;
1635 if (fs->op.read || fs->op.read_buf) {
1636 int res;
1638 if (fs->debug)
1639 fprintf(stderr,
1640 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1641 (unsigned long long) fi->fh,
1642 size, (unsigned long long) off, fi->flags);
1644 if (fs->op.read_buf) {
1645 res = fs->op.read_buf(path, bufp, size, off, fi);
1646 } else {
1647 struct fuse_bufvec *buf;
1648 void *mem;
1650 buf = malloc(sizeof(struct fuse_bufvec));
1651 if (buf == NULL)
1652 return -ENOMEM;
1654 mem = malloc(size);
1655 if (mem == NULL) {
1656 free(buf);
1657 return -ENOMEM;
1659 *buf = FUSE_BUFVEC_INIT(size);
1660 buf->buf[0].mem = mem;
1661 *bufp = buf;
1663 res = fs->op.read(path, mem, size, off, fi);
1664 if (res >= 0)
1665 buf->buf[0].size = res;
1668 if (fs->debug && res >= 0)
1669 fprintf(stderr, " read[%llu] %zu bytes from %llu\n",
1670 (unsigned long long) fi->fh,
1671 fuse_buf_size(*bufp),
1672 (unsigned long long) off);
1673 if (res >= 0 && fuse_buf_size(*bufp) > (int) size)
1674 fprintf(stderr, "fuse: read too many bytes\n");
1676 if (res < 0)
1677 return res;
1679 return 0;
1680 } else {
1681 return -ENOSYS;
1685 int fuse_fs_read(struct fuse_fs *fs, const char *path, char *mem, size_t size,
1686 off_t off, struct fuse_file_info *fi)
1688 int res;
1689 struct fuse_bufvec *buf = NULL;
1691 res = fuse_fs_read_buf(fs, path, &buf, size, off, fi);
1692 if (res == 0) {
1693 struct fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
1695 dst.buf[0].mem = mem;
1696 res = fuse_buf_copy(&dst, buf, 0);
1698 fuse_free_buf(buf);
1700 return res;
1703 int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
1704 struct fuse_bufvec *buf, off_t off,
1705 struct fuse_file_info *fi)
1707 fuse_get_context()->private_data = fs->user_data;
1708 if (fs->op.write_buf || fs->op.write) {
1709 int res;
1710 size_t size = fuse_buf_size(buf);
1712 assert(buf->idx == 0 && buf->off == 0);
1713 if (fs->debug)
1714 fprintf(stderr,
1715 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1716 fi->writepage ? "page" : "",
1717 (unsigned long long) fi->fh,
1718 size,
1719 (unsigned long long) off,
1720 fi->flags);
1722 if (fs->op.write_buf) {
1723 res = fs->op.write_buf(path, buf, off, fi);
1724 } else {
1725 void *mem = NULL;
1726 struct fuse_buf *flatbuf;
1727 struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
1729 if (buf->count == 1 &&
1730 !(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
1731 flatbuf = &buf->buf[0];
1732 } else {
1733 res = -ENOMEM;
1734 mem = malloc(size);
1735 if (mem == NULL)
1736 goto out;
1738 tmp.buf[0].mem = mem;
1739 res = fuse_buf_copy(&tmp, buf, 0);
1740 if (res <= 0)
1741 goto out_free;
1743 tmp.buf[0].size = res;
1744 flatbuf = &tmp.buf[0];
1747 res = fs->op.write(path, flatbuf->mem, flatbuf->size,
1748 off, fi);
1749 out_free:
1750 free(mem);
1752 out:
1753 if (fs->debug && res >= 0)
1754 fprintf(stderr, " write%s[%llu] %u bytes to %llu\n",
1755 fi->writepage ? "page" : "",
1756 (unsigned long long) fi->fh, res,
1757 (unsigned long long) off);
1758 if (res > (int) size)
1759 fprintf(stderr, "fuse: wrote too many bytes\n");
1761 return res;
1762 } else {
1763 return -ENOSYS;
1767 int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *mem,
1768 size_t size, off_t off, struct fuse_file_info *fi)
1770 struct fuse_bufvec bufv = FUSE_BUFVEC_INIT(size);
1772 bufv.buf[0].mem = (void *) mem;
1774 return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1777 int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
1778 struct fuse_file_info *fi)
1780 fuse_get_context()->private_data = fs->user_data;
1781 if (fs->op.fsync) {
1782 if (fs->debug)
1783 fprintf(stderr, "fsync[%llu] datasync: %i\n",
1784 (unsigned long long) fi->fh, datasync);
1786 return fs->op.fsync(path, datasync, fi);
1787 } else {
1788 return -ENOSYS;
1792 int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
1793 struct fuse_file_info *fi)
1795 fuse_get_context()->private_data = fs->user_data;
1796 if (fs->op.fsyncdir) {
1797 if (fs->debug)
1798 fprintf(stderr, "fsyncdir[%llu] datasync: %i\n",
1799 (unsigned long long) fi->fh, datasync);
1801 return fs->op.fsyncdir(path, datasync, fi);
1802 } else {
1803 return -ENOSYS;
1807 int fuse_fs_flush(struct fuse_fs *fs, const char *path,
1808 struct fuse_file_info *fi)
1810 fuse_get_context()->private_data = fs->user_data;
1811 if (fs->op.flush) {
1812 if (fs->debug)
1813 fprintf(stderr, "flush[%llu]\n",
1814 (unsigned long long) fi->fh);
1816 return fs->op.flush(path, fi);
1817 } else {
1818 return -ENOSYS;
1822 int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
1824 fuse_get_context()->private_data = fs->user_data;
1825 if (fs->op.statfs) {
1826 if (fs->debug)
1827 fprintf(stderr, "statfs %s\n", path);
1829 return fs->op.statfs(path, buf);
1830 } else {
1831 buf->f_namemax = 255;
1832 buf->f_bsize = 512;
1833 return 0;
1837 int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
1838 struct fuse_file_info *fi)
1840 fuse_get_context()->private_data = fs->user_data;
1841 if (fs->op.releasedir) {
1842 if (fs->debug)
1843 fprintf(stderr, "releasedir[%llu] flags: 0x%x\n",
1844 (unsigned long long) fi->fh, fi->flags);
1846 return fs->op.releasedir(path, fi);
1847 } else {
1848 return 0;
1852 int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
1853 fuse_fill_dir_t filler, off_t off,
1854 struct fuse_file_info *fi)
1856 fuse_get_context()->private_data = fs->user_data;
1857 if (fs->op.readdir) {
1858 if (fs->debug)
1859 fprintf(stderr, "readdir[%llu] from %llu\n",
1860 (unsigned long long) fi->fh,
1861 (unsigned long long) off);
1863 return fs->op.readdir(path, buf, filler, off, fi);
1864 } else {
1865 return -ENOSYS;
1869 int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
1870 struct fuse_file_info *fi)
1872 fuse_get_context()->private_data = fs->user_data;
1873 if (fs->op.create) {
1874 int err;
1876 if (fs->debug)
1877 fprintf(stderr,
1878 "create flags: 0x%x %s 0%o umask=0%03o\n",
1879 fi->flags, path, mode,
1880 fuse_get_context()->umask);
1882 err = fs->op.create(path, mode, fi);
1884 if (fs->debug && !err)
1885 fprintf(stderr, " create[%llu] flags: 0x%x %s\n",
1886 (unsigned long long) fi->fh, fi->flags, path);
1888 return err;
1889 } else {
1890 return -ENOSYS;
1894 int fuse_fs_lock(struct fuse_fs *fs, const char *path,
1895 struct fuse_file_info *fi, int cmd, struct flock *lock)
1897 fuse_get_context()->private_data = fs->user_data;
1898 if (fs->op.lock) {
1899 if (fs->debug)
1900 fprintf(stderr, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
1901 (unsigned long long) fi->fh,
1902 (cmd == F_GETLK ? "F_GETLK" :
1903 (cmd == F_SETLK ? "F_SETLK" :
1904 (cmd == F_SETLKW ? "F_SETLKW" : "???"))),
1905 (lock->l_type == F_RDLCK ? "F_RDLCK" :
1906 (lock->l_type == F_WRLCK ? "F_WRLCK" :
1907 (lock->l_type == F_UNLCK ? "F_UNLCK" :
1908 "???"))),
1909 (unsigned long long) lock->l_start,
1910 (unsigned long long) lock->l_len,
1911 (unsigned long long) lock->l_pid);
1913 return fs->op.lock(path, fi, cmd, lock);
1914 } else {
1915 return -ENOSYS;
1919 int fuse_fs_flock(struct fuse_fs *fs, const char *path,
1920 struct fuse_file_info *fi, int op)
1922 fuse_get_context()->private_data = fs->user_data;
1923 if (fs->op.flock) {
1924 if (fs->debug) {
1925 int xop = op & ~LOCK_NB;
1927 fprintf(stderr, "lock[%llu] %s%s\n",
1928 (unsigned long long) fi->fh,
1929 xop == LOCK_SH ? "LOCK_SH" :
1930 (xop == LOCK_EX ? "LOCK_EX" :
1931 (xop == LOCK_UN ? "LOCK_UN" : "???")),
1932 (op & LOCK_NB) ? "|LOCK_NB" : "");
1934 return fs->op.flock(path, fi, op);
1935 } else {
1936 return -ENOSYS;
1940 int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid)
1942 fuse_get_context()->private_data = fs->user_data;
1943 if (fs->op.chown) {
1944 if (fs->debug)
1945 fprintf(stderr, "chown %s %lu %lu\n", path,
1946 (unsigned long) uid, (unsigned long) gid);
1948 return fs->op.chown(path, uid, gid);
1949 } else {
1950 return -ENOSYS;
1954 int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size)
1956 fuse_get_context()->private_data = fs->user_data;
1957 if (fs->op.truncate) {
1958 if (fs->debug)
1959 fprintf(stderr, "truncate %s %llu\n", path,
1960 (unsigned long long) size);
1962 return fs->op.truncate(path, size);
1963 } else {
1964 return -ENOSYS;
1968 int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
1969 struct fuse_file_info *fi)
1971 fuse_get_context()->private_data = fs->user_data;
1972 if (fs->op.ftruncate) {
1973 if (fs->debug)
1974 fprintf(stderr, "ftruncate[%llu] %llu\n",
1975 (unsigned long long) fi->fh,
1976 (unsigned long long) size);
1978 return fs->op.ftruncate(path, size, fi);
1979 } else if (path && fs->op.truncate) {
1980 if (fs->debug)
1981 fprintf(stderr, "truncate %s %llu\n", path,
1982 (unsigned long long) size);
1984 return fs->op.truncate(path, size);
1985 } else {
1986 return -ENOSYS;
1990 int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
1991 const struct timespec tv[2])
1993 fuse_get_context()->private_data = fs->user_data;
1994 if (fs->op.utimens) {
1995 if (fs->debug)
1996 fprintf(stderr, "utimens %s %li.%09lu %li.%09lu\n",
1997 path, tv[0].tv_sec, tv[0].tv_nsec,
1998 tv[1].tv_sec, tv[1].tv_nsec);
2000 return fs->op.utimens(path, tv);
2001 } else {
2002 return -ENOSYS;
2006 int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
2008 fuse_get_context()->private_data = fs->user_data;
2009 if (fs->op.access) {
2010 if (fs->debug)
2011 fprintf(stderr, "access %s 0%o\n", path, mask);
2013 return fs->op.access(path, mask);
2014 } else {
2015 return -ENOSYS;
2019 int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
2020 size_t len)
2022 fuse_get_context()->private_data = fs->user_data;
2023 if (fs->op.readlink) {
2024 if (fs->debug)
2025 fprintf(stderr, "readlink %s %lu\n", path,
2026 (unsigned long) len);
2028 return fs->op.readlink(path, buf, len);
2029 } else {
2030 return -ENOSYS;
2034 int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
2035 dev_t rdev)
2037 fuse_get_context()->private_data = fs->user_data;
2038 if (fs->op.mknod) {
2039 if (fs->debug)
2040 fprintf(stderr, "mknod %s 0%o 0x%llx umask=0%03o\n",
2041 path, mode, (unsigned long long) rdev,
2042 fuse_get_context()->umask);
2044 return fs->op.mknod(path, mode, rdev);
2045 } else {
2046 return -ENOSYS;
2050 int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
2052 fuse_get_context()->private_data = fs->user_data;
2053 if (fs->op.mkdir) {
2054 if (fs->debug)
2055 fprintf(stderr, "mkdir %s 0%o umask=0%03o\n",
2056 path, mode, fuse_get_context()->umask);
2058 return fs->op.mkdir(path, mode);
2059 } else {
2060 return -ENOSYS;
2064 int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
2065 const char *value, size_t size, int flags)
2067 fuse_get_context()->private_data = fs->user_data;
2068 if (fs->op.setxattr) {
2069 if (fs->debug)
2070 fprintf(stderr, "setxattr %s %s %lu 0x%x\n",
2071 path, name, (unsigned long) size, flags);
2073 return fs->op.setxattr(path, name, value, size, flags);
2074 } else {
2075 return -ENOSYS;
2079 int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
2080 char *value, size_t size)
2082 fuse_get_context()->private_data = fs->user_data;
2083 if (fs->op.getxattr) {
2084 if (fs->debug)
2085 fprintf(stderr, "getxattr %s %s %lu\n",
2086 path, name, (unsigned long) size);
2088 return fs->op.getxattr(path, name, value, size);
2089 } else {
2090 return -ENOSYS;
2094 int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
2095 size_t size)
2097 fuse_get_context()->private_data = fs->user_data;
2098 if (fs->op.listxattr) {
2099 if (fs->debug)
2100 fprintf(stderr, "listxattr %s %lu\n",
2101 path, (unsigned long) size);
2103 return fs->op.listxattr(path, list, size);
2104 } else {
2105 return -ENOSYS;
2109 int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
2110 uint64_t *idx)
2112 fuse_get_context()->private_data = fs->user_data;
2113 if (fs->op.bmap) {
2114 if (fs->debug)
2115 fprintf(stderr, "bmap %s blocksize: %lu index: %llu\n",
2116 path, (unsigned long) blocksize,
2117 (unsigned long long) *idx);
2119 return fs->op.bmap(path, blocksize, idx);
2120 } else {
2121 return -ENOSYS;
2125 int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
2127 fuse_get_context()->private_data = fs->user_data;
2128 if (fs->op.removexattr) {
2129 if (fs->debug)
2130 fprintf(stderr, "removexattr %s %s\n", path, name);
2132 return fs->op.removexattr(path, name);
2133 } else {
2134 return -ENOSYS;
2138 int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
2139 struct fuse_file_info *fi, unsigned int flags, void *data)
2141 fuse_get_context()->private_data = fs->user_data;
2142 if (fs->op.ioctl) {
2143 if (fs->debug)
2144 fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n",
2145 (unsigned long long) fi->fh, cmd, flags);
2147 return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2148 } else
2149 return -ENOSYS;
2152 int fuse_fs_poll(struct fuse_fs *fs, const char *path,
2153 struct fuse_file_info *fi, struct fuse_pollhandle *ph,
2154 unsigned *reventsp)
2156 fuse_get_context()->private_data = fs->user_data;
2157 if (fs->op.poll) {
2158 int res;
2160 if (fs->debug)
2161 fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n",
2162 (unsigned long long) fi->fh, ph,
2163 fi->poll_events);
2165 res = fs->op.poll(path, fi, ph, reventsp);
2167 if (fs->debug && !res)
2168 fprintf(stderr, " poll[%llu] revents: 0x%x\n",
2169 (unsigned long long) fi->fh, *reventsp);
2171 return res;
2172 } else
2173 return -ENOSYS;
2176 int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
2177 off_t offset, off_t length, struct fuse_file_info *fi)
2179 fuse_get_context()->private_data = fs->user_data;
2180 if (fs->op.fallocate) {
2181 if (fs->debug)
2182 fprintf(stderr, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2183 path,
2184 mode,
2185 (unsigned long long) offset,
2186 (unsigned long long) length);
2188 return fs->op.fallocate(path, mode, offset, length, fi);
2189 } else
2190 return -ENOSYS;
2193 static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
2195 struct node *node;
2196 int isopen = 0;
2197 pthread_mutex_lock(&f->lock);
2198 node = lookup_node(f, dir, name);
2199 if (node && node->open_count > 0)
2200 isopen = 1;
2201 pthread_mutex_unlock(&f->lock);
2202 return isopen;
2205 static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
2206 char *newname, size_t bufsize)
2208 struct stat buf;
2209 struct node *node;
2210 struct node *newnode;
2211 char *newpath;
2212 int res;
2213 int failctr = 10;
2215 do {
2216 pthread_mutex_lock(&f->lock);
2217 node = lookup_node(f, dir, oldname);
2218 if (node == NULL) {
2219 pthread_mutex_unlock(&f->lock);
2220 return NULL;
2222 do {
2223 f->hidectr ++;
2224 snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
2225 (unsigned int) node->nodeid, f->hidectr);
2226 newnode = lookup_node(f, dir, newname);
2227 } while(newnode);
2229 res = try_get_path(f, dir, newname, &newpath, NULL, false);
2230 pthread_mutex_unlock(&f->lock);
2231 if (res)
2232 break;
2234 res = fuse_fs_getattr(f->fs, newpath, &buf);
2235 if (res == -ENOENT)
2236 break;
2237 free(newpath);
2238 newpath = NULL;
2239 } while(res == 0 && --failctr);
2241 return newpath;
2244 static int hide_node(struct fuse *f, const char *oldpath,
2245 fuse_ino_t dir, const char *oldname)
2247 char newname[64];
2248 char *newpath;
2249 int err = -EBUSY;
2251 newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
2252 if (newpath) {
2253 err = fuse_fs_rename(f->fs, oldpath, newpath);
2254 if (!err)
2255 err = rename_node(f, dir, oldname, dir, newname, 1);
2256 free(newpath);
2258 return err;
2261 static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
2263 return stbuf->st_mtime == ts->tv_sec &&
2264 ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2267 #ifndef CLOCK_MONOTONIC
2268 #define CLOCK_MONOTONIC CLOCK_REALTIME
2269 #endif
2271 static void curr_time(struct timespec *now)
2273 static clockid_t clockid = CLOCK_MONOTONIC;
2274 int res = clock_gettime(clockid, now);
2275 if (res == -1 && errno == EINVAL) {
2276 clockid = CLOCK_REALTIME;
2277 res = clock_gettime(clockid, now);
2279 if (res == -1) {
2280 perror("fuse: clock_gettime");
2281 abort();
2285 static void update_stat(struct node *node, const struct stat *stbuf)
2287 if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2288 stbuf->st_size != node->size))
2289 node->cache_valid = 0;
2290 node->mtime.tv_sec = stbuf->st_mtime;
2291 node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2292 node->size = stbuf->st_size;
2293 curr_time(&node->stat_updated);
2296 static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
2297 const char *name, const char *path,
2298 struct fuse_entry_param *e, struct fuse_file_info *fi)
2300 int res;
2302 memset(e, 0, sizeof(struct fuse_entry_param));
2303 if (fi)
2304 res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
2305 else
2306 res = fuse_fs_getattr(f->fs, path, &e->attr);
2307 if (res == 0) {
2308 struct node *node;
2310 node = find_node(f, nodeid, name);
2311 if (node == NULL)
2312 res = -ENOMEM;
2313 else {
2314 e->ino = node->nodeid;
2315 e->generation = node->generation;
2316 e->entry_timeout = f->conf.entry_timeout;
2317 e->attr_timeout = f->conf.attr_timeout;
2318 if (f->conf.auto_cache) {
2319 pthread_mutex_lock(&f->lock);
2320 update_stat(node, &e->attr);
2321 pthread_mutex_unlock(&f->lock);
2323 set_stat(f, e->ino, &e->attr);
2324 if (f->conf.debug)
2325 fprintf(stderr, " NODEID: %llu\n",
2326 (unsigned long long) e->ino);
2329 return res;
2332 static struct fuse_context_i *fuse_get_context_internal(void)
2334 return (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2337 static struct fuse_context_i *fuse_create_context(struct fuse *f)
2339 struct fuse_context_i *c = fuse_get_context_internal();
2340 if (c == NULL) {
2341 c = (struct fuse_context_i *)
2342 calloc(1, sizeof(struct fuse_context_i));
2343 if (c == NULL) {
2344 /* This is hard to deal with properly, so just
2345 abort. If memory is so low that the
2346 context cannot be allocated, there's not
2347 much hope for the filesystem anyway */
2348 fprintf(stderr, "fuse: failed to allocate thread specific data\n");
2349 abort();
2351 pthread_setspecific(fuse_context_key, c);
2352 } else {
2353 memset(c, 0, sizeof(*c));
2355 c->ctx.fuse = f;
2357 return c;
2360 static void fuse_freecontext(void *data)
2362 free(data);
2365 static int fuse_create_context_key(void)
2367 int err = 0;
2368 pthread_mutex_lock(&fuse_context_lock);
2369 if (!fuse_context_ref) {
2370 err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2371 if (err) {
2372 fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
2373 strerror(err));
2374 pthread_mutex_unlock(&fuse_context_lock);
2375 return -1;
2378 fuse_context_ref++;
2379 pthread_mutex_unlock(&fuse_context_lock);
2380 return 0;
2383 static void fuse_delete_context_key(void)
2385 pthread_mutex_lock(&fuse_context_lock);
2386 fuse_context_ref--;
2387 if (!fuse_context_ref) {
2388 free(pthread_getspecific(fuse_context_key));
2389 pthread_key_delete(fuse_context_key);
2391 pthread_mutex_unlock(&fuse_context_lock);
2394 static struct fuse *req_fuse_prepare(fuse_req_t req)
2396 struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2397 const struct fuse_ctx *ctx = fuse_req_ctx(req);
2398 c->req = req;
2399 c->ctx.uid = ctx->uid;
2400 c->ctx.gid = ctx->gid;
2401 c->ctx.pid = ctx->pid;
2402 c->ctx.umask = ctx->umask;
2403 return c->ctx.fuse;
2406 static inline void reply_err(fuse_req_t req, int err)
2408 /* fuse_reply_err() uses non-negated errno values */
2409 fuse_reply_err(req, -err);
2412 static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
2413 int err)
2415 if (!err) {
2416 struct fuse *f = req_fuse(req);
2417 if (fuse_reply_entry(req, e) == -ENOENT) {
2418 /* Skip forget for negative result */
2419 if (e->ino != 0)
2420 forget_node(f, e->ino, 1);
2422 } else
2423 reply_err(req, err);
2426 void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn)
2428 fuse_get_context()->private_data = fs->user_data;
2429 if (!fs->op.write_buf)
2430 conn->want &= ~FUSE_CAP_SPLICE_READ;
2431 if (!fs->op.lock)
2432 conn->want &= ~FUSE_CAP_POSIX_LOCKS;
2433 if (!fs->op.flock)
2434 conn->want &= ~FUSE_CAP_FLOCK_LOCKS;
2435 if (fs->op.init)
2436 fs->user_data = fs->op.init(conn);
2439 static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
2441 struct fuse *f = (struct fuse *) data;
2443 fuse_create_context(f);
2444 conn->want |= FUSE_CAP_EXPORT_SUPPORT;
2445 fuse_fs_init(f->fs, conn);
2448 void fuse_fs_destroy(struct fuse_fs *fs)
2450 fuse_get_context()->private_data = fs->user_data;
2451 if (fs->op.destroy)
2452 fs->op.destroy(fs->user_data);
2453 if (fs->m)
2454 fuse_put_module(fs->m);
2455 free(fs);
2458 static void fuse_lib_destroy(void *data)
2460 struct fuse *f = (struct fuse *) data;
2462 fuse_create_context(f);
2463 fuse_fs_destroy(f->fs);
2464 f->fs = NULL;
2467 static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
2468 const char *name)
2470 struct fuse *f = req_fuse_prepare(req);
2471 struct fuse_entry_param e;
2472 char *path;
2473 int err;
2474 struct node *dot = NULL;
2476 if (name[0] == '.') {
2477 int len = strlen(name);
2479 if (len == 1 || (name[1] == '.' && len == 2)) {
2480 pthread_mutex_lock(&f->lock);
2481 if (len == 1) {
2482 if (f->conf.debug)
2483 fprintf(stderr, "LOOKUP-DOT\n");
2484 dot = get_node_nocheck(f, parent);
2485 if (dot == NULL) {
2486 pthread_mutex_unlock(&f->lock);
2487 reply_entry(req, &e, -ESTALE);
2488 return;
2490 dot->refctr++;
2491 } else {
2492 if (f->conf.debug)
2493 fprintf(stderr, "LOOKUP-DOTDOT\n");
2494 parent = get_node(f, parent)->parent->nodeid;
2496 pthread_mutex_unlock(&f->lock);
2497 name = NULL;
2501 err = get_path_name(f, parent, name, &path);
2502 if (!err) {
2503 struct fuse_intr_data d;
2504 if (f->conf.debug)
2505 fprintf(stderr, "LOOKUP %s\n", path);
2506 fuse_prepare_interrupt(f, req, &d);
2507 err = lookup_path(f, parent, name, path, &e, NULL);
2508 if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2509 e.ino = 0;
2510 e.entry_timeout = f->conf.negative_timeout;
2511 err = 0;
2513 fuse_finish_interrupt(f, req, &d);
2514 free_path(f, parent, path);
2516 if (dot) {
2517 pthread_mutex_lock(&f->lock);
2518 unref_node(f, dot);
2519 pthread_mutex_unlock(&f->lock);
2521 reply_entry(req, &e, err);
2524 static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup)
2526 if (f->conf.debug)
2527 fprintf(stderr, "FORGET %llu/%llu\n", (unsigned long long)ino,
2528 (unsigned long long) nlookup);
2529 forget_node(f, ino, nlookup);
2532 static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino,
2533 unsigned long nlookup)
2535 do_forget(req_fuse(req), ino, nlookup);
2536 fuse_reply_none(req);
2539 static void fuse_lib_forget_multi(fuse_req_t req, size_t count,
2540 struct fuse_forget_data *forgets)
2542 struct fuse *f = req_fuse(req);
2543 size_t i;
2545 for (i = 0; i < count; i++)
2546 do_forget(f, forgets[i].ino, forgets[i].nlookup);
2548 fuse_reply_none(req);
2552 static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
2553 struct fuse_file_info *fi)
2555 struct fuse *f = req_fuse_prepare(req);
2556 struct stat buf;
2557 char *path;
2558 int err;
2560 memset(&buf, 0, sizeof(buf));
2562 if (fi != NULL && f->fs->op.fgetattr)
2563 err = get_path_nullok(f, ino, &path);
2564 else
2565 err = get_path(f, ino, &path);
2566 if (!err) {
2567 struct fuse_intr_data d;
2568 fuse_prepare_interrupt(f, req, &d);
2569 if (fi)
2570 err = fuse_fs_fgetattr(f->fs, path, &buf, fi);
2571 else
2572 err = fuse_fs_getattr(f->fs, path, &buf);
2573 fuse_finish_interrupt(f, req, &d);
2574 free_path(f, ino, path);
2576 if (!err) {
2577 struct node *node;
2579 pthread_mutex_lock(&f->lock);
2580 node = get_node(f, ino);
2581 if (node->is_hidden && buf.st_nlink > 0)
2582 buf.st_nlink--;
2583 if (f->conf.auto_cache)
2584 update_stat(node, &buf);
2585 pthread_mutex_unlock(&f->lock);
2586 set_stat(f, ino, &buf);
2587 fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2588 } else
2589 reply_err(req, err);
2592 int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode)
2594 fuse_get_context()->private_data = fs->user_data;
2595 if (fs->op.chmod)
2596 return fs->op.chmod(path, mode);
2597 else
2598 return -ENOSYS;
2601 static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
2602 int valid, struct fuse_file_info *fi)
2604 struct fuse *f = req_fuse_prepare(req);
2605 struct stat buf;
2606 char *path;
2607 int err;
2609 if (valid == FUSE_SET_ATTR_SIZE && fi != NULL &&
2610 f->fs->op.ftruncate && f->fs->op.fgetattr)
2611 err = get_path_nullok(f, ino, &path);
2612 else
2613 err = get_path(f, ino, &path);
2614 if (!err) {
2615 struct fuse_intr_data d;
2616 fuse_prepare_interrupt(f, req, &d);
2617 err = 0;
2618 if (!err && (valid & FUSE_SET_ATTR_MODE))
2619 err = fuse_fs_chmod(f->fs, path, attr->st_mode);
2620 if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2621 uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2622 attr->st_uid : (uid_t) -1;
2623 gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2624 attr->st_gid : (gid_t) -1;
2625 err = fuse_fs_chown(f->fs, path, uid, gid);
2627 if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2628 if (fi)
2629 err = fuse_fs_ftruncate(f->fs, path,
2630 attr->st_size, fi);
2631 else
2632 err = fuse_fs_truncate(f->fs, path,
2633 attr->st_size);
2635 #ifdef HAVE_UTIMENSAT
2636 if (!err &&
2637 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2638 struct timespec tv[2];
2640 tv[0].tv_sec = 0;
2641 tv[1].tv_sec = 0;
2642 tv[0].tv_nsec = UTIME_OMIT;
2643 tv[1].tv_nsec = UTIME_OMIT;
2645 if (valid & FUSE_SET_ATTR_ATIME_NOW)
2646 tv[0].tv_nsec = UTIME_NOW;
2647 else if (valid & FUSE_SET_ATTR_ATIME)
2648 tv[0] = attr->st_atim;
2650 if (valid & FUSE_SET_ATTR_MTIME_NOW)
2651 tv[1].tv_nsec = UTIME_NOW;
2652 else if (valid & FUSE_SET_ATTR_MTIME)
2653 tv[1] = attr->st_mtim;
2655 err = fuse_fs_utimens(f->fs, path, tv);
2656 } else
2657 #endif
2658 if (!err &&
2659 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2660 (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2661 struct timespec tv[2];
2662 tv[0].tv_sec = attr->st_atime;
2663 tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2664 tv[1].tv_sec = attr->st_mtime;
2665 tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2666 err = fuse_fs_utimens(f->fs, path, tv);
2668 if (!err) {
2669 if (fi)
2670 err = fuse_fs_fgetattr(f->fs, path, &buf, fi);
2671 else
2672 err = fuse_fs_getattr(f->fs, path, &buf);
2674 fuse_finish_interrupt(f, req, &d);
2675 free_path(f, ino, path);
2677 if (!err) {
2678 if (f->conf.auto_cache) {
2679 pthread_mutex_lock(&f->lock);
2680 update_stat(get_node(f, ino), &buf);
2681 pthread_mutex_unlock(&f->lock);
2683 set_stat(f, ino, &buf);
2684 fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2685 } else
2686 reply_err(req, err);
2689 static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
2691 struct fuse *f = req_fuse_prepare(req);
2692 char *path;
2693 int err;
2695 err = get_path(f, ino, &path);
2696 if (!err) {
2697 struct fuse_intr_data d;
2699 fuse_prepare_interrupt(f, req, &d);
2700 err = fuse_fs_access(f->fs, path, mask);
2701 fuse_finish_interrupt(f, req, &d);
2702 free_path(f, ino, path);
2704 reply_err(req, err);
2707 static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
2709 struct fuse *f = req_fuse_prepare(req);
2710 char linkname[PATH_MAX + 1];
2711 char *path;
2712 int err;
2714 err = get_path(f, ino, &path);
2715 if (!err) {
2716 struct fuse_intr_data d;
2717 fuse_prepare_interrupt(f, req, &d);
2718 err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
2719 fuse_finish_interrupt(f, req, &d);
2720 free_path(f, ino, path);
2722 if (!err) {
2723 linkname[PATH_MAX] = '\0';
2724 fuse_reply_readlink(req, linkname);
2725 } else
2726 reply_err(req, err);
2729 static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
2730 mode_t mode, dev_t rdev)
2732 struct fuse *f = req_fuse_prepare(req);
2733 struct fuse_entry_param e;
2734 char *path;
2735 int err;
2737 err = get_path_name(f, parent, name, &path);
2738 if (!err) {
2739 struct fuse_intr_data d;
2741 fuse_prepare_interrupt(f, req, &d);
2742 err = -ENOSYS;
2743 if (S_ISREG(mode)) {
2744 struct fuse_file_info fi;
2746 memset(&fi, 0, sizeof(fi));
2747 fi.flags = O_CREAT | O_EXCL | O_WRONLY;
2748 err = fuse_fs_create(f->fs, path, mode, &fi);
2749 if (!err) {
2750 err = lookup_path(f, parent, name, path, &e,
2751 &fi);
2752 fuse_fs_release(f->fs, path, &fi);
2755 if (err == -ENOSYS) {
2756 err = fuse_fs_mknod(f->fs, path, mode, rdev);
2757 if (!err)
2758 err = lookup_path(f, parent, name, path, &e,
2759 NULL);
2761 fuse_finish_interrupt(f, req, &d);
2762 free_path(f, parent, path);
2764 reply_entry(req, &e, err);
2767 static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
2768 mode_t mode)
2770 struct fuse *f = req_fuse_prepare(req);
2771 struct fuse_entry_param e;
2772 char *path;
2773 int err;
2775 err = get_path_name(f, parent, name, &path);
2776 if (!err) {
2777 struct fuse_intr_data d;
2779 fuse_prepare_interrupt(f, req, &d);
2780 err = fuse_fs_mkdir(f->fs, path, mode);
2781 if (!err)
2782 err = lookup_path(f, parent, name, path, &e, NULL);
2783 fuse_finish_interrupt(f, req, &d);
2784 free_path(f, parent, path);
2786 reply_entry(req, &e, err);
2789 static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
2790 const char *name)
2792 struct fuse *f = req_fuse_prepare(req);
2793 struct node *wnode;
2794 char *path;
2795 int err;
2797 err = get_path_wrlock(f, parent, name, &path, &wnode);
2798 if (!err) {
2799 struct fuse_intr_data d;
2801 fuse_prepare_interrupt(f, req, &d);
2802 if (!f->conf.hard_remove && is_open(f, parent, name)) {
2803 err = hide_node(f, path, parent, name);
2804 } else {
2805 err = fuse_fs_unlink(f->fs, path);
2806 if (!err)
2807 remove_node(f, parent, name);
2809 fuse_finish_interrupt(f, req, &d);
2810 free_path_wrlock(f, parent, wnode, path);
2812 reply_err(req, err);
2815 static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
2817 struct fuse *f = req_fuse_prepare(req);
2818 struct node *wnode;
2819 char *path;
2820 int err;
2822 err = get_path_wrlock(f, parent, name, &path, &wnode);
2823 if (!err) {
2824 struct fuse_intr_data d;
2826 fuse_prepare_interrupt(f, req, &d);
2827 err = fuse_fs_rmdir(f->fs, path);
2828 fuse_finish_interrupt(f, req, &d);
2829 if (!err)
2830 remove_node(f, parent, name);
2831 free_path_wrlock(f, parent, wnode, path);
2833 reply_err(req, err);
2836 static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
2837 fuse_ino_t parent, const char *name)
2839 struct fuse *f = req_fuse_prepare(req);
2840 struct fuse_entry_param e;
2841 char *path;
2842 int err;
2844 err = get_path_name(f, parent, name, &path);
2845 if (!err) {
2846 struct fuse_intr_data d;
2848 fuse_prepare_interrupt(f, req, &d);
2849 err = fuse_fs_symlink(f->fs, linkname, path);
2850 if (!err)
2851 err = lookup_path(f, parent, name, path, &e, NULL);
2852 fuse_finish_interrupt(f, req, &d);
2853 free_path(f, parent, path);
2855 reply_entry(req, &e, err);
2858 static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
2859 const char *oldname, fuse_ino_t newdir,
2860 const char *newname)
2862 struct fuse *f = req_fuse_prepare(req);
2863 char *oldpath;
2864 char *newpath;
2865 struct node *wnode1;
2866 struct node *wnode2;
2867 int err;
2869 err = get_path2(f, olddir, oldname, newdir, newname,
2870 &oldpath, &newpath, &wnode1, &wnode2);
2871 if (!err) {
2872 struct fuse_intr_data d;
2873 err = 0;
2874 fuse_prepare_interrupt(f, req, &d);
2875 if (!f->conf.hard_remove && is_open(f, newdir, newname))
2876 err = hide_node(f, newpath, newdir, newname);
2877 if (!err) {
2878 err = fuse_fs_rename(f->fs, oldpath, newpath);
2879 if (!err)
2880 err = rename_node(f, olddir, oldname, newdir,
2881 newname, 0);
2883 fuse_finish_interrupt(f, req, &d);
2884 free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
2886 reply_err(req, err);
2889 static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
2890 const char *newname)
2892 struct fuse *f = req_fuse_prepare(req);
2893 struct fuse_entry_param e;
2894 char *oldpath;
2895 char *newpath;
2896 int err;
2898 err = get_path2(f, ino, NULL, newparent, newname,
2899 &oldpath, &newpath, NULL, NULL);
2900 if (!err) {
2901 struct fuse_intr_data d;
2903 fuse_prepare_interrupt(f, req, &d);
2904 err = fuse_fs_link(f->fs, oldpath, newpath);
2905 if (!err)
2906 err = lookup_path(f, newparent, newname, newpath,
2907 &e, NULL);
2908 fuse_finish_interrupt(f, req, &d);
2909 free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
2911 reply_entry(req, &e, err);
2914 static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
2915 struct fuse_file_info *fi)
2917 struct node *node;
2918 int unlink_hidden = 0;
2920 fuse_fs_release(f->fs, path, fi);
2922 pthread_mutex_lock(&f->lock);
2923 node = get_node(f, ino);
2924 assert(node->open_count > 0);
2925 --node->open_count;
2926 if (node->is_hidden && !node->open_count) {
2927 unlink_hidden = 1;
2928 node->is_hidden = 0;
2930 pthread_mutex_unlock(&f->lock);
2932 if(unlink_hidden) {
2933 if (path) {
2934 fuse_fs_unlink(f->fs, path);
2935 } else if (f->conf.nopath) {
2936 char *unlinkpath;
2938 if (get_path(f, ino, &unlinkpath) == 0)
2939 fuse_fs_unlink(f->fs, unlinkpath);
2941 free_path(f, ino, unlinkpath);
2946 static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
2947 const char *name, mode_t mode,
2948 struct fuse_file_info *fi)
2950 struct fuse *f = req_fuse_prepare(req);
2951 struct fuse_intr_data d;
2952 struct fuse_entry_param e;
2953 char *path;
2954 int err;
2956 err = get_path_name(f, parent, name, &path);
2957 if (!err) {
2958 fuse_prepare_interrupt(f, req, &d);
2959 err = fuse_fs_create(f->fs, path, mode, fi);
2960 if (!err) {
2961 err = lookup_path(f, parent, name, path, &e, fi);
2962 if (err)
2963 fuse_fs_release(f->fs, path, fi);
2964 else if (!S_ISREG(e.attr.st_mode)) {
2965 err = -EIO;
2966 fuse_fs_release(f->fs, path, fi);
2967 forget_node(f, e.ino, 1);
2968 } else {
2969 if (f->conf.direct_io)
2970 fi->direct_io = 1;
2971 if (f->conf.kernel_cache)
2972 fi->keep_cache = 1;
2976 fuse_finish_interrupt(f, req, &d);
2978 if (!err) {
2979 pthread_mutex_lock(&f->lock);
2980 get_node(f, e.ino)->open_count++;
2981 pthread_mutex_unlock(&f->lock);
2982 if (fuse_reply_create(req, &e, fi) == -ENOENT) {
2983 /* The open syscall was interrupted, so it
2984 must be cancelled */
2985 fuse_do_release(f, e.ino, path, fi);
2986 forget_node(f, e.ino, 1);
2988 } else {
2989 reply_err(req, err);
2992 free_path(f, parent, path);
2995 static double diff_timespec(const struct timespec *t1,
2996 const struct timespec *t2)
2998 return (t1->tv_sec - t2->tv_sec) +
2999 ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
3002 static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
3003 struct fuse_file_info *fi)
3005 struct node *node;
3007 pthread_mutex_lock(&f->lock);
3008 node = get_node(f, ino);
3009 if (node->cache_valid) {
3010 struct timespec now;
3012 curr_time(&now);
3013 if (diff_timespec(&now, &node->stat_updated) >
3014 f->conf.ac_attr_timeout) {
3015 struct stat stbuf;
3016 int err;
3017 pthread_mutex_unlock(&f->lock);
3018 err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
3019 pthread_mutex_lock(&f->lock);
3020 if (!err)
3021 update_stat(node, &stbuf);
3022 else
3023 node->cache_valid = 0;
3026 if (node->cache_valid)
3027 fi->keep_cache = 1;
3029 node->cache_valid = 1;
3030 pthread_mutex_unlock(&f->lock);
3033 static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
3034 struct fuse_file_info *fi)
3036 struct fuse *f = req_fuse_prepare(req);
3037 struct fuse_intr_data d;
3038 char *path;
3039 int err;
3041 err = get_path(f, ino, &path);
3042 if (!err) {
3043 fuse_prepare_interrupt(f, req, &d);
3044 err = fuse_fs_open(f->fs, path, fi);
3045 if (!err) {
3046 if (f->conf.direct_io)
3047 fi->direct_io = 1;
3048 if (f->conf.kernel_cache)
3049 fi->keep_cache = 1;
3051 if (f->conf.auto_cache)
3052 open_auto_cache(f, ino, path, fi);
3054 fuse_finish_interrupt(f, req, &d);
3056 if (!err) {
3057 pthread_mutex_lock(&f->lock);
3058 get_node(f, ino)->open_count++;
3059 pthread_mutex_unlock(&f->lock);
3060 if (fuse_reply_open(req, fi) == -ENOENT) {
3061 /* The open syscall was interrupted, so it
3062 must be cancelled */
3063 fuse_do_release(f, ino, path, fi);
3065 } else
3066 reply_err(req, err);
3068 free_path(f, ino, path);
3071 static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
3072 off_t off, struct fuse_file_info *fi)
3074 struct fuse *f = req_fuse_prepare(req);
3075 struct fuse_bufvec *buf = NULL;
3076 char *path;
3077 int res;
3079 res = get_path_nullok(f, ino, &path);
3080 if (res == 0) {
3081 struct fuse_intr_data d;
3083 fuse_prepare_interrupt(f, req, &d);
3084 res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3085 fuse_finish_interrupt(f, req, &d);
3086 free_path(f, ino, path);
3089 if (res == 0)
3090 fuse_reply_data(req, buf, FUSE_BUF_SPLICE_MOVE);
3091 else
3092 reply_err(req, res);
3094 fuse_free_buf(buf);
3097 static void fuse_lib_write_buf(fuse_req_t req, fuse_ino_t ino,
3098 struct fuse_bufvec *buf, off_t off,
3099 struct fuse_file_info *fi)
3101 struct fuse *f = req_fuse_prepare(req);
3102 char *path;
3103 int res;
3105 res = get_path_nullok(f, ino, &path);
3106 if (res == 0) {
3107 struct fuse_intr_data d;
3109 fuse_prepare_interrupt(f, req, &d);
3110 res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3111 fuse_finish_interrupt(f, req, &d);
3112 free_path(f, ino, path);
3115 if (res >= 0)
3116 fuse_reply_write(req, res);
3117 else
3118 reply_err(req, res);
3121 static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
3122 struct fuse_file_info *fi)
3124 struct fuse *f = req_fuse_prepare(req);
3125 char *path;
3126 int err;
3128 err = get_path_nullok(f, ino, &path);
3129 if (!err) {
3130 struct fuse_intr_data d;
3132 fuse_prepare_interrupt(f, req, &d);
3133 err = fuse_fs_fsync(f->fs, path, datasync, fi);
3134 fuse_finish_interrupt(f, req, &d);
3135 free_path(f, ino, path);
3137 reply_err(req, err);
3140 static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
3141 struct fuse_file_info *fi)
3143 struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
3144 memset(fi, 0, sizeof(struct fuse_file_info));
3145 fi->fh = dh->fh;
3146 fi->fh_old = dh->fh;
3147 return dh;
3150 static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
3151 struct fuse_file_info *llfi)
3153 struct fuse *f = req_fuse_prepare(req);
3154 struct fuse_intr_data d;
3155 struct fuse_dh *dh;
3156 struct fuse_file_info fi;
3157 char *path;
3158 int err;
3160 dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
3161 if (dh == NULL) {
3162 reply_err(req, -ENOMEM);
3163 return;
3165 memset(dh, 0, sizeof(struct fuse_dh));
3166 dh->fuse = f;
3167 dh->contents = NULL;
3168 dh->len = 0;
3169 dh->filled = 0;
3170 dh->nodeid = ino;
3171 fuse_mutex_init(&dh->lock);
3173 llfi->fh = (uintptr_t) dh;
3175 memset(&fi, 0, sizeof(fi));
3176 fi.flags = llfi->flags;
3178 err = get_path(f, ino, &path);
3179 if (!err) {
3180 fuse_prepare_interrupt(f, req, &d);
3181 err = fuse_fs_opendir(f->fs, path, &fi);
3182 fuse_finish_interrupt(f, req, &d);
3183 dh->fh = fi.fh;
3185 if (!err) {
3186 if (fuse_reply_open(req, llfi) == -ENOENT) {
3187 /* The opendir syscall was interrupted, so it
3188 must be cancelled */
3189 fuse_fs_releasedir(f->fs, path, &fi);
3190 pthread_mutex_destroy(&dh->lock);
3191 free(dh);
3193 } else {
3194 reply_err(req, err);
3195 pthread_mutex_destroy(&dh->lock);
3196 free(dh);
3198 free_path(f, ino, path);
3201 static int extend_contents(struct fuse_dh *dh, unsigned minsize)
3203 if (minsize > dh->size) {
3204 char *newptr;
3205 unsigned newsize = dh->size;
3206 if (!newsize)
3207 newsize = 1024;
3208 while (newsize < minsize) {
3209 if (newsize >= 0x80000000)
3210 newsize = 0xffffffff;
3211 else
3212 newsize *= 2;
3215 newptr = (char *) realloc(dh->contents, newsize);
3216 if (!newptr) {
3217 dh->error = -ENOMEM;
3218 return -1;
3220 dh->contents = newptr;
3221 dh->size = newsize;
3223 return 0;
3226 static int fill_dir(void *dh_, const char *name, const struct stat *statp,
3227 off_t off)
3229 struct fuse_dh *dh = (struct fuse_dh *) dh_;
3230 struct stat stbuf;
3231 size_t newlen;
3233 if (statp)
3234 stbuf = *statp;
3235 else {
3236 memset(&stbuf, 0, sizeof(stbuf));
3237 stbuf.st_ino = FUSE_UNKNOWN_INO;
3240 if (!dh->fuse->conf.use_ino) {
3241 stbuf.st_ino = FUSE_UNKNOWN_INO;
3242 if (dh->fuse->conf.readdir_ino) {
3243 struct node *node;
3244 pthread_mutex_lock(&dh->fuse->lock);
3245 node = lookup_node(dh->fuse, dh->nodeid, name);
3246 if (node)
3247 stbuf.st_ino = (ino_t) node->nodeid;
3248 pthread_mutex_unlock(&dh->fuse->lock);
3252 if (off) {
3253 if (extend_contents(dh, dh->needlen) == -1)
3254 return 1;
3256 dh->filled = 0;
3257 newlen = dh->len +
3258 fuse_add_direntry(dh->req, dh->contents + dh->len,
3259 dh->needlen - dh->len, name,
3260 &stbuf, off);
3261 if (newlen > dh->needlen)
3262 return 1;
3263 } else {
3264 newlen = dh->len +
3265 fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
3266 if (extend_contents(dh, newlen) == -1)
3267 return 1;
3269 fuse_add_direntry(dh->req, dh->contents + dh->len,
3270 dh->size - dh->len, name, &stbuf, newlen);
3272 dh->len = newlen;
3273 return 0;
3276 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3277 size_t size, off_t off, struct fuse_dh *dh,
3278 struct fuse_file_info *fi)
3280 char *path;
3281 int err;
3283 if (f->fs->op.readdir)
3284 err = get_path_nullok(f, ino, &path);
3285 else
3286 err = get_path(f, ino, &path);
3287 if (!err) {
3288 struct fuse_intr_data d;
3290 dh->len = 0;
3291 dh->error = 0;
3292 dh->needlen = size;
3293 dh->filled = 1;
3294 dh->req = req;
3295 fuse_prepare_interrupt(f, req, &d);
3296 err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
3297 fuse_finish_interrupt(f, req, &d);
3298 dh->req = NULL;
3299 if (!err)
3300 err = dh->error;
3301 if (err)
3302 dh->filled = 0;
3303 free_path(f, ino, path);
3305 return err;
3308 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3309 off_t off, struct fuse_file_info *llfi)
3311 struct fuse *f = req_fuse_prepare(req);
3312 struct fuse_file_info fi;
3313 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3315 pthread_mutex_lock(&dh->lock);
3316 /* According to SUS, directory contents need to be refreshed on
3317 rewinddir() */
3318 if (!off)
3319 dh->filled = 0;
3321 if (!dh->filled) {
3322 int err = readdir_fill(f, req, ino, size, off, dh, &fi);
3323 if (err) {
3324 reply_err(req, err);
3325 goto out;
3328 if (dh->filled) {
3329 if (off < dh->len) {
3330 if (off + size > dh->len)
3331 size = dh->len - off;
3332 } else
3333 size = 0;
3334 } else {
3335 size = dh->len;
3336 off = 0;
3338 fuse_reply_buf(req, dh->contents + off, size);
3339 out:
3340 pthread_mutex_unlock(&dh->lock);
3343 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3344 struct fuse_file_info *llfi)
3346 struct fuse *f = req_fuse_prepare(req);
3347 struct fuse_intr_data d;
3348 struct fuse_file_info fi;
3349 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3350 char *path;
3352 get_path_nullok(f, ino, &path);
3354 fuse_prepare_interrupt(f, req, &d);
3355 fuse_fs_releasedir(f->fs, path, &fi);
3356 fuse_finish_interrupt(f, req, &d);
3357 free_path(f, ino, path);
3359 pthread_mutex_lock(&dh->lock);
3360 pthread_mutex_unlock(&dh->lock);
3361 pthread_mutex_destroy(&dh->lock);
3362 free(dh->contents);
3363 free(dh);
3364 reply_err(req, 0);
3367 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3368 struct fuse_file_info *llfi)
3370 struct fuse *f = req_fuse_prepare(req);
3371 struct fuse_file_info fi;
3372 char *path;
3373 int err;
3375 get_dirhandle(llfi, &fi);
3377 err = get_path_nullok(f, ino, &path);
3378 if (!err) {
3379 struct fuse_intr_data d;
3380 fuse_prepare_interrupt(f, req, &d);
3381 err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3382 fuse_finish_interrupt(f, req, &d);
3383 free_path(f, ino, path);
3385 reply_err(req, err);
3388 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3390 struct fuse *f = req_fuse_prepare(req);
3391 struct statvfs buf;
3392 char *path = NULL;
3393 int err = 0;
3395 memset(&buf, 0, sizeof(buf));
3396 if (ino)
3397 err = get_path(f, ino, &path);
3399 if (!err) {
3400 struct fuse_intr_data d;
3401 fuse_prepare_interrupt(f, req, &d);
3402 err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3403 fuse_finish_interrupt(f, req, &d);
3404 free_path(f, ino, path);
3407 if (!err)
3408 fuse_reply_statfs(req, &buf);
3409 else
3410 reply_err(req, err);
3413 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3414 const char *value, size_t size, int flags)
3416 struct fuse *f = req_fuse_prepare(req);
3417 char *path;
3418 int err;
3420 err = get_path(f, ino, &path);
3421 if (!err) {
3422 struct fuse_intr_data d;
3423 fuse_prepare_interrupt(f, req, &d);
3424 err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3425 fuse_finish_interrupt(f, req, &d);
3426 free_path(f, ino, path);
3428 reply_err(req, err);
3431 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3432 const char *name, char *value, size_t size)
3434 int err;
3435 char *path;
3437 err = get_path(f, ino, &path);
3438 if (!err) {
3439 struct fuse_intr_data d;
3440 fuse_prepare_interrupt(f, req, &d);
3441 err = fuse_fs_getxattr(f->fs, path, name, value, size);
3442 fuse_finish_interrupt(f, req, &d);
3443 free_path(f, ino, path);
3445 return err;
3448 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3449 size_t size)
3451 struct fuse *f = req_fuse_prepare(req);
3452 int res;
3454 if (size) {
3455 char *value = (char *) malloc(size);
3456 if (value == NULL) {
3457 reply_err(req, -ENOMEM);
3458 return;
3460 res = common_getxattr(f, req, ino, name, value, size);
3461 if (res > 0)
3462 fuse_reply_buf(req, value, res);
3463 else
3464 reply_err(req, res);
3465 free(value);
3466 } else {
3467 res = common_getxattr(f, req, ino, name, NULL, 0);
3468 if (res >= 0)
3469 fuse_reply_xattr(req, res);
3470 else
3471 reply_err(req, res);
3475 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3476 char *list, size_t size)
3478 char *path;
3479 int err;
3481 err = get_path(f, ino, &path);
3482 if (!err) {
3483 struct fuse_intr_data d;
3484 fuse_prepare_interrupt(f, req, &d);
3485 err = fuse_fs_listxattr(f->fs, path, list, size);
3486 fuse_finish_interrupt(f, req, &d);
3487 free_path(f, ino, path);
3489 return err;
3492 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3494 struct fuse *f = req_fuse_prepare(req);
3495 int res;
3497 if (size) {
3498 char *list = (char *) malloc(size);
3499 if (list == NULL) {
3500 reply_err(req, -ENOMEM);
3501 return;
3503 res = common_listxattr(f, req, ino, list, size);
3504 if (res > 0)
3505 fuse_reply_buf(req, list, res);
3506 else
3507 reply_err(req, res);
3508 free(list);
3509 } else {
3510 res = common_listxattr(f, req, ino, NULL, 0);
3511 if (res >= 0)
3512 fuse_reply_xattr(req, res);
3513 else
3514 reply_err(req, res);
3518 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3519 const char *name)
3521 struct fuse *f = req_fuse_prepare(req);
3522 char *path;
3523 int err;
3525 err = get_path(f, ino, &path);
3526 if (!err) {
3527 struct fuse_intr_data d;
3528 fuse_prepare_interrupt(f, req, &d);
3529 err = fuse_fs_removexattr(f->fs, path, name);
3530 fuse_finish_interrupt(f, req, &d);
3531 free_path(f, ino, path);
3533 reply_err(req, err);
3536 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3538 struct lock *l;
3540 for (l = node->locks; l; l = l->next)
3541 if (l->owner != lock->owner &&
3542 lock->start <= l->end && l->start <= lock->end &&
3543 (l->type == F_WRLCK || lock->type == F_WRLCK))
3544 break;
3546 return l;
3549 static void delete_lock(struct lock **lockp)
3551 struct lock *l = *lockp;
3552 *lockp = l->next;
3553 free(l);
3556 static void insert_lock(struct lock **pos, struct lock *lock)
3558 lock->next = *pos;
3559 *pos = lock;
3562 static int locks_insert(struct node *node, struct lock *lock)
3564 struct lock **lp;
3565 struct lock *newl1 = NULL;
3566 struct lock *newl2 = NULL;
3568 if (lock->type != F_UNLCK || lock->start != 0 ||
3569 lock->end != OFFSET_MAX) {
3570 newl1 = malloc(sizeof(struct lock));
3571 newl2 = malloc(sizeof(struct lock));
3573 if (!newl1 || !newl2) {
3574 free(newl1);
3575 free(newl2);
3576 return -ENOLCK;
3580 for (lp = &node->locks; *lp;) {
3581 struct lock *l = *lp;
3582 if (l->owner != lock->owner)
3583 goto skip;
3585 if (lock->type == l->type) {
3586 if (l->end < lock->start - 1)
3587 goto skip;
3588 if (lock->end < l->start - 1)
3589 break;
3590 if (l->start <= lock->start && lock->end <= l->end)
3591 goto out;
3592 if (l->start < lock->start)
3593 lock->start = l->start;
3594 if (lock->end < l->end)
3595 lock->end = l->end;
3596 goto delete;
3597 } else {
3598 if (l->end < lock->start)
3599 goto skip;
3600 if (lock->end < l->start)
3601 break;
3602 if (lock->start <= l->start && l->end <= lock->end)
3603 goto delete;
3604 if (l->end <= lock->end) {
3605 l->end = lock->start - 1;
3606 goto skip;
3608 if (lock->start <= l->start) {
3609 l->start = lock->end + 1;
3610 break;
3612 *newl2 = *l;
3613 newl2->start = lock->end + 1;
3614 l->end = lock->start - 1;
3615 insert_lock(&l->next, newl2);
3616 newl2 = NULL;
3618 skip:
3619 lp = &l->next;
3620 continue;
3622 delete:
3623 delete_lock(lp);
3625 if (lock->type != F_UNLCK) {
3626 *newl1 = *lock;
3627 insert_lock(lp, newl1);
3628 newl1 = NULL;
3630 out:
3631 free(newl1);
3632 free(newl2);
3633 return 0;
3636 static void flock_to_lock(struct flock *flock, struct lock *lock)
3638 memset(lock, 0, sizeof(struct lock));
3639 lock->type = flock->l_type;
3640 lock->start = flock->l_start;
3641 lock->end =
3642 flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
3643 lock->pid = flock->l_pid;
3646 static void lock_to_flock(struct lock *lock, struct flock *flock)
3648 flock->l_type = lock->type;
3649 flock->l_start = lock->start;
3650 flock->l_len =
3651 (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
3652 flock->l_pid = lock->pid;
3655 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3656 const char *path, struct fuse_file_info *fi)
3658 struct fuse_intr_data d;
3659 struct flock lock;
3660 struct lock l;
3661 int err;
3662 int errlock;
3664 fuse_prepare_interrupt(f, req, &d);
3665 memset(&lock, 0, sizeof(lock));
3666 lock.l_type = F_UNLCK;
3667 lock.l_whence = SEEK_SET;
3668 err = fuse_fs_flush(f->fs, path, fi);
3669 errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
3670 fuse_finish_interrupt(f, req, &d);
3672 if (errlock != -ENOSYS) {
3673 flock_to_lock(&lock, &l);
3674 l.owner = fi->lock_owner;
3675 pthread_mutex_lock(&f->lock);
3676 locks_insert(get_node(f, ino), &l);
3677 pthread_mutex_unlock(&f->lock);
3679 /* if op.lock() is defined FLUSH is needed regardless
3680 of op.flush() */
3681 if (err == -ENOSYS)
3682 err = 0;
3684 return err;
3687 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
3688 struct fuse_file_info *fi)
3690 struct fuse *f = req_fuse_prepare(req);
3691 struct fuse_intr_data d;
3692 char *path;
3693 int err = 0;
3695 get_path_nullok(f, ino, &path);
3696 if (fi->flush) {
3697 err = fuse_flush_common(f, req, ino, path, fi);
3698 if (err == -ENOSYS)
3699 err = 0;
3702 fuse_prepare_interrupt(f, req, &d);
3703 fuse_do_release(f, ino, path, fi);
3704 fuse_finish_interrupt(f, req, &d);
3705 free_path(f, ino, path);
3707 reply_err(req, err);
3710 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
3711 struct fuse_file_info *fi)
3713 struct fuse *f = req_fuse_prepare(req);
3714 char *path;
3715 int err;
3717 get_path_nullok(f, ino, &path);
3718 err = fuse_flush_common(f, req, ino, path, fi);
3719 free_path(f, ino, path);
3721 reply_err(req, err);
3724 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
3725 struct fuse_file_info *fi, struct flock *lock,
3726 int cmd)
3728 struct fuse *f = req_fuse_prepare(req);
3729 char *path;
3730 int err;
3732 err = get_path_nullok(f, ino, &path);
3733 if (!err) {
3734 struct fuse_intr_data d;
3735 fuse_prepare_interrupt(f, req, &d);
3736 err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
3737 fuse_finish_interrupt(f, req, &d);
3738 free_path(f, ino, path);
3740 return err;
3743 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
3744 struct fuse_file_info *fi, struct flock *lock)
3746 int err;
3747 struct lock l;
3748 struct lock *conflict;
3749 struct fuse *f = req_fuse(req);
3751 flock_to_lock(lock, &l);
3752 l.owner = fi->lock_owner;
3753 pthread_mutex_lock(&f->lock);
3754 conflict = locks_conflict(get_node(f, ino), &l);
3755 if (conflict)
3756 lock_to_flock(conflict, lock);
3757 pthread_mutex_unlock(&f->lock);
3758 if (!conflict)
3759 err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
3760 else
3761 err = 0;
3763 if (!err)
3764 fuse_reply_lock(req, lock);
3765 else
3766 reply_err(req, err);
3769 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
3770 struct fuse_file_info *fi, struct flock *lock,
3771 int sleep)
3773 int err = fuse_lock_common(req, ino, fi, lock,
3774 sleep ? F_SETLKW : F_SETLK);
3775 if (!err) {
3776 struct fuse *f = req_fuse(req);
3777 struct lock l;
3778 flock_to_lock(lock, &l);
3779 l.owner = fi->lock_owner;
3780 pthread_mutex_lock(&f->lock);
3781 locks_insert(get_node(f, ino), &l);
3782 pthread_mutex_unlock(&f->lock);
3784 reply_err(req, err);
3787 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
3788 struct fuse_file_info *fi, int op)
3790 struct fuse *f = req_fuse_prepare(req);
3791 char *path;
3792 int err;
3794 err = get_path_nullok(f, ino, &path);
3795 if (err == 0) {
3796 struct fuse_intr_data d;
3797 fuse_prepare_interrupt(f, req, &d);
3798 err = fuse_fs_flock(f->fs, path, fi, op);
3799 fuse_finish_interrupt(f, req, &d);
3800 free_path(f, ino, path);
3802 reply_err(req, err);
3805 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
3806 uint64_t idx)
3808 struct fuse *f = req_fuse_prepare(req);
3809 struct fuse_intr_data d;
3810 char *path;
3811 int err;
3813 err = get_path(f, ino, &path);
3814 if (!err) {
3815 fuse_prepare_interrupt(f, req, &d);
3816 err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
3817 fuse_finish_interrupt(f, req, &d);
3818 free_path(f, ino, path);
3820 if (!err)
3821 fuse_reply_bmap(req, idx);
3822 else
3823 reply_err(req, err);
3826 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
3827 struct fuse_file_info *fi, unsigned int flags,
3828 const void *in_buf, size_t in_bufsz,
3829 size_t out_bufsz)
3831 struct fuse *f = req_fuse_prepare(req);
3832 struct fuse_intr_data d;
3833 char *path, *out_buf = NULL;
3834 int err;
3836 err = -EPERM;
3837 if (flags & FUSE_IOCTL_UNRESTRICTED)
3838 goto err;
3840 if (out_bufsz) {
3841 err = -ENOMEM;
3842 out_buf = malloc(out_bufsz);
3843 if (!out_buf)
3844 goto err;
3847 assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
3848 if (out_buf)
3849 memcpy(out_buf, in_buf, in_bufsz);
3851 err = get_path_nullok(f, ino, &path);
3852 if (err)
3853 goto err;
3855 fuse_prepare_interrupt(f, req, &d);
3857 err = fuse_fs_ioctl(f->fs, path, cmd, arg, fi, flags,
3858 out_buf ?: (void *)in_buf);
3860 fuse_finish_interrupt(f, req, &d);
3861 free_path(f, ino, path);
3863 fuse_reply_ioctl(req, err, out_buf, out_bufsz);
3864 goto out;
3865 err:
3866 reply_err(req, err);
3867 out:
3868 free(out_buf);
3871 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
3872 struct fuse_file_info *fi, struct fuse_pollhandle *ph)
3874 struct fuse *f = req_fuse_prepare(req);
3875 struct fuse_intr_data d;
3876 char *path;
3877 int err;
3878 unsigned revents = 0;
3880 err = get_path_nullok(f, ino, &path);
3881 if (!err) {
3882 fuse_prepare_interrupt(f, req, &d);
3883 err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
3884 fuse_finish_interrupt(f, req, &d);
3885 free_path(f, ino, path);
3887 if (!err)
3888 fuse_reply_poll(req, revents);
3889 else
3890 reply_err(req, err);
3893 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
3894 off_t offset, off_t length, struct fuse_file_info *fi)
3896 struct fuse *f = req_fuse_prepare(req);
3897 struct fuse_intr_data d;
3898 char *path;
3899 int err;
3901 err = get_path_nullok(f, ino, &path);
3902 if (!err) {
3903 fuse_prepare_interrupt(f, req, &d);
3904 err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
3905 fuse_finish_interrupt(f, req, &d);
3906 free_path(f, ino, path);
3908 reply_err(req, err);
3911 static int clean_delay(struct fuse *f)
3914 * This is calculating the delay between clean runs. To
3915 * reduce the number of cleans we are doing them 10 times
3916 * within the remember window.
3918 int min_sleep = 60;
3919 int max_sleep = 3600;
3920 int sleep_time = f->conf.remember / 10;
3922 if (sleep_time > max_sleep)
3923 return max_sleep;
3924 if (sleep_time < min_sleep)
3925 return min_sleep;
3926 return sleep_time;
3929 int fuse_clean_cache(struct fuse *f)
3931 struct node_lru *lnode;
3932 struct list_head *curr, *next;
3933 struct node *node;
3934 struct timespec now;
3936 pthread_mutex_lock(&f->lock);
3938 curr_time(&now);
3940 for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
3941 double age;
3943 next = curr->next;
3944 lnode = list_entry(curr, struct node_lru, lru);
3945 node = &lnode->node;
3947 age = diff_timespec(&now, &lnode->forget_time);
3948 if (age <= f->conf.remember)
3949 break;
3951 assert(node->nlookup == 1);
3953 /* Don't forget active directories */
3954 if (node->refctr > 1)
3955 continue;
3957 node->nlookup = 0;
3958 unhash_name(f, node);
3959 unref_node(f, node);
3961 pthread_mutex_unlock(&f->lock);
3963 return clean_delay(f);
3966 static struct fuse_lowlevel_ops fuse_path_ops = {
3967 .init = fuse_lib_init,
3968 .destroy = fuse_lib_destroy,
3969 .lookup = fuse_lib_lookup,
3970 .forget = fuse_lib_forget,
3971 .forget_multi = fuse_lib_forget_multi,
3972 .getattr = fuse_lib_getattr,
3973 .setattr = fuse_lib_setattr,
3974 .access = fuse_lib_access,
3975 .readlink = fuse_lib_readlink,
3976 .mknod = fuse_lib_mknod,
3977 .mkdir = fuse_lib_mkdir,
3978 .unlink = fuse_lib_unlink,
3979 .rmdir = fuse_lib_rmdir,
3980 .symlink = fuse_lib_symlink,
3981 .rename = fuse_lib_rename,
3982 .link = fuse_lib_link,
3983 .create = fuse_lib_create,
3984 .open = fuse_lib_open,
3985 .read = fuse_lib_read,
3986 .write_buf = fuse_lib_write_buf,
3987 .flush = fuse_lib_flush,
3988 .release = fuse_lib_release,
3989 .fsync = fuse_lib_fsync,
3990 .opendir = fuse_lib_opendir,
3991 .readdir = fuse_lib_readdir,
3992 .releasedir = fuse_lib_releasedir,
3993 .fsyncdir = fuse_lib_fsyncdir,
3994 .statfs = fuse_lib_statfs,
3995 .setxattr = fuse_lib_setxattr,
3996 .getxattr = fuse_lib_getxattr,
3997 .listxattr = fuse_lib_listxattr,
3998 .removexattr = fuse_lib_removexattr,
3999 .getlk = fuse_lib_getlk,
4000 .setlk = fuse_lib_setlk,
4001 .flock = fuse_lib_flock,
4002 .bmap = fuse_lib_bmap,
4003 .ioctl = fuse_lib_ioctl,
4004 .poll = fuse_lib_poll,
4005 .fallocate = fuse_lib_fallocate,
4008 int fuse_notify_poll(struct fuse_pollhandle *ph)
4010 return fuse_lowlevel_notify_poll(ph);
4013 struct fuse_session *fuse_get_session(struct fuse *f)
4015 return f->se;
4018 static int fuse_session_loop_remember(struct fuse *f)
4020 struct fuse_session *se = f->se;
4021 int res = 0;
4022 struct timespec now;
4023 time_t next_clean;
4024 struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
4025 size_t bufsize = fuse_chan_bufsize(ch);
4026 char *buf = (char *) malloc(bufsize);
4027 struct pollfd fds = {
4028 .fd = fuse_chan_fd(ch),
4029 .events = POLLIN
4032 if (!buf) {
4033 fprintf(stderr, "fuse: failed to allocate read buffer\n");
4034 return -1;
4037 curr_time(&now);
4038 next_clean = now.tv_sec;
4039 while (!fuse_session_exited(se)) {
4040 struct fuse_chan *tmpch = ch;
4041 struct fuse_buf fbuf = {
4042 .mem = buf,
4043 .size = bufsize,
4045 unsigned timeout;
4047 curr_time(&now);
4048 if (now.tv_sec < next_clean)
4049 timeout = next_clean - now.tv_sec;
4050 else
4051 timeout = 0;
4053 res = poll(&fds, 1, timeout * 1000);
4054 if (res == -1) {
4055 if (errno == -EINTR)
4056 continue;
4057 else
4058 break;
4059 } else if (res > 0) {
4060 res = fuse_session_receive_buf(se, &fbuf, &tmpch);
4062 if (res == -EINTR)
4063 continue;
4064 if (res <= 0)
4065 break;
4067 fuse_session_process_buf(se, &fbuf, tmpch);
4068 } else {
4069 timeout = fuse_clean_cache(f);
4070 curr_time(&now);
4071 next_clean = now.tv_sec + timeout;
4075 free(buf);
4076 fuse_session_reset(se);
4077 return res < 0 ? -1 : 0;
4080 int fuse_loop(struct fuse *f)
4082 if (!f)
4083 return -1;
4085 if (lru_enabled(f))
4086 return fuse_session_loop_remember(f);
4088 return fuse_session_loop(f->se);
4091 void fuse_exit(struct fuse *f)
4093 fuse_session_exit(f->se);
4096 struct fuse_context *fuse_get_context(void)
4098 struct fuse_context_i *c = fuse_get_context_internal();
4100 if (c)
4101 return &c->ctx;
4102 else
4103 return NULL;
4106 int fuse_getgroups(int size, gid_t list[])
4108 struct fuse_context_i *c = fuse_get_context_internal();
4109 if (!c)
4110 return -EINVAL;
4112 return fuse_req_getgroups(c->req, size, list);
4115 int fuse_interrupted(void)
4117 struct fuse_context_i *c = fuse_get_context_internal();
4119 if (c)
4120 return fuse_req_interrupted(c->req);
4121 else
4122 return 0;
4125 enum {
4126 KEY_HELP,
4129 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4131 static const struct fuse_opt fuse_lib_opts[] = {
4132 FUSE_OPT_KEY("-h", KEY_HELP),
4133 FUSE_OPT_KEY("--help", KEY_HELP),
4134 FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
4135 FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
4136 FUSE_LIB_OPT("debug", debug, 1),
4137 FUSE_LIB_OPT("-d", debug, 1),
4138 FUSE_LIB_OPT("hard_remove", hard_remove, 1),
4139 FUSE_LIB_OPT("use_ino", use_ino, 1),
4140 FUSE_LIB_OPT("readdir_ino", readdir_ino, 1),
4141 FUSE_LIB_OPT("direct_io", direct_io, 1),
4142 FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
4143 FUSE_LIB_OPT("auto_cache", auto_cache, 1),
4144 FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
4145 FUSE_LIB_OPT("umask=", set_mode, 1),
4146 FUSE_LIB_OPT("umask=%o", umask, 0),
4147 FUSE_LIB_OPT("uid=", set_uid, 1),
4148 FUSE_LIB_OPT("uid=%d", uid, 0),
4149 FUSE_LIB_OPT("gid=", set_gid, 1),
4150 FUSE_LIB_OPT("gid=%d", gid, 0),
4151 FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
4152 FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
4153 FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
4154 FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
4155 FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
4156 FUSE_LIB_OPT("noforget", remember, -1),
4157 FUSE_LIB_OPT("remember=%u", remember, 0),
4158 FUSE_LIB_OPT("nopath", nopath, 1),
4159 FUSE_LIB_OPT("intr", intr, 1),
4160 FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
4161 FUSE_LIB_OPT("modules=%s", modules, 0),
4162 FUSE_OPT_END
4165 static void fuse_lib_help(void)
4167 fprintf(stderr,
4168 " -o hard_remove immediate removal (don't hide files)\n"
4169 " -o use_ino let filesystem set inode numbers\n"
4170 " -o readdir_ino try to fill in d_ino in readdir\n"
4171 " -o direct_io use direct I/O\n"
4172 " -o kernel_cache cache files in kernel\n"
4173 " -o [no]auto_cache enable caching based on modification times (off)\n"
4174 " -o umask=M set file permissions (octal)\n"
4175 " -o uid=N set file owner\n"
4176 " -o gid=N set file group\n"
4177 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4178 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4179 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4180 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4181 " -o noforget never forget cached inodes\n"
4182 " -o remember=T remember cached inodes for T seconds (0s)\n"
4183 " -o intr allow requests to be interrupted\n"
4184 " -o intr_signal=NUM signal to send on interrupt (%i)\n"
4185 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
4186 "\n", FUSE_DEFAULT_INTR_SIGNAL);
4189 static void fuse_lib_help_modules(void)
4191 struct fuse_module *m;
4192 fprintf(stderr, "\nModule options:\n");
4193 pthread_mutex_lock(&fuse_context_lock);
4194 for (m = fuse_modules; m; m = m->next) {
4195 struct fuse_fs *fs = NULL;
4196 struct fuse_fs *newfs;
4197 struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
4198 if (fuse_opt_add_arg(&args, "") != -1 &&
4199 fuse_opt_add_arg(&args, "-h") != -1) {
4200 fprintf(stderr, "\n[%s]\n", m->name);
4201 newfs = m->factory(&args, &fs);
4202 assert(newfs == NULL);
4204 fuse_opt_free_args(&args);
4206 pthread_mutex_unlock(&fuse_context_lock);
4209 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4210 struct fuse_args *outargs)
4212 (void) arg; (void) outargs;
4214 if (key == KEY_HELP) {
4215 struct fuse_config *conf = (struct fuse_config *) data;
4216 fuse_lib_help();
4217 conf->help = 1;
4220 return 1;
4223 static int fuse_init_intr_signal(int signum, int *installed)
4225 struct sigaction old_sa;
4227 if (sigaction(signum, NULL, &old_sa) == -1) {
4228 perror("fuse: cannot get old signal handler");
4229 return -1;
4232 if (old_sa.sa_handler == SIG_DFL) {
4233 struct sigaction sa;
4235 memset(&sa, 0, sizeof(struct sigaction));
4236 sa.sa_handler = fuse_intr_sighandler;
4237 sigemptyset(&sa.sa_mask);
4239 if (sigaction(signum, &sa, NULL) == -1) {
4240 perror("fuse: cannot set interrupt signal handler");
4241 return -1;
4243 *installed = 1;
4245 return 0;
4248 static void fuse_restore_intr_signal(int signum)
4250 struct sigaction sa;
4252 memset(&sa, 0, sizeof(struct sigaction));
4253 sa.sa_handler = SIG_DFL;
4254 sigaction(signum, &sa, NULL);
4258 static int fuse_push_module(struct fuse *f, const char *module,
4259 struct fuse_args *args)
4261 struct fuse_fs *fs[2] = { f->fs, NULL };
4262 struct fuse_fs *newfs;
4263 struct fuse_module *m = fuse_get_module(module);
4265 if (!m)
4266 return -1;
4268 newfs = m->factory(args, fs);
4269 if (!newfs) {
4270 fuse_put_module(m);
4271 return -1;
4273 newfs->m = m;
4274 f->fs = newfs;
4275 f->conf.nopath = newfs->op.flag_nopath && f->conf.nopath;
4276 return 0;
4279 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4280 void *user_data)
4282 struct fuse_fs *fs;
4284 if (sizeof(struct fuse_operations) < op_size) {
4285 fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
4286 op_size = sizeof(struct fuse_operations);
4289 fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4290 if (!fs) {
4291 fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
4292 return NULL;
4295 fs->user_data = user_data;
4296 if (op)
4297 memcpy(&fs->op, op, op_size);
4298 return fs;
4301 static int node_table_init(struct node_table *t)
4303 t->size = NODE_TABLE_MIN_SIZE;
4304 t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4305 if (t->array == NULL) {
4306 fprintf(stderr, "fuse: memory allocation failed\n");
4307 return -1;
4309 t->use = 0;
4310 t->split = 0;
4312 return 0;
4315 static void *fuse_prune_nodes(void *fuse)
4317 struct fuse *f = fuse;
4318 int sleep_time;
4320 while(1) {
4321 sleep_time = fuse_clean_cache(f);
4322 sleep(sleep_time);
4324 return NULL;
4327 int fuse_start_cleanup_thread(struct fuse *f)
4329 if (lru_enabled(f))
4330 return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4332 return 0;
4335 void fuse_stop_cleanup_thread(struct fuse *f)
4337 if (lru_enabled(f)) {
4338 pthread_mutex_lock(&f->lock);
4339 pthread_cancel(f->prune_thread);
4340 pthread_mutex_unlock(&f->lock);
4341 pthread_join(f->prune_thread, NULL);
4345 struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
4346 const struct fuse_operations *op,
4347 size_t op_size, void *user_data)
4349 struct fuse *f;
4350 struct node *root;
4351 struct fuse_fs *fs;
4352 struct fuse_lowlevel_ops llop = fuse_path_ops;
4354 if (fuse_create_context_key() == -1)
4355 goto out;
4357 f = (struct fuse *) calloc(1, sizeof(struct fuse));
4358 if (f == NULL) {
4359 fprintf(stderr, "fuse: failed to allocate fuse object\n");
4360 goto out_delete_context_key;
4363 fs = fuse_fs_new(op, op_size, user_data);
4364 if (!fs)
4365 goto out_free;
4367 f->fs = fs;
4368 f->conf.nopath = fs->op.flag_nopath;
4370 /* Oh f**k, this is ugly! */
4371 if (!fs->op.lock) {
4372 llop.getlk = NULL;
4373 llop.setlk = NULL;
4376 f->conf.entry_timeout = 1.0;
4377 f->conf.attr_timeout = 1.0;
4378 f->conf.negative_timeout = 0.0;
4379 f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4381 f->pagesize = getpagesize();
4382 init_list_head(&f->partial_slabs);
4383 init_list_head(&f->full_slabs);
4384 init_list_head(&f->lru_table);
4386 if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4387 fuse_lib_opt_proc) == -1)
4388 goto out_free_fs;
4390 if (f->conf.modules) {
4391 char *module;
4392 char *next;
4394 for (module = f->conf.modules; module; module = next) {
4395 char *p;
4396 for (p = module; *p && *p != ':'; p++);
4397 next = *p ? p + 1 : NULL;
4398 *p = '\0';
4399 if (module[0] &&
4400 fuse_push_module(f, module, args) == -1)
4401 goto out_free_fs;
4405 if (!f->conf.ac_attr_timeout_set)
4406 f->conf.ac_attr_timeout = f->conf.attr_timeout;
4408 #if defined(__FreeBSD__) || defined(__NetBSD__)
4410 * In FreeBSD, we always use these settings as inode numbers
4411 * are needed to make getcwd(3) work.
4413 f->conf.readdir_ino = 1;
4414 #endif
4416 f->se = fuse_lowlevel_new(args, &llop, sizeof(llop), f);
4417 if (f->se == NULL) {
4418 if (f->conf.help)
4419 fuse_lib_help_modules();
4420 goto out_free_fs;
4423 fuse_session_add_chan(f->se, ch);
4425 if (f->conf.debug) {
4426 fprintf(stderr, "nopath: %i\n", f->conf.nopath);
4429 /* Trace topmost layer by default */
4430 f->fs->debug = f->conf.debug;
4431 f->ctr = 0;
4432 f->generation = 0;
4433 if (node_table_init(&f->name_table) == -1)
4434 goto out_free_session;
4436 if (node_table_init(&f->id_table) == -1)
4437 goto out_free_name_table;
4439 fuse_mutex_init(&f->lock);
4441 root = alloc_node(f);
4442 if (root == NULL) {
4443 fprintf(stderr, "fuse: memory allocation failed\n");
4444 goto out_free_id_table;
4446 if (lru_enabled(f)) {
4447 struct node_lru *lnode = node_lru(root);
4448 init_list_head(&lnode->lru);
4451 strcpy(root->inline_name, "/");
4452 root->name = root->inline_name;
4454 if (f->conf.intr &&
4455 fuse_init_intr_signal(f->conf.intr_signal,
4456 &f->intr_installed) == -1)
4457 goto out_free_root;
4459 root->parent = NULL;
4460 root->nodeid = FUSE_ROOT_ID;
4461 inc_nlookup(root);
4462 hash_id(f, root);
4464 return f;
4466 out_free_root:
4467 free(root);
4468 out_free_id_table:
4469 free(f->id_table.array);
4470 out_free_name_table:
4471 free(f->name_table.array);
4472 out_free_session:
4473 fuse_session_destroy(f->se);
4474 out_free_fs:
4475 if (f->fs->m)
4476 fuse_put_module(f->fs->m);
4477 free(f->fs);
4478 free(f->conf.modules);
4479 out_free:
4480 free(f);
4481 out_delete_context_key:
4482 fuse_delete_context_key();
4483 out:
4484 return NULL;
4487 void fuse_destroy(struct fuse *f)
4489 size_t i;
4491 if (f->conf.intr && f->intr_installed)
4492 fuse_restore_intr_signal(f->conf.intr_signal);
4494 if (f->fs) {
4495 fuse_create_context(f);
4497 for (i = 0; i < f->id_table.size; i++) {
4498 struct node *node;
4500 for (node = f->id_table.array[i]; node != NULL;
4501 node = node->id_next) {
4502 if (node->is_hidden) {
4503 char *path;
4504 if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
4505 fuse_fs_unlink(f->fs, path);
4506 free(path);
4512 for (i = 0; i < f->id_table.size; i++) {
4513 struct node *node;
4514 struct node *next;
4516 for (node = f->id_table.array[i]; node != NULL; node = next) {
4517 next = node->id_next;
4518 free_node(f, node);
4519 f->id_table.use--;
4522 assert(list_empty(&f->partial_slabs));
4523 assert(list_empty(&f->full_slabs));
4525 free(f->id_table.array);
4526 free(f->name_table.array);
4527 pthread_mutex_destroy(&f->lock);
4528 fuse_session_destroy(f->se);
4529 free(f->conf.modules);
4530 free(f);
4531 fuse_delete_context_key();
4534 /* called with fuse_context_lock held or during initialization (before
4535 main() has been called) */
4536 void fuse_register_module(struct fuse_module *mod)
4538 mod->ctr = 0;
4539 mod->so = fuse_current_so;
4540 if (mod->so)
4541 mod->so->ctr++;
4542 mod->next = fuse_modules;
4543 fuse_modules = mod;