20 #include "fuse_misc.h" 21 #include "fuse_kernel.h" 37 #include <sys/param.h> 43 #define FUSE_NODE_SLAB 1 49 #ifndef RENAME_EXCHANGE 50 #define RENAME_EXCHANGE (1 << 1) 53 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1 55 #define FUSE_UNKNOWN_INO 0xffffffff 56 #define OFFSET_MAX 0x7fffffffffffffffLL 58 #define NODE_TABLE_MIN_SIZE 8192 72 struct lock_queue_element {
73 struct lock_queue_element *next;
84 bool first_locked : 1;
85 bool second_locked : 1;
96 #define container_of(ptr, type, member) ({ \ 97 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 98 (type *)( (char *)__mptr - offsetof(type,member) );}) 100 #define list_entry(ptr, type, member) \ 101 container_of(ptr, type, member) 104 struct list_head *next;
105 struct list_head *prev;
109 struct list_head list;
110 struct list_head freelist;
115 struct fuse_session *se;
116 struct node_table name_table;
117 struct node_table id_table;
118 struct list_head lru_table;
120 unsigned int generation;
121 unsigned int hidectr;
122 pthread_mutex_t lock;
126 struct lock_queue_element *lockq;
128 struct list_head partial_slabs;
129 struct list_head full_slabs;
130 pthread_t prune_thread;
143 struct node *name_next;
144 struct node *id_next;
146 unsigned int generation;
152 struct timespec stat_updated;
153 struct timespec mtime;
156 unsigned int is_hidden : 1;
157 unsigned int cache_valid : 1;
159 char inline_name[32];
162 #define TREELOCK_WRITE -1 163 #define TREELOCK_WAIT_OFFSET INT_MIN 167 struct list_head lru;
168 struct timespec forget_time;
171 struct fuse_direntry {
174 struct fuse_direntry *next;
178 pthread_mutex_t lock;
182 struct fuse_direntry *first;
183 struct fuse_direntry **last;
193 struct fuse_context_i {
204 static pthread_key_t fuse_context_key;
205 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
206 static int fuse_context_ref;
209 static int fuse_register_module(
const char *name,
211 struct fusemod_so *so)
217 fprintf(stderr,
"fuse: failed to allocate module\n");
220 mod->name = strdup(name);
222 fprintf(stderr,
"fuse: failed to allocate module name\n");
226 mod->factory = factory;
231 mod->next = fuse_modules;
237 static void fuse_unregister_module(
struct fuse_module *m)
240 for (mp = &fuse_modules; *mp; mp = &(*mp)->next) {
250 static int fuse_load_so_module(
const char *module)
254 struct fusemod_so *so;
257 tmp = malloc(strlen(module) + 64);
259 fprintf(stderr,
"fuse: memory allocation failed\n");
262 sprintf(tmp,
"libfusemod_%s.so", module);
263 so = calloc(1,
sizeof(
struct fusemod_so));
265 fprintf(stderr,
"fuse: failed to allocate module so\n");
269 so->handle = dlopen(tmp, RTLD_NOW);
270 if (so->handle == NULL) {
271 fprintf(stderr,
"fuse: dlopen(%s) failed: %s\n",
276 sprintf(tmp,
"fuse_module_%s_factory", module);
277 *(
void**)(&factory) = dlsym(so->handle, tmp);
278 if (factory == NULL) {
279 fprintf(stderr,
"fuse: symbol <%s> not found in module: %s\n",
283 ret = fuse_register_module(module, factory, so);
298 static struct fuse_module *fuse_find_module(
const char *module)
301 for (m = fuse_modules; m; m = m->next) {
302 if (strcmp(module, m->name) == 0) {
310 static struct fuse_module *fuse_get_module(
const char *module)
314 pthread_mutex_lock(&fuse_context_lock);
315 m = fuse_find_module(module);
317 int err = fuse_load_so_module(module);
319 m = fuse_find_module(module);
321 pthread_mutex_unlock(&fuse_context_lock);
327 pthread_mutex_lock(&fuse_context_lock);
333 if (!m->ctr && m->so) {
334 struct fusemod_so *so = m->so;
339 for (mp = &fuse_modules; *mp;) {
341 fuse_unregister_module(*mp);
348 }
else if (!m->ctr) {
349 fuse_unregister_module(m);
351 pthread_mutex_unlock(&fuse_context_lock);
354 static void init_list_head(
struct list_head *list)
360 static int list_empty(
const struct list_head *head)
362 return head->next == head;
365 static void list_add(
struct list_head *
new,
struct list_head *prev,
366 struct list_head *next)
374 static inline void list_add_head(
struct list_head *
new,
struct list_head *head)
376 list_add(
new, head, head->next);
379 static inline void list_add_tail(
struct list_head *
new,
struct list_head *head)
381 list_add(
new, head->prev, head);
384 static inline void list_del(
struct list_head *entry)
386 struct list_head *prev = entry->prev;
387 struct list_head *next = entry->next;
393 static inline int lru_enabled(
struct fuse *f)
395 return f->conf.remember > 0;
398 static struct node_lru *node_lru(
struct node *node)
400 return (
struct node_lru *) node;
403 static size_t get_node_size(
struct fuse *f)
406 return sizeof(
struct node_lru);
408 return sizeof(
struct node);
411 #ifdef FUSE_NODE_SLAB 412 static struct node_slab *list_to_slab(
struct list_head *head)
414 return (
struct node_slab *) head;
417 static struct node_slab *node_to_slab(
struct fuse *f,
struct node *node)
419 return (
struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
422 static int alloc_slab(
struct fuse *f)
425 struct node_slab *slab;
429 size_t node_size = get_node_size(f);
431 mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
432 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
434 if (mem == MAP_FAILED)
438 init_list_head(&slab->freelist);
440 num = (f->pagesize -
sizeof(
struct node_slab)) / node_size;
442 start = (
char *) mem + f->pagesize - num * node_size;
443 for (i = 0; i < num; i++) {
446 n = (
struct list_head *) (start + i * node_size);
447 list_add_tail(n, &slab->freelist);
449 list_add_tail(&slab->list, &f->partial_slabs);
454 static struct node *alloc_node(
struct fuse *f)
456 struct node_slab *slab;
457 struct list_head *node;
459 if (list_empty(&f->partial_slabs)) {
460 int res = alloc_slab(f);
464 slab = list_to_slab(f->partial_slabs.next);
466 node = slab->freelist.next;
468 if (list_empty(&slab->freelist)) {
469 list_del(&slab->list);
470 list_add_tail(&slab->list, &f->full_slabs);
472 memset(node, 0,
sizeof(
struct node));
474 return (
struct node *) node;
477 static void free_slab(
struct fuse *f,
struct node_slab *slab)
481 list_del(&slab->list);
482 res = munmap(slab, f->pagesize);
484 fprintf(stderr,
"fuse warning: munmap(%p) failed\n", slab);
487 static void free_node_mem(
struct fuse *f,
struct node *node)
489 struct node_slab *slab = node_to_slab(f, node);
490 struct list_head *n = (
struct list_head *) node;
494 if (list_empty(&slab->freelist)) {
495 list_del(&slab->list);
496 list_add_tail(&slab->list, &f->partial_slabs);
498 list_add_head(n, &slab->freelist);
504 static struct node *alloc_node(
struct fuse *f)
506 return (
struct node *) calloc(1, get_node_size(f));
509 static void free_node_mem(
struct fuse *f,
struct node *node)
516 static size_t id_hash(
struct fuse *f,
fuse_ino_t ino)
518 uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
519 uint64_t oldhash = hash % (f->id_table.size / 2);
521 if (oldhash >= f->id_table.split)
527 static struct node *get_node_nocheck(
struct fuse *f,
fuse_ino_t nodeid)
529 size_t hash = id_hash(f, nodeid);
532 for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
533 if (node->nodeid == nodeid)
539 static struct node *get_node(
struct fuse *f,
fuse_ino_t nodeid)
541 struct node *node = get_node_nocheck(f, nodeid);
543 fprintf(stderr,
"fuse internal error: node %llu not found\n",
544 (
unsigned long long) nodeid);
550 static void curr_time(
struct timespec *now);
551 static double diff_timespec(
const struct timespec *t1,
552 const struct timespec *t2);
554 static void remove_node_lru(
struct node *node)
556 struct node_lru *lnode = node_lru(node);
557 list_del(&lnode->lru);
558 init_list_head(&lnode->lru);
561 static void set_forget_time(
struct fuse *f,
struct node *node)
563 struct node_lru *lnode = node_lru(node);
565 list_del(&lnode->lru);
566 list_add_tail(&lnode->lru, &f->lru_table);
567 curr_time(&lnode->forget_time);
570 static void free_node(
struct fuse *f,
struct node *node)
572 if (node->name != node->inline_name)
574 free_node_mem(f, node);
577 static void node_table_reduce(
struct node_table *t)
579 size_t newsize = t->size / 2;
582 if (newsize < NODE_TABLE_MIN_SIZE)
585 newarray = realloc(t->array,
sizeof(
struct node *) * newsize);
586 if (newarray != NULL)
590 t->split = t->size / 2;
593 static void remerge_id(
struct fuse *f)
595 struct node_table *t = &f->id_table;
599 node_table_reduce(t);
601 for (iter = 8; t->split > 0 && iter; iter--) {
605 upper = &t->array[t->split + t->size / 2];
609 for (nodep = &t->array[t->split]; *nodep;
610 nodep = &(*nodep)->id_next);
619 static void unhash_id(
struct fuse *f,
struct node *node)
621 struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
623 for (; *nodep != NULL; nodep = &(*nodep)->id_next)
624 if (*nodep == node) {
625 *nodep = node->id_next;
628 if(f->id_table.use < f->id_table.size / 4)
634 static int node_table_resize(
struct node_table *t)
636 size_t newsize = t->size * 2;
639 newarray = realloc(t->array,
sizeof(
struct node *) * newsize);
640 if (newarray == NULL)
644 memset(t->array + t->size, 0, t->size *
sizeof(
struct node *));
651 static void rehash_id(
struct fuse *f)
653 struct node_table *t = &f->id_table;
658 if (t->split == t->size / 2)
663 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
664 struct node *node = *nodep;
665 size_t newhash = id_hash(f, node->nodeid);
667 if (newhash != hash) {
669 *nodep = node->id_next;
670 node->id_next = t->array[newhash];
671 t->array[newhash] = node;
673 next = &node->id_next;
676 if (t->split == t->size / 2)
677 node_table_resize(t);
680 static void hash_id(
struct fuse *f,
struct node *node)
682 size_t hash = id_hash(f, node->nodeid);
683 node->id_next = f->id_table.array[hash];
684 f->id_table.array[hash] = node;
687 if (f->id_table.use >= f->id_table.size / 2)
691 static size_t name_hash(
struct fuse *f,
fuse_ino_t parent,
694 uint64_t hash = parent;
697 for (; *name; name++)
698 hash = hash * 31 + (
unsigned char) *name;
700 hash %= f->name_table.size;
701 oldhash = hash % (f->name_table.size / 2);
702 if (oldhash >= f->name_table.split)
708 static void unref_node(
struct fuse *f,
struct node *node);
710 static void remerge_name(
struct fuse *f)
712 struct node_table *t = &f->name_table;
716 node_table_reduce(t);
718 for (iter = 8; t->split > 0 && iter; iter--) {
722 upper = &t->array[t->split + t->size / 2];
726 for (nodep = &t->array[t->split]; *nodep;
727 nodep = &(*nodep)->name_next);
736 static void unhash_name(
struct fuse *f,
struct node *node)
739 size_t hash = name_hash(f, node->parent->nodeid, node->name);
740 struct node **nodep = &f->name_table.array[hash];
742 for (; *nodep != NULL; nodep = &(*nodep)->name_next)
743 if (*nodep == node) {
744 *nodep = node->name_next;
745 node->name_next = NULL;
746 unref_node(f, node->parent);
747 if (node->name != node->inline_name)
753 if (f->name_table.use < f->name_table.size / 4)
758 "fuse internal error: unable to unhash node: %llu\n",
759 (
unsigned long long) node->nodeid);
764 static void rehash_name(
struct fuse *f)
766 struct node_table *t = &f->name_table;
771 if (t->split == t->size / 2)
776 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
777 struct node *node = *nodep;
778 size_t newhash = name_hash(f, node->parent->nodeid, node->name);
780 if (newhash != hash) {
782 *nodep = node->name_next;
783 node->name_next = t->array[newhash];
784 t->array[newhash] = node;
786 next = &node->name_next;
789 if (t->split == t->size / 2)
790 node_table_resize(t);
793 static int hash_name(
struct fuse *f,
struct node *node,
fuse_ino_t parentid,
796 size_t hash = name_hash(f, parentid, name);
797 struct node *parent = get_node(f, parentid);
798 if (strlen(name) <
sizeof(node->inline_name)) {
799 strcpy(node->inline_name, name);
800 node->name = node->inline_name;
802 node->name = strdup(name);
803 if (node->name == NULL)
808 node->parent = parent;
809 node->name_next = f->name_table.array[hash];
810 f->name_table.array[hash] = node;
813 if (f->name_table.use >= f->name_table.size / 2)
819 static void delete_node(
struct fuse *f,
struct node *node)
822 fprintf(stderr,
"DELETE: %llu\n",
823 (
unsigned long long) node->nodeid);
825 assert(node->treelock == 0);
826 unhash_name(f, node);
828 remove_node_lru(node);
833 static void unref_node(
struct fuse *f,
struct node *node)
835 assert(node->refctr > 0);
838 delete_node(f, node);
844 f->ctr = (f->ctr + 1) & 0xffffffff;
847 }
while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
848 get_node_nocheck(f, f->ctr) != NULL);
852 static struct node *lookup_node(
struct fuse *f,
fuse_ino_t parent,
855 size_t hash = name_hash(f, parent, name);
858 for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
859 if (node->parent->nodeid == parent &&
860 strcmp(node->name, name) == 0)
866 static void inc_nlookup(
struct node *node)
873 static struct node *find_node(
struct fuse *f,
fuse_ino_t parent,
878 pthread_mutex_lock(&f->lock);
880 node = get_node(f, parent);
882 node = lookup_node(f, parent, name);
884 node = alloc_node(f);
888 node->nodeid = next_id(f);
889 node->generation = f->generation;
890 if (f->conf.remember)
893 if (hash_name(f, node, parent, name) == -1) {
899 if (lru_enabled(f)) {
900 struct node_lru *lnode = node_lru(node);
901 init_list_head(&lnode->lru);
903 }
else if (lru_enabled(f) && node->nlookup == 1) {
904 remove_node_lru(node);
908 pthread_mutex_unlock(&f->lock);
912 static int lookup_path_in_cache(
struct fuse *f,
915 char *tmp = strdup(path);
919 pthread_mutex_lock(&f->lock);
924 char *path_element = strtok_r(tmp,
"/", &save_ptr);
925 while (path_element != NULL) {
926 struct node *node = lookup_node(f, ino, path_element);
932 path_element = strtok_r(NULL,
"/", &save_ptr);
934 pthread_mutex_unlock(&f->lock);
942 static char *add_name(
char **buf,
unsigned *bufsize,
char *s,
const char *name)
944 size_t len = strlen(name);
946 if (s - len <= *buf) {
947 unsigned pathlen = *bufsize - (s - *buf);
948 unsigned newbufsize = *bufsize;
951 while (newbufsize < pathlen + len + 1) {
952 if (newbufsize >= 0x80000000)
953 newbufsize = 0xffffffff;
958 newbuf = realloc(*buf, newbufsize);
963 s = newbuf + newbufsize - pathlen;
964 memmove(s, newbuf + *bufsize - pathlen, pathlen);
965 *bufsize = newbufsize;
968 strncpy(s, name, len);
975 static void unlock_path(
struct fuse *f,
fuse_ino_t nodeid,
struct node *wnode,
981 assert(wnode->treelock == TREELOCK_WRITE);
985 for (node = get_node(f, nodeid);
986 node != end && node->nodeid !=
FUSE_ROOT_ID; node = node->parent) {
987 assert(node->treelock != 0);
988 assert(node->treelock != TREELOCK_WAIT_OFFSET);
989 assert(node->treelock != TREELOCK_WRITE);
991 if (node->treelock == TREELOCK_WAIT_OFFSET)
996 static int try_get_path(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
997 char **path,
struct node **wnodep,
bool need_lock)
999 unsigned bufsize = 256;
1003 struct node *wnode = NULL;
1009 buf = malloc(bufsize);
1013 s = buf + bufsize - 1;
1017 s = add_name(&buf, &bufsize, s, name);
1025 wnode = lookup_node(f, nodeid, name);
1027 if (wnode->treelock != 0) {
1028 if (wnode->treelock > 0)
1029 wnode->treelock += TREELOCK_WAIT_OFFSET;
1033 wnode->treelock = TREELOCK_WRITE;
1037 for (node = get_node(f, nodeid); node->nodeid !=
FUSE_ROOT_ID;
1038 node = node->parent) {
1040 if (node->name == NULL || node->parent == NULL)
1044 s = add_name(&buf, &bufsize, s, node->name);
1050 if (node->treelock < 0)
1058 memmove(buf, s, bufsize - (s - buf));
1070 unlock_path(f, nodeid, wnode, node);
1078 static void queue_element_unlock(
struct fuse *f,
struct lock_queue_element *qe)
1082 if (qe->first_locked) {