18 #include "fuse_lowlevel.h" 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;
194 struct fuse_context_i {
205 static pthread_key_t fuse_context_key;
206 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
207 static int fuse_context_ref;
210 static int fuse_register_module(
const char *name,
212 struct fusemod_so *so)
218 fprintf(stderr,
"fuse: failed to allocate module\n");
221 mod->name = strdup(name);
223 fprintf(stderr,
"fuse: failed to allocate module name\n");
227 mod->factory = factory;
232 mod->next = fuse_modules;
239 static int fuse_load_so_module(
const char *module)
243 struct fusemod_so *so;
246 tmp = malloc(strlen(module) + 64);
248 fprintf(stderr,
"fuse: memory allocation failed\n");
251 sprintf(tmp,
"libfusemod_%s.so", module);
252 so = calloc(1,
sizeof(
struct fusemod_so));
254 fprintf(stderr,
"fuse: failed to allocate module so\n");
258 so->handle = dlopen(tmp, RTLD_NOW);
259 if (so->handle == NULL) {
260 fprintf(stderr,
"fuse: dlopen(%s) failed: %s\n",
265 sprintf(tmp,
"fuse_module_%s_factory", module);
266 *(
void**)(&factory) = dlsym(so->handle, tmp);
267 if (factory == NULL) {
268 fprintf(stderr,
"fuse: symbol <%s> not found in module: %s\n",
272 ret = fuse_register_module(module, factory, so);
287 static struct fuse_module *fuse_find_module(
const char *module)
290 for (m = fuse_modules; m; m = m->next) {
291 if (strcmp(module, m->name) == 0) {
299 static struct fuse_module *fuse_get_module(
const char *module)
303 pthread_mutex_lock(&fuse_context_lock);
304 m = fuse_find_module(module);
306 int err = fuse_load_so_module(module);
308 m = fuse_find_module(module);
310 pthread_mutex_unlock(&fuse_context_lock);
316 pthread_mutex_lock(&fuse_context_lock);
319 if (!m->ctr && m->so) {
320 struct fusemod_so *so = m->so;
325 for (mp = &fuse_modules; *mp;) {
335 pthread_mutex_unlock(&fuse_context_lock);
338 static void init_list_head(
struct list_head *list)
344 static int list_empty(
const struct list_head *head)
346 return head->next == head;
349 static void list_add(
struct list_head *
new,
struct list_head *prev,
350 struct list_head *next)
358 static inline void list_add_head(
struct list_head *
new,
struct list_head *head)
360 list_add(
new, head, head->next);
363 static inline void list_add_tail(
struct list_head *
new,
struct list_head *head)
365 list_add(
new, head->prev, head);
368 static inline void list_del(
struct list_head *entry)
370 struct list_head *prev = entry->prev;
371 struct list_head *next = entry->next;
377 static inline int lru_enabled(
struct fuse *f)
379 return f->conf.remember > 0;
382 static struct node_lru *node_lru(
struct node *node)
384 return (
struct node_lru *) node;
387 static size_t get_node_size(
struct fuse *f)
390 return sizeof(
struct node_lru);
392 return sizeof(
struct node);
395 #ifdef FUSE_NODE_SLAB 396 static struct node_slab *list_to_slab(
struct list_head *head)
398 return (
struct node_slab *) head;
401 static struct node_slab *node_to_slab(
struct fuse *f,
struct node *node)
403 return (
struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
406 static int alloc_slab(
struct fuse *f)
409 struct node_slab *slab;
413 size_t node_size = get_node_size(f);
415 mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
416 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
418 if (mem == MAP_FAILED)
422 init_list_head(&slab->freelist);
424 num = (f->pagesize -
sizeof(
struct node_slab)) / node_size;
426 start = (
char *) mem + f->pagesize - num * node_size;
427 for (i = 0; i < num; i++) {
430 n = (
struct list_head *) (start + i * node_size);
431 list_add_tail(n, &slab->freelist);
433 list_add_tail(&slab->list, &f->partial_slabs);
438 static struct node *alloc_node(
struct fuse *f)
440 struct node_slab *slab;
441 struct list_head *node;
443 if (list_empty(&f->partial_slabs)) {
444 int res = alloc_slab(f);
448 slab = list_to_slab(f->partial_slabs.next);
450 node = slab->freelist.next;
452 if (list_empty(&slab->freelist)) {
453 list_del(&slab->list);
454 list_add_tail(&slab->list, &f->full_slabs);
456 memset(node, 0,
sizeof(
struct node));
458 return (
struct node *) node;
461 static void free_slab(
struct fuse *f,
struct node_slab *slab)
465 list_del(&slab->list);
466 res = munmap(slab, f->pagesize);
468 fprintf(stderr,
"fuse warning: munmap(%p) failed\n", slab);
471 static void free_node_mem(
struct fuse *f,
struct node *node)
473 struct node_slab *slab = node_to_slab(f, node);
474 struct list_head *n = (
struct list_head *) node;
478 if (list_empty(&slab->freelist)) {
479 list_del(&slab->list);
480 list_add_tail(&slab->list, &f->partial_slabs);
482 list_add_head(n, &slab->freelist);
488 static struct node *alloc_node(
struct fuse *f)
490 return (
struct node *) calloc(1, get_node_size(f));
493 static void free_node_mem(
struct fuse *f,
struct node *node)
500 static size_t id_hash(
struct fuse *f,
fuse_ino_t ino)
502 uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
503 uint64_t oldhash = hash % (f->id_table.size / 2);
505 if (oldhash >= f->id_table.split)
511 static struct node *get_node_nocheck(
struct fuse *f,
fuse_ino_t nodeid)
513 size_t hash = id_hash(f, nodeid);
516 for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
517 if (node->nodeid == nodeid)
523 static struct node *get_node(
struct fuse *f,
fuse_ino_t nodeid)
525 struct node *node = get_node_nocheck(f, nodeid);
527 fprintf(stderr,
"fuse internal error: node %llu not found\n",
528 (
unsigned long long) nodeid);
534 static void curr_time(
struct timespec *now);
535 static double diff_timespec(
const struct timespec *t1,
536 const struct timespec *t2);
538 static void remove_node_lru(
struct node *node)
540 struct node_lru *lnode = node_lru(node);
541 list_del(&lnode->lru);
542 init_list_head(&lnode->lru);
545 static void set_forget_time(
struct fuse *f,
struct node *node)
547 struct node_lru *lnode = node_lru(node);
549 list_del(&lnode->lru);
550 list_add_tail(&lnode->lru, &f->lru_table);
551 curr_time(&lnode->forget_time);
554 static void free_node(
struct fuse *f,
struct node *node)
556 if (node->name != node->inline_name)
558 free_node_mem(f, node);
561 static void node_table_reduce(
struct node_table *t)
563 size_t newsize = t->size / 2;
566 if (newsize < NODE_TABLE_MIN_SIZE)
569 newarray = realloc(t->array,
sizeof(
struct node *) * newsize);
570 if (newarray != NULL)
574 t->split = t->size / 2;
577 static void remerge_id(
struct fuse *f)
579 struct node_table *t = &f->id_table;
583 node_table_reduce(t);
585 for (iter = 8; t->split > 0 && iter; iter--) {
589 upper = &t->array[t->split + t->size / 2];
593 for (nodep = &t->array[t->split]; *nodep;
594 nodep = &(*nodep)->id_next);
603 static void unhash_id(
struct fuse *f,
struct node *node)
605 struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
607 for (; *nodep != NULL; nodep = &(*nodep)->id_next)
608 if (*nodep == node) {
609 *nodep = node->id_next;
612 if(f->id_table.use < f->id_table.size / 4)
618 static int node_table_resize(
struct node_table *t)
620 size_t newsize = t->size * 2;
623 newarray = realloc(t->array,
sizeof(
struct node *) * newsize);
624 if (newarray == NULL)
628 memset(t->array + t->size, 0, t->size *
sizeof(
struct node *));
635 static void rehash_id(
struct fuse *f)
637 struct node_table *t = &f->id_table;
642 if (t->split == t->size / 2)
647 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
648 struct node *node = *nodep;
649 size_t newhash = id_hash(f, node->nodeid);
651 if (newhash != hash) {
653 *nodep = node->id_next;
654 node->id_next = t->array[newhash];
655 t->array[newhash] = node;
657 next = &node->id_next;
660 if (t->split == t->size / 2)
661 node_table_resize(t);
664 static void hash_id(
struct fuse *f,
struct node *node)
666 size_t hash = id_hash(f, node->nodeid);
667 node->id_next = f->id_table.array[hash];
668 f->id_table.array[hash] = node;
671 if (f->id_table.use >= f->id_table.size / 2)
675 static size_t name_hash(
struct fuse *f,
fuse_ino_t parent,
678 uint64_t hash = parent;
681 for (; *name; name++)
682 hash = hash * 31 + (
unsigned char) *name;
684 hash %= f->name_table.size;
685 oldhash = hash % (f->name_table.size / 2);
686 if (oldhash >= f->name_table.split)
692 static void unref_node(
struct fuse *f,
struct node *node);
694 static void remerge_name(
struct fuse *f)
696 struct node_table *t = &f->name_table;
700 node_table_reduce(t);
702 for (iter = 8; t->split > 0 && iter; iter--) {
706 upper = &t->array[t->split + t->size / 2];
710 for (nodep = &t->array[t->split]; *nodep;
711 nodep = &(*nodep)->name_next);
720 static void unhash_name(
struct fuse *f,
struct node *node)
723 size_t hash = name_hash(f, node->parent->nodeid, node->name);
724 struct node **nodep = &f->name_table.array[hash];
726 for (; *nodep != NULL; nodep = &(*nodep)->name_next)
727 if (*nodep == node) {
728 *nodep = node->name_next;
729 node->name_next = NULL;
730 unref_node(f, node->parent);
731 if (node->name != node->inline_name)
737 if (f->name_table.use < f->name_table.size / 4)
742 "fuse internal error: unable to unhash node: %llu\n",
743 (
unsigned long long) node->nodeid);
748 static void rehash_name(
struct fuse *f)
750 struct node_table *t = &f->name_table;
755 if (t->split == t->size / 2)
760 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
761 struct node *node = *nodep;
762 size_t newhash = name_hash(f, node->parent->nodeid, node->name);
764 if (newhash != hash) {
766 *nodep = node->name_next;
767 node->name_next = t->array[newhash];
768 t->array[newhash] = node;
770 next = &node->name_next;
773 if (t->split == t->size / 2)
774 node_table_resize(t);
777 static int hash_name(
struct fuse *f,
struct node *node,
fuse_ino_t parentid,
780 size_t hash = name_hash(f, parentid, name);
781 struct node *parent = get_node(f, parentid);
782 if (strlen(name) <
sizeof(node->inline_name)) {
783 strcpy(node->inline_name, name);
784 node->name = node->inline_name;
786 node->name = strdup(name);
787 if (node->name == NULL)
792 node->parent = parent;
793 node->name_next = f->name_table.array[hash];
794 f->name_table.array[hash] = node;
797 if (f->name_table.use >= f->name_table.size / 2)
803 static void delete_node(
struct fuse *f,
struct node *node)
806 fprintf(stderr,
"DELETE: %llu\n",
807 (
unsigned long long) node->nodeid);
809 assert(node->treelock == 0);
810 unhash_name(f, node);
812 remove_node_lru(node);
817 static void unref_node(
struct fuse *f,
struct node *node)
819 assert(node->refctr > 0);
822 delete_node(f, node);
828 f->ctr = (f->ctr + 1) & 0xffffffff;
831 }
while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
832 get_node_nocheck(f, f->ctr) != NULL);
836 static struct node *lookup_node(
struct fuse *f,
fuse_ino_t parent,
839 size_t hash = name_hash(f, parent, name);
842 for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
843 if (node->parent->nodeid == parent &&
844 strcmp(node->name, name) == 0)
850 static void inc_nlookup(
struct node *node)
857 static struct node *find_node(
struct fuse *f,
fuse_ino_t parent,
862 pthread_mutex_lock(&f->lock);
864 node = get_node(f, parent);
866 node = lookup_node(f, parent, name);
868 node = alloc_node(f);
872 node->nodeid = next_id(f);
873 node->generation = f->generation;
874 if (f->conf.remember)
877 if (hash_name(f, node, parent, name) == -1) {
883 if (lru_enabled(f)) {
884 struct node_lru *lnode = node_lru(node);
885 init_list_head(&lnode->lru);
887 }
else if (lru_enabled(f) && node->nlookup == 1) {
888 remove_node_lru(node);
892 pthread_mutex_unlock(&f->lock);
896 static int lookup_path_in_cache(
struct fuse *f,
899 char *tmp = strdup(path);
903 pthread_mutex_lock(&f->lock);
908 char *path_element = strtok_r(tmp,
"/", &save_ptr);
909 while (path_element != NULL) {
910 struct node *node = lookup_node(f, ino, path_element);
916 path_element = strtok_r(NULL,
"/", &save_ptr);
918 pthread_mutex_unlock(&f->lock);
926 static char *add_name(
char **buf,
unsigned *bufsize,
char *s,
const char *name)
928 size_t len = strlen(name);
930 if (s - len <= *buf) {
931 unsigned pathlen = *bufsize - (s - *buf);
932 unsigned newbufsize = *bufsize;
935 while (newbufsize < pathlen + len + 1) {
936 if (newbufsize >= 0x80000000)
937 newbufsize = 0xffffffff;
942 newbuf = realloc(*buf, newbufsize);
947 s = newbuf + newbufsize - pathlen;
948 memmove(s, newbuf + *bufsize - pathlen, pathlen);
949 *bufsize = newbufsize;
952 strncpy(s, name, len);
959 static void unlock_path(
struct fuse *f,
fuse_ino_t nodeid,
struct node *wnode,
965 assert(wnode->treelock == TREELOCK_WRITE);
969 for (node = get_node(f, nodeid);
970 node != end && node->nodeid !=
FUSE_ROOT_ID; node = node->parent) {
971 assert(node->treelock != 0);
972 assert(node->treelock != TREELOCK_WAIT_OFFSET);
973 assert(node->treelock != TREELOCK_WRITE);
975 if (node->treelock == TREELOCK_WAIT_OFFSET)
980 static int try_get_path(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
981 char **path,
struct node **wnodep,
bool need_lock)
983 unsigned bufsize = 256;
987 struct node *wnode = NULL;
993 buf = malloc(bufsize);
997 s = buf + bufsize - 1;
1001 s = add_name(&buf, &bufsize, s, name);
1009 wnode = lookup_node(f, nodeid, name);
1011 if (wnode->treelock != 0) {
1012 if (wnode->treelock > 0)
1013 wnode->treelock += TREELOCK_WAIT_OFFSET;
1017 wnode->treelock = TREELOCK_WRITE;
1021 for (node = get_node(f, nodeid); node->nodeid !=
FUSE_ROOT_ID;
1022 node = node->parent) {
1024 if (node->name == NULL || node->parent == NULL)
1028 s = add_name(&buf, &bufsize, s, node->name);
1034 if (node->treelock < 0)
1042 memmove(buf, s, bufsize - (s - buf));
1054 unlock_path(f, nodeid, wnode, node);
1062 static void queue_element_unlock(
struct fuse *f,
struct lock_queue_element *qe)
1066 if (qe->first_locked) {
1067 wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1068 unlock_path(f, qe->nodeid1, wnode, NULL);
1069 qe->first_locked =
false;
1071 if (qe->second_locked) {
1072 wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1073 unlock_path(f, qe->nodeid2, wnode, NULL);
1074 qe->second_locked =
false;
1078 static void queue_element_wakeup(
struct fuse *f,
struct lock_queue_element *qe)
1081 bool first = (qe == f->lockq);
1085 if (get_node(f, qe->nodeid1)->treelock == 0)
1086 pthread_cond_signal(&qe->cond);
1091 if (!qe->first_locked) {
1092 err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1095 qe->first_locked =
true;
1096 else if (err != -EAGAIN)
1099 if (!qe->second_locked && qe->path2) {
1100 err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1103 qe->second_locked =
true;
1104 else if (err != -EAGAIN)
1108 if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1121 queue_element_unlock(f, qe);
1127 queue_element_unlock(f, qe);
1131 pthread_cond_signal(&qe->cond);
1134 static void wake_up_queued(
struct fuse *f)
1136 struct lock_queue_element *qe;
1138 for (qe = f->lockq; qe != NULL; qe = qe->next)
1139 queue_element_wakeup(f, qe);
1142 static void debug_path(
struct fuse *f,
const char *msg,
fuse_ino_t nodeid,
1143 const char *name,
bool wr)
1145 if (f->conf.debug) {
1146 struct node *wnode = NULL;
1149 wnode = lookup_node(f, nodeid, name);
1152 fprintf(stderr,
"%s %llu (w)\n",
1153 msg, (
unsigned long long) wnode->nodeid);
1155 fprintf(stderr,
"%s %llu\n",
1156 msg, (
unsigned long long) nodeid);
1161 static void queue_path(
struct fuse *f,
struct lock_queue_element *qe)
1163 struct lock_queue_element **qp;
1166 qe->first_locked =
false;
1167 qe->second_locked =
false;
1168 pthread_cond_init(&qe->cond, NULL);
1170 for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1174 static void dequeue_path(
struct fuse *f,
struct lock_queue_element *qe)
1176 struct lock_queue_element **qp;
1178 pthread_cond_destroy(&qe->cond);
1179 for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1183 static int wait_path(
struct fuse *f,
struct lock_queue_element *qe)
1188 pthread_cond_wait(&qe->cond, &f->lock);
1189 }
while (!qe->done);
1191 dequeue_path(f, qe);
1196 static int get_path_common(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1197 char **path,
struct node **wnode)
1201 pthread_mutex_lock(&f->lock);
1202 err = try_get_path(f, nodeid, name, path, wnode,
true);
1203 if (err == -EAGAIN) {
1204 struct lock_queue_element qe = {
1210 debug_path(f,
"QUEUE PATH", nodeid, name, !!wnode);
1211 err = wait_path(f, &qe);
1212 debug_path(f,
"DEQUEUE PATH", nodeid, name, !!wnode);
1214 pthread_mutex_unlock(&f->lock);
1219 static int get_path(
struct fuse *f,
fuse_ino_t nodeid,
char **path)
1221 return get_path_common(f, nodeid, NULL, path, NULL);
1224 static int get_path_nullok(
struct fuse *f,
fuse_ino_t nodeid,
char **path)
1228 if (f->conf.nullpath_ok) {
1231 err = get_path_common(f, nodeid, NULL, path, NULL);
1239 static int get_path_name(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1242 return get_path_common(f, nodeid, name, path, NULL);
1245 static int get_path_wrlock(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1246 char **path,
struct node **wnode)
1248 return get_path_common(f, nodeid, name, path, wnode);
1251 #if defined(__FreeBSD__) 1252 #define CHECK_DIR_LOOP 1255 #if defined(CHECK_DIR_LOOP) 1256 static int check_dir_loop(
struct fuse *f,
1260 struct node *node, *node1, *node2;
1263 node1 = lookup_node(f, nodeid1, name1);
1264 id1 = node1 ? node1->nodeid : nodeid1;
1266 node2 = lookup_node(f, nodeid2, name2);
1267 id2 = node2 ? node2->nodeid : nodeid2;
1269 for (node = get_node(f, id2); node->nodeid !=
FUSE_ROOT_ID;
1270 node = node->parent) {
1271 if (node->name == NULL || node->parent == NULL)
1274 if (node->nodeid != id2 && node->nodeid == id1)
1280 for (node = get_node(f, id1); node->nodeid !=
FUSE_ROOT_ID;
1281 node = node->parent) {
1282 if (node->name == NULL || node->parent == NULL)
1285 if (node->nodeid != id1 && node->nodeid == id2)
1294 static int try_get_path2(
struct fuse *f,
fuse_ino_t nodeid1,
const char *name1,
1296 char **path1,
char **path2,
1297 struct node **wnode1,
struct node **wnode2)
1302 err = try_get_path(f, nodeid1, name1, path1, wnode1,
true);
1304 err = try_get_path(f, nodeid2, name2, path2, wnode2,
true);
1306 struct node *wn1 = wnode1 ? *wnode1 : NULL;
1308 unlock_path(f, nodeid1, wn1, NULL);
1315 static int get_path2(
struct fuse *f,
fuse_ino_t nodeid1,
const char *name1,
1317 char **path1,
char **path2,
1318 struct node **wnode1,
struct node **wnode2)
1322 pthread_mutex_lock(&f->lock);
1324 #if defined(CHECK_DIR_LOOP) 1328 err = check_dir_loop(f, nodeid1, name1, nodeid2, name2);
1334 err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1335 path1, path2, wnode1, wnode2);
1336 if (err == -EAGAIN) {
1337 struct lock_queue_element qe = {
1348 debug_path(f,
"QUEUE PATH1", nodeid1, name1, !!wnode1);
1349 debug_path(f,
" PATH2", nodeid2, name2, !!wnode2);
1350 err = wait_path(f, &qe);
1351 debug_path(f,
"DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1352 debug_path(f,
" PATH2", nodeid2, name2, !!wnode2);
1355 #if defined(CHECK_DIR_LOOP) 1358 pthread_mutex_unlock(&f->lock);
1363 static void free_path_wrlock(
struct fuse *f,
fuse_ino_t nodeid,
1364 struct node *wnode,
char *path)
1366 pthread_mutex_lock(&f->lock);
1367 unlock_path(f, nodeid, wnode, NULL);
1370 pthread_mutex_unlock(&f->lock);
1374 static void free_path(
struct fuse *f,
fuse_ino_t nodeid,
char *path)
1377 free_path_wrlock(f, nodeid, NULL, path);
1381 struct node *wnode1,
struct node *wnode2,
1382 char *path1,
char *path2)
1384 pthread_mutex_lock(&f->lock);
1385 unlock_path(f, nodeid1, wnode1, NULL);
1386 unlock_path(f, nodeid2, wnode2, NULL);
1388 pthread_mutex_unlock(&f->lock);
1393 static void forget_node(
struct fuse *f,
fuse_ino_t nodeid, uint64_t nlookup)
1398 pthread_mutex_lock(&f->lock);
1399 node = get_node(f, nodeid);
1405 while (node->nlookup == nlookup && node->treelock) {
1406 struct lock_queue_element qe = {
1410 debug_path(f,
"QUEUE PATH (forget)", nodeid, NULL,
false);
1414 pthread_cond_wait(&qe.cond, &f->lock);
1415 }
while (node->nlookup == nlookup && node->treelock);
1417 dequeue_path(f, &qe);
1418 debug_path(f,
"DEQUEUE_PATH (forget)", nodeid, NULL,
false);
1421 assert(node->nlookup >= nlookup);
1422 node->nlookup -= nlookup;
1423 if (!node->nlookup) {
1424 unref_node(f, node);
1425 }
else if (lru_enabled(f) && node->nlookup == 1) {
1426 set_forget_time(f, node);
1428 pthread_mutex_unlock(&f->lock);
1431 static void unlink_node(
struct fuse *f,
struct node *node)
1433 if (f->conf.remember) {
1434 assert(node->nlookup > 1);
1437 unhash_name(f, node);
1440 static void remove_node(
struct fuse *f,
fuse_ino_t dir,
const char *name)
1444 pthread_mutex_lock(&f->lock);
1445 node = lookup_node(f, dir, name);
1447 unlink_node(f, node);
1448 pthread_mutex_unlock(&f->lock);
1451 static int rename_node(
struct fuse *f,
fuse_ino_t olddir,
const char *oldname,
1452 fuse_ino_t newdir,
const char *newname,
int hide)
1455 struct node *newnode;
1458 pthread_mutex_lock(&f->lock);
1459 node = lookup_node(f, olddir, oldname);
1460 newnode = lookup_node(f, newdir, newname);
1464 if (newnode != NULL) {
1466 fprintf(stderr,
"fuse: hidden file got created during hiding\n");
1470 unlink_node(f, newnode);
1473 unhash_name(f, node);
1474 if (hash_name(f, node, newdir, newname) == -1) {
1480 node->is_hidden = 1;
1483 pthread_mutex_unlock(&f->lock);
1487 static int exchange_node(
struct fuse *f,
fuse_ino_t olddir,
const char *oldname,
1490 struct node *oldnode;
1491 struct node *newnode;
1494 pthread_mutex_lock(&f->lock);
1495 oldnode = lookup_node(f, olddir, oldname);
1496 newnode = lookup_node(f, newdir, newname);
1499 unhash_name(f, oldnode);
1501 unhash_name(f, newnode);
1505 if (hash_name(f, oldnode, newdir, newname) == -1)
1509 if (hash_name(f, newnode, olddir, oldname) == -1)
1514 pthread_mutex_unlock(&f->lock);
1518 static void set_stat(
struct fuse *f,
fuse_ino_t nodeid,
struct stat *stbuf)
1520 if (!f->conf.use_ino)
1521 stbuf->st_ino = nodeid;
1522 if (f->conf.set_mode)
1523 stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1524 (0777 & ~f->conf.umask);
1525 if (f->conf.set_uid)
1526 stbuf->st_uid = f->conf.uid;
1527 if (f->conf.set_gid)
1528 stbuf->st_gid = f->conf.gid;
1536 static void fuse_intr_sighandler(
int sig)
1542 struct fuse_intr_data {
1544 pthread_cond_t cond;
1548 static void fuse_interrupt(
fuse_req_t req,
void *d_)
1550 struct fuse_intr_data *d = d_;
1551 struct fuse *f = req_fuse(req);
1553 if (d->id == pthread_self())
1556 pthread_mutex_lock(&f->lock);
1557 while (!d->finished) {
1559 struct timespec timeout;
1561 pthread_kill(d->id, f->conf.intr_signal);
1562 gettimeofday(&now, NULL);
1563 timeout.tv_sec = now.tv_sec + 1;
1564 timeout.tv_nsec = now.tv_usec * 1000;
1565 pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1567 pthread_mutex_unlock(&f->lock);
1570 static void fuse_do_finish_interrupt(
struct fuse *f,
fuse_req_t req,
1571 struct fuse_intr_data *d)
1573 pthread_mutex_lock(&f->lock);
1575 pthread_cond_broadcast(&d->cond);
1576 pthread_mutex_unlock(&f->lock);
1578 pthread_cond_destroy(&d->cond);
1581 static void fuse_do_prepare_interrupt(
fuse_req_t req,
struct fuse_intr_data *d)
1583 d->id = pthread_self();
1584 pthread_cond_init(&d->cond, NULL);
1589 static inline void fuse_finish_interrupt(
struct fuse *f,
fuse_req_t req,
1590 struct fuse_intr_data *d)
1593 fuse_do_finish_interrupt(f, req, d);
1596 static inline void fuse_prepare_interrupt(
struct fuse *f,
fuse_req_t req,
1597 struct fuse_intr_data *d)
1600 fuse_do_prepare_interrupt(req, d);
1604 char* buf,
size_t len)
1608 snprintf(buf, len,
"%llu", (
unsigned long long) fi->
fh);
1612 int fuse_fs_getattr(
struct fuse_fs *fs,
const char *path,
struct stat *buf,
1616 if (fs->op.getattr) {
1619 fprintf(stderr,
"getattr[%s] %s\n",
1620 file_info_string(fi, buf,
sizeof(buf)),
1623 return fs->op.getattr(path, buf, fi);
1629 int fuse_fs_rename(
struct fuse_fs *fs,
const char *oldpath,
1630 const char *newpath,
unsigned int flags)
1633 if (fs->op.rename) {
1635 fprintf(stderr,
"rename %s %s 0x%x\n", oldpath, newpath,
1638 return fs->op.rename(oldpath, newpath, flags);
1644 int fuse_fs_unlink(
struct fuse_fs *fs,
const char *path)
1647 if (fs->op.unlink) {
1649 fprintf(stderr,
"unlink %s\n", path);
1651 return fs->op.unlink(path);
1657 int fuse_fs_rmdir(
struct fuse_fs *fs,
const char *path)
1662 fprintf(stderr,
"rmdir %s\n", path);
1664 return fs->op.rmdir(path);
1670 int fuse_fs_symlink(
struct fuse_fs *fs,
const char *linkname,
const char *path)
1673 if (fs->op.symlink) {
1675 fprintf(stderr,
"symlink %s %s\n", linkname, path);
1677 return fs->op.symlink(linkname, path);
1683 int fuse_fs_link(
struct fuse_fs *fs,
const char *oldpath,
const char *newpath)
1688 fprintf(stderr,
"link %s %s\n", oldpath, newpath);
1690 return fs->op.link(oldpath, newpath);
1696 int fuse_fs_release(
struct fuse_fs *fs,
const char *path,
1700 if (fs->op.release) {
1702 fprintf(stderr,
"release%s[%llu] flags: 0x%x\n",
1703 fi->
flush ?
"+flush" :
"",
1704 (
unsigned long long) fi->
fh, fi->
flags);
1706 return fs->op.release(path, fi);
1712 int fuse_fs_opendir(
struct fuse_fs *fs,
const char *path,
1716 if (fs->op.opendir) {
1720 fprintf(stderr,
"opendir flags: 0x%x %s\n", fi->
flags,
1723 err = fs->op.opendir(path, fi);
1725 if (fs->debug && !err)
1726 fprintf(stderr,
" opendir[%llu] flags: 0x%x %s\n",
1727 (
unsigned long long) fi->
fh, fi->
flags, path);
1735 int fuse_fs_open(
struct fuse_fs *fs,
const char *path,
1743 fprintf(stderr,
"open flags: 0x%x %s\n", fi->
flags,
1746 err = fs->op.open(path, fi);
1748 if (fs->debug && !err)
1749 fprintf(stderr,
" open[%llu] flags: 0x%x %s\n",
1750 (
unsigned long long) fi->
fh, fi->
flags, path);
1758 static void fuse_free_buf(
struct fuse_bufvec *buf)
1763 for (i = 0; i < buf->
count; i++)
1769 int fuse_fs_read_buf(
struct fuse_fs *fs,
const char *path,
1770 struct fuse_bufvec **bufp,
size_t size, off_t off,
1774 if (fs->op.read || fs->op.read_buf) {
1779 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1780 (
unsigned long long) fi->
fh,
1781 size, (
unsigned long long) off, fi->
flags);
1783 if (fs->op.read_buf) {
1784 res = fs->op.read_buf(path, bufp, size, off, fi);
1798 *buf = FUSE_BUFVEC_INIT(size);
1802 res = fs->op.read(path, mem, size, off, fi);
1807 if (fs->debug && res >= 0)
1808 fprintf(stderr,
" read[%llu] %zu bytes from %llu\n",
1809 (
unsigned long long) fi->
fh,
1811 (
unsigned long long) off);
1813 fprintf(stderr,
"fuse: read too many bytes\n");
1824 int fuse_fs_read(
struct fuse_fs *fs,
const char *path,
char *mem,
size_t size,
1828 if (fs->op.read || fs->op.read_buf) {
1833 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1834 (
unsigned long long) fi->
fh,
1835 size, (
unsigned long long) off, fi->
flags);
1837 if (fs->op.read_buf) {
1840 res = fs->op.read_buf(path, &buf, size, off, fi);
1849 res = fs->op.read(path, mem, size, off, fi);
1852 if (fs->debug && res >= 0)
1853 fprintf(stderr,
" read[%llu] %u bytes from %llu\n",
1854 (
unsigned long long) fi->
fh,
1856 (
unsigned long long) off);
1857 if (res >= 0 && res > (
int) size)
1858 fprintf(stderr,
"fuse: read too many bytes\n");
1866 int fuse_fs_write_buf(
struct fuse_fs *fs,
const char *path,
1871 if (fs->op.write_buf || fs->op.write) {
1875 assert(buf->
idx == 0 && buf->
off == 0);
1878 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1880 (
unsigned long long) fi->
fh,
1882 (
unsigned long long) off,
1885 if (fs->op.write_buf) {
1886 res = fs->op.write_buf(path, buf, off, fi);
1892 if (buf->
count == 1 &&
1894 flatbuf = &buf->
buf[0];
1907 flatbuf = &tmp.
buf[0];
1910 res = fs->op.write(path, flatbuf->
mem, flatbuf->
size,
1916 if (fs->debug && res >= 0)
1917 fprintf(stderr,
" write%s[%llu] %u bytes to %llu\n",
1919 (
unsigned long long) fi->
fh, res,
1920 (
unsigned long long) off);
1921 if (res > (
int) size)
1922 fprintf(stderr,
"fuse: wrote too many bytes\n");
1930 int fuse_fs_write(
struct fuse_fs *fs,
const char *path,
const char *mem,
1935 bufv.
buf[0].
mem = (
void *) mem;
1937 return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1940 int fuse_fs_fsync(
struct fuse_fs *fs,
const char *path,
int datasync,
1946 fprintf(stderr,
"fsync[%llu] datasync: %i\n",
1947 (
unsigned long long) fi->
fh, datasync);
1949 return fs->op.fsync(path, datasync, fi);
1955 int fuse_fs_fsyncdir(
struct fuse_fs *fs,
const char *path,
int datasync,
1959 if (fs->op.fsyncdir) {
1961 fprintf(stderr,
"fsyncdir[%llu] datasync: %i\n",
1962 (
unsigned long long) fi->
fh, datasync);
1964 return fs->op.fsyncdir(path, datasync, fi);
1970 int fuse_fs_flush(
struct fuse_fs *fs,
const char *path,
1976 fprintf(stderr,
"flush[%llu]\n",
1977 (
unsigned long long) fi->
fh);
1979 return fs->op.flush(path, fi);
1985 int fuse_fs_statfs(
struct fuse_fs *fs,
const char *path,
struct statvfs *buf)
1988 if (fs->op.statfs) {
1990 fprintf(stderr,
"statfs %s\n", path);
1992 return fs->op.statfs(path, buf);
1994 buf->f_namemax = 255;
2000 int fuse_fs_releasedir(
struct fuse_fs *fs,
const char *path,
2004 if (fs->op.releasedir) {
2006 fprintf(stderr,
"releasedir[%llu] flags: 0x%x\n",
2007 (
unsigned long long) fi->
fh, fi->
flags);
2009 return fs->op.releasedir(path, fi);
2015 int fuse_fs_readdir(
struct fuse_fs *fs,
const char *path,
void *buf,
2021 if (fs->op.readdir) {
2023 fprintf(stderr,
"readdir%s[%llu] from %llu\n",
2025 (
unsigned long long) fi->
fh,
2026 (
unsigned long long) off);
2029 return fs->op.readdir(path, buf, filler, off, fi, flags);
2035 int fuse_fs_create(
struct fuse_fs *fs,
const char *path, mode_t mode,
2039 if (fs->op.create) {
2044 "create flags: 0x%x %s 0%o umask=0%03o\n",
2045 fi->
flags, path, mode,
2048 err = fs->op.create(path, mode, fi);
2050 if (fs->debug && !err)
2051 fprintf(stderr,
" create[%llu] flags: 0x%x %s\n",
2052 (
unsigned long long) fi->
fh, fi->
flags, path);
2060 int fuse_fs_lock(
struct fuse_fs *fs,
const char *path,
2066 fprintf(stderr,
"lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2067 (
unsigned long long) fi->
fh,
2068 (cmd == F_GETLK ?
"F_GETLK" :
2069 (cmd == F_SETLK ?
"F_SETLK" :
2070 (cmd == F_SETLKW ?
"F_SETLKW" :
"???"))),
2071 (lock->l_type == F_RDLCK ?
"F_RDLCK" :
2072 (lock->l_type == F_WRLCK ?
"F_WRLCK" :
2073 (lock->l_type == F_UNLCK ?
"F_UNLCK" :
2075 (
unsigned long long) lock->l_start,
2076 (
unsigned long long) lock->l_len,
2077 (
unsigned long long) lock->l_pid);
2079 return fs->op.lock(path, fi, cmd, lock);
2085 int fuse_fs_flock(
struct fuse_fs *fs,
const char *path,
2091 int xop = op & ~LOCK_NB;
2093 fprintf(stderr,
"lock[%llu] %s%s\n",
2094 (
unsigned long long) fi->
fh,
2095 xop == LOCK_SH ?
"LOCK_SH" :
2096 (xop == LOCK_EX ?
"LOCK_EX" :
2097 (xop == LOCK_UN ?
"LOCK_UN" :
"???")),
2098 (op & LOCK_NB) ?
"|LOCK_NB" :
"");
2100 return fs->op.flock(path, fi, op);
2106 int fuse_fs_chown(
struct fuse_fs *fs,
const char *path, uid_t uid,
2113 fprintf(stderr,
"chown[%s] %s %lu %lu\n",
2114 file_info_string(fi, buf,
sizeof(buf)),
2115 path, (
unsigned long) uid, (
unsigned long) gid);
2117 return fs->op.chown(path, uid, gid, fi);
2123 int fuse_fs_truncate(
struct fuse_fs *fs,
const char *path, off_t size,
2127 if (fs->op.truncate) {
2130 fprintf(stderr,
"truncate[%s] %llu\n",
2131 file_info_string(fi, buf,
sizeof(buf)),
2132 (
unsigned long long) size);
2134 return fs->op.truncate(path, size, fi);
2140 int fuse_fs_utimens(
struct fuse_fs *fs,
const char *path,
2144 if (fs->op.utimens) {
2147 fprintf(stderr,
"utimens[%s] %s %li.%09lu %li.%09lu\n",
2148 file_info_string(fi, buf,
sizeof(buf)),
2149 path, tv[0].tv_sec, tv[0].tv_nsec,
2150 tv[1].tv_sec, tv[1].tv_nsec);
2152 return fs->op.utimens(path, tv, fi);
2158 int fuse_fs_access(
struct fuse_fs *fs,
const char *path,
int mask)
2161 if (fs->op.access) {
2163 fprintf(stderr,
"access %s 0%o\n", path, mask);
2165 return fs->op.access(path, mask);
2171 int fuse_fs_readlink(
struct fuse_fs *fs,
const char *path,
char *buf,
2175 if (fs->op.readlink) {
2177 fprintf(stderr,
"readlink %s %lu\n", path,
2178 (
unsigned long) len);
2180 return fs->op.readlink(path, buf, len);
2186 int fuse_fs_mknod(
struct fuse_fs *fs,
const char *path, mode_t mode,
2192 fprintf(stderr,
"mknod %s 0%o 0x%llx umask=0%03o\n",
2193 path, mode, (
unsigned long long) rdev,
2196 return fs->op.mknod(path, mode, rdev);
2202 int fuse_fs_mkdir(
struct fuse_fs *fs,
const char *path, mode_t mode)
2207 fprintf(stderr,
"mkdir %s 0%o umask=0%03o\n",
2210 return fs->op.mkdir(path, mode);
2216 int fuse_fs_setxattr(
struct fuse_fs *fs,
const char *path,
const char *name,
2217 const char *value,
size_t size,
int flags)
2220 if (fs->op.setxattr) {
2222 fprintf(stderr,
"setxattr %s %s %lu 0x%x\n",
2223 path, name, (
unsigned long) size, flags);
2225 return fs->op.setxattr(path, name, value, size, flags);
2231 int fuse_fs_getxattr(
struct fuse_fs *fs,
const char *path,
const char *name,
2232 char *value,
size_t size)
2235 if (fs->op.getxattr) {
2237 fprintf(stderr,
"getxattr %s %s %lu\n",
2238 path, name, (
unsigned long) size);
2240 return fs->op.getxattr(path, name, value, size);
2246 int fuse_fs_listxattr(
struct fuse_fs *fs,
const char *path,
char *list,
2250 if (fs->op.listxattr) {
2252 fprintf(stderr,
"listxattr %s %lu\n",
2253 path, (
unsigned long) size);
2255 return fs->op.listxattr(path, list, size);
2261 int fuse_fs_bmap(
struct fuse_fs *fs,
const char *path,
size_t blocksize,
2267 fprintf(stderr,
"bmap %s blocksize: %lu index: %llu\n",
2268 path, (
unsigned long) blocksize,
2269 (
unsigned long long) *idx);
2271 return fs->op.bmap(path, blocksize, idx);
2277 int fuse_fs_removexattr(
struct fuse_fs *fs,
const char *path,
const char *name)
2280 if (fs->op.removexattr) {
2282 fprintf(stderr,
"removexattr %s %s\n", path, name);
2284 return fs->op.removexattr(path, name);
2290 int fuse_fs_ioctl(
struct fuse_fs *fs,
const char *path,
int cmd,
void *arg,
2296 fprintf(stderr,
"ioctl[%llu] 0x%x flags: 0x%x\n",
2297 (
unsigned long long) fi->
fh, cmd, flags);
2299 return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2304 int fuse_fs_poll(
struct fuse_fs *fs,
const char *path,
2313 fprintf(stderr,
"poll[%llu] ph: %p, events 0x%x\n",
2314 (
unsigned long long) fi->
fh, ph,
2317 res = fs->op.poll(path, fi, ph, reventsp);
2319 if (fs->debug && !res)
2320 fprintf(stderr,
" poll[%llu] revents: 0x%x\n",
2321 (
unsigned long long) fi->
fh, *reventsp);
2328 int fuse_fs_fallocate(
struct fuse_fs *fs,
const char *path,
int mode,
2332 if (fs->op.fallocate) {
2334 fprintf(stderr,
"fallocate %s mode %x, offset: %llu, length: %llu\n",
2337 (
unsigned long long) offset,
2338 (
unsigned long long) length);
2340 return fs->op.fallocate(path, mode, offset, length, fi);
2345 static int is_open(
struct fuse *f,
fuse_ino_t dir,
const char *name)
2349 pthread_mutex_lock(&f->lock);
2350 node = lookup_node(f, dir, name);
2351 if (node && node->open_count > 0)
2353 pthread_mutex_unlock(&f->lock);
2357 static char *hidden_name(
struct fuse *f,
fuse_ino_t dir,
const char *oldname,
2358 char *newname,
size_t bufsize)
2362 struct node *newnode;
2368 pthread_mutex_lock(&f->lock);
2369 node = lookup_node(f, dir, oldname);
2371 pthread_mutex_unlock(&f->lock);
2376 snprintf(newname, bufsize,
".fuse_hidden%08x%08x",
2377 (
unsigned int) node->nodeid, f->hidectr);
2378 newnode = lookup_node(f, dir, newname);
2381 res = try_get_path(f, dir, newname, &newpath, NULL,
false);
2382 pthread_mutex_unlock(&f->lock);
2386 memset(&buf, 0,
sizeof(buf));
2387 res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
2392 }
while(res == 0 && --failctr);
2397 static int hide_node(
struct fuse *f,
const char *oldpath,
2404 newpath = hidden_name(f, dir, oldname, newname,
sizeof(newname));
2406 err = fuse_fs_rename(f->fs, oldpath, newpath, 0);
2408 err = rename_node(f, dir, oldname, dir, newname, 1);
2414 static int mtime_eq(
const struct stat *stbuf,
const struct timespec *ts)
2416 return stbuf->st_mtime == ts->tv_sec &&
2417 ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2420 #ifndef CLOCK_MONOTONIC 2421 #define CLOCK_MONOTONIC CLOCK_REALTIME 2424 static void curr_time(
struct timespec *now)
2426 static clockid_t clockid = CLOCK_MONOTONIC;
2427 int res = clock_gettime(clockid, now);
2428 if (res == -1 && errno == EINVAL) {
2429 clockid = CLOCK_REALTIME;
2430 res = clock_gettime(clockid, now);
2433 perror(
"fuse: clock_gettime");
2438 static void update_stat(
struct node *node,
const struct stat *stbuf)
2440 if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2441 stbuf->st_size != node->size))
2442 node->cache_valid = 0;
2443 node->mtime.tv_sec = stbuf->st_mtime;
2444 node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2445 node->size = stbuf->st_size;
2446 curr_time(&node->stat_updated);
2449 static int do_lookup(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
2454 node = find_node(f, nodeid, name);
2458 e->
ino = node->nodeid;
2462 if (f->conf.auto_cache) {
2463 pthread_mutex_lock(&f->lock);
2464 update_stat(node, &e->
attr);
2465 pthread_mutex_unlock(&f->lock);
2467 set_stat(f, e->
ino, &e->
attr);
2471 static int lookup_path(
struct fuse *f,
fuse_ino_t nodeid,
2472 const char *name,
const char *path,
2478 res = fuse_fs_getattr(f->fs, path, &e->
attr, fi);
2480 res = do_lookup(f, nodeid, name, e);
2481 if (res == 0 && f->conf.debug) {
2482 fprintf(stderr,
" NODEID: %llu\n",
2483 (
unsigned long long) e->
ino);
2489 static struct fuse_context_i *fuse_get_context_internal(
void)
2491 return (
struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2494 static struct fuse_context_i *fuse_create_context(
struct fuse *f)
2496 struct fuse_context_i *c = fuse_get_context_internal();
2498 c = (
struct fuse_context_i *)
2499 calloc(1,
sizeof(
struct fuse_context_i));
2505 fprintf(stderr,
"fuse: failed to allocate thread specific data\n");
2508 pthread_setspecific(fuse_context_key, c);
2510 memset(c, 0,
sizeof(*c));
2517 static void fuse_freecontext(
void *data)
2522 static int fuse_create_context_key(
void)
2525 pthread_mutex_lock(&fuse_context_lock);
2526 if (!fuse_context_ref) {
2527 err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2529 fprintf(stderr,
"fuse: failed to create thread specific key: %s\n",
2531 pthread_mutex_unlock(&fuse_context_lock);
2536 pthread_mutex_unlock(&fuse_context_lock);
2540 static void fuse_delete_context_key(
void)
2542 pthread_mutex_lock(&fuse_context_lock);
2544 if (!fuse_context_ref) {
2545 free(pthread_getspecific(fuse_context_key));
2546 pthread_key_delete(fuse_context_key);
2548 pthread_mutex_unlock(&fuse_context_lock);
2551 static struct fuse *req_fuse_prepare(
fuse_req_t req)
2553 struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2556 c->ctx.uid = ctx->
uid;
2557 c->ctx.gid = ctx->
gid;
2558 c->ctx.pid = ctx->
pid;
2559 c->ctx.umask = ctx->
umask;
2563 static inline void reply_err(
fuse_req_t req,
int err)
2573 struct fuse *f = req_fuse(req);
2577 forget_node(f, e->
ino, 1);
2580 reply_err(req, err);
2583 void fuse_fs_init(
struct fuse_fs *fs,
struct fuse_conn_info *conn,
2587 if (!fs->op.write_buf)
2594 fs->user_data = fs->op.init(conn, cfg);
2597 static void fuse_lib_init(
void *data,
struct fuse_conn_info *conn)
2599 struct fuse *f = (
struct fuse *) data;
2601 fuse_create_context(f);
2604 fuse_fs_init(f->fs, conn, &f->conf);
2607 void fuse_fs_destroy(
struct fuse_fs *fs)
2611 fs->op.destroy(fs->user_data);
2613 fuse_put_module(fs->m);
2617 static void fuse_lib_destroy(
void *data)
2619 struct fuse *f = (
struct fuse *) data;
2621 fuse_create_context(f);
2622 fuse_fs_destroy(f->fs);
2629 struct fuse *f = req_fuse_prepare(req);
2633 struct node *dot = NULL;
2635 if (name[0] ==
'.') {
2636 int len = strlen(name);
2638 if (len == 1 || (name[1] ==
'.' && len == 2)) {
2639 pthread_mutex_lock(&f->lock);
2642 fprintf(stderr,
"LOOKUP-DOT\n");
2643 dot = get_node_nocheck(f, parent);
2645 pthread_mutex_unlock(&f->lock);
2646 reply_entry(req, &e, -ESTALE);
2652 fprintf(stderr,
"LOOKUP-DOTDOT\n");
2653 parent = get_node(f, parent)->parent->nodeid;
2655 pthread_mutex_unlock(&f->lock);
2660 err = get_path_name(f, parent, name, &path);
2662 struct fuse_intr_data d;
2664 fprintf(stderr,
"LOOKUP %s\n", path);
2665 fuse_prepare_interrupt(f, req, &d);
2666 err = lookup_path(f, parent, name, path, &e, NULL);
2667 if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2672 fuse_finish_interrupt(f, req, &d);
2673 free_path(f, parent, path);
2676 pthread_mutex_lock(&f->lock);
2678 pthread_mutex_unlock(&f->lock);
2680 reply_entry(req, &e, err);
2683 static void do_forget(
struct fuse *f,
fuse_ino_t ino, uint64_t nlookup)
2686 fprintf(stderr,
"FORGET %llu/%llu\n", (
unsigned long long)ino,
2687 (
unsigned long long) nlookup);
2688 forget_node(f, ino, nlookup);
2693 do_forget(req_fuse(req), ino, nlookup);
2697 static void fuse_lib_forget_multi(
fuse_req_t req,
size_t count,
2698 struct fuse_forget_data *forgets)
2700 struct fuse *f = req_fuse(req);
2703 for (i = 0; i < count; i++)
2704 do_forget(f, forgets[i].ino, forgets[i].nlookup);
2713 struct fuse *f = req_fuse_prepare(req);
2718 memset(&buf, 0,
sizeof(buf));
2721 err = get_path_nullok(f, ino, &path);
2723 err = get_path(f, ino, &path);
2725 struct fuse_intr_data d;
2726 fuse_prepare_interrupt(f, req, &d);
2727 err = fuse_fs_getattr(f->fs, path, &buf, fi);
2728 fuse_finish_interrupt(f, req, &d);
2729 free_path(f, ino, path);
2734 pthread_mutex_lock(&f->lock);
2735 node = get_node(f, ino);
2736 if (node->is_hidden && buf.st_nlink > 0)
2738 if (f->conf.auto_cache)
2739 update_stat(node, &buf);
2740 pthread_mutex_unlock(&f->lock);
2741 set_stat(f, ino, &buf);
2744 reply_err(req, err);
2747 int fuse_fs_chmod(
struct fuse_fs *fs,
const char *path, mode_t mode,
2754 fprintf(stderr,
"chmod[%s] %s %llo\n",
2755 file_info_string(fi, buf,
sizeof(buf)),
2756 path, (
unsigned long long) mode);
2758 return fs->op.chmod(path, mode, fi);
2767 struct fuse *f = req_fuse_prepare(req);
2772 memset(&buf, 0,
sizeof(buf));
2774 err = get_path_nullok(f, ino, &path);
2776 err = get_path(f, ino, &path);
2778 struct fuse_intr_data d;
2779 fuse_prepare_interrupt(f, req, &d);
2781 if (!err && (valid & FUSE_SET_ATTR_MODE))
2782 err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
2783 if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2784 uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2785 attr->st_uid : (uid_t) -1;
2786 gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2787 attr->st_gid : (gid_t) -1;
2788 err = fuse_fs_chown(f->fs, path, uid, gid, fi);
2790 if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2791 err = fuse_fs_truncate(f->fs, path,
2794 #ifdef HAVE_UTIMENSAT 2796 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2797 struct timespec tv[2];
2801 tv[0].tv_nsec = UTIME_OMIT;
2802 tv[1].tv_nsec = UTIME_OMIT;
2804 if (valid & FUSE_SET_ATTR_ATIME_NOW)
2805 tv[0].tv_nsec = UTIME_NOW;
2806 else if (valid & FUSE_SET_ATTR_ATIME)
2807 tv[0] = attr->st_atim;
2809 if (valid & FUSE_SET_ATTR_MTIME_NOW)
2810 tv[1].tv_nsec = UTIME_NOW;
2811 else if (valid & FUSE_SET_ATTR_MTIME)
2812 tv[1] = attr->st_mtim;
2814 err = fuse_fs_utimens(f->fs, path, tv, fi);
2818 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2819 (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2820 struct timespec tv[2];
2821 tv[0].tv_sec = attr->st_atime;
2822 tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2823 tv[1].tv_sec = attr->st_mtime;
2824 tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2825 err = fuse_fs_utimens(f->fs, path, tv, fi);
2828 err = fuse_fs_getattr(f->fs, path, &buf, fi);
2830 fuse_finish_interrupt(f, req, &d);
2831 free_path(f, ino, path);
2834 if (f->conf.auto_cache) {
2835 pthread_mutex_lock(&f->lock);
2836 update_stat(get_node(f, ino), &buf);
2837 pthread_mutex_unlock(&f->lock);
2839 set_stat(f, ino, &buf);
2842 reply_err(req, err);
2847 struct fuse *f = req_fuse_prepare(req);
2851 err = get_path(f, ino, &path);
2853 struct fuse_intr_data d;
2855 fuse_prepare_interrupt(f, req, &d);
2856 err = fuse_fs_access(f->fs, path, mask);
2857 fuse_finish_interrupt(f, req, &d);
2858 free_path(f, ino, path);
2860 reply_err(req, err);
2865 struct fuse *f = req_fuse_prepare(req);
2866 char linkname[PATH_MAX + 1];
2870 err = get_path(f, ino, &path);
2872 struct fuse_intr_data d;
2873 fuse_prepare_interrupt(f, req, &d);
2874 err = fuse_fs_readlink(f->fs, path, linkname,
sizeof(linkname));
2875 fuse_finish_interrupt(f, req, &d);
2876 free_path(f, ino, path);
2879 linkname[PATH_MAX] =
'\0';
2882 reply_err(req, err);
2886 mode_t mode, dev_t rdev)
2888 struct fuse *f = req_fuse_prepare(req);
2893 err = get_path_name(f, parent, name, &path);
2895 struct fuse_intr_data d;
2897 fuse_prepare_interrupt(f, req, &d);
2899 if (S_ISREG(mode)) {
2902 memset(&fi, 0,
sizeof(fi));
2903 fi.
flags = O_CREAT | O_EXCL | O_WRONLY;
2904 err = fuse_fs_create(f->fs, path, mode, &fi);
2906 err = lookup_path(f, parent, name, path, &e,
2908 fuse_fs_release(f->fs, path, &fi);
2911 if (err == -ENOSYS) {
2912 err = fuse_fs_mknod(f->fs, path, mode, rdev);
2914 err = lookup_path(f, parent, name, path, &e,
2917 fuse_finish_interrupt(f, req, &d);
2918 free_path(f, parent, path);
2920 reply_entry(req, &e, err);
2926 struct fuse *f = req_fuse_prepare(req);
2931 err = get_path_name(f, parent, name, &path);
2933 struct fuse_intr_data d;
2935 fuse_prepare_interrupt(f, req, &d);
2936 err = fuse_fs_mkdir(f->fs, path, mode);
2938 err = lookup_path(f, parent, name, path, &e, NULL);
2939 fuse_finish_interrupt(f, req, &d);
2940 free_path(f, parent, path);
2942 reply_entry(req, &e, err);
2948 struct fuse *f = req_fuse_prepare(req);
2953 err = get_path_wrlock(f, parent, name, &path, &wnode);
2955 struct fuse_intr_data d;
2957 fuse_prepare_interrupt(f, req, &d);
2958 if (!f->conf.hard_remove && is_open(f, parent, name)) {
2959 err = hide_node(f, path, parent, name);
2961 err = fuse_fs_unlink(f->fs, path);
2963 remove_node(f, parent, name);
2965 fuse_finish_interrupt(f, req, &d);
2966 free_path_wrlock(f, parent, wnode, path);
2968 reply_err(req, err);
2973 struct fuse *f = req_fuse_prepare(req);
2978 err = get_path_wrlock(f, parent, name, &path, &wnode);
2980 struct fuse_intr_data d;
2982 fuse_prepare_interrupt(f, req, &d);
2983 err = fuse_fs_rmdir(f->fs, path);
2984 fuse_finish_interrupt(f, req, &d);
2986 remove_node(f, parent, name);
2987 free_path_wrlock(f, parent, wnode, path);
2989 reply_err(req, err);
2992 static void fuse_lib_symlink(
fuse_req_t req,
const char *linkname,
2995 struct fuse *f = req_fuse_prepare(req);
3000 err = get_path_name(f, parent, name, &path);
3002 struct fuse_intr_data d;
3004 fuse_prepare_interrupt(f, req, &d);
3005 err = fuse_fs_symlink(f->fs, linkname, path);
3007 err = lookup_path(f, parent, name, path, &e, NULL);
3008 fuse_finish_interrupt(f, req, &d);
3009 free_path(f, parent, path);
3011 reply_entry(req, &e, err);
3016 const char *newname,
unsigned int flags)
3018 struct fuse *f = req_fuse_prepare(req);
3021 struct node *wnode1;
3022 struct node *wnode2;
3025 err = get_path2(f, olddir, oldname, newdir, newname,
3026 &oldpath, &newpath, &wnode1, &wnode2);
3028 struct fuse_intr_data d;
3030 fuse_prepare_interrupt(f, req, &d);
3031 if (!f->conf.hard_remove && !(flags & RENAME_EXCHANGE) &&
3032 is_open(f, newdir, newname))
3033 err = hide_node(f, newpath, newdir, newname);
3035 err = fuse_fs_rename(f->fs, oldpath, newpath, flags);
3037 if (flags & RENAME_EXCHANGE) {
3038 err = exchange_node(f, olddir, oldname,
3041 err = rename_node(f, olddir, oldname,
3042 newdir, newname, 0);
3046 fuse_finish_interrupt(f, req, &d);
3047 free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3049 reply_err(req, err);
3053 const char *newname)
3055 struct fuse *f = req_fuse_prepare(req);
3061 err = get_path2(f, ino, NULL, newparent, newname,
3062 &oldpath, &newpath, NULL, NULL);
3064 struct fuse_intr_data d;
3066 fuse_prepare_interrupt(f, req, &d);
3067 err = fuse_fs_link(f->fs, oldpath, newpath);
3069 err = lookup_path(f, newparent, newname, newpath,
3071 fuse_finish_interrupt(f, req, &d);
3072 free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3074 reply_entry(req, &e, err);
3077 static void fuse_do_release(
struct fuse *f,
fuse_ino_t ino,
const char *path,
3081 int unlink_hidden = 0;
3083 fuse_fs_release(f->fs, path, fi);
3085 pthread_mutex_lock(&f->lock);
3086 node = get_node(f, ino);
3087 assert(node->open_count > 0);
3089 if (node->is_hidden && !node->open_count) {
3091 node->is_hidden = 0;
3093 pthread_mutex_unlock(&f->lock);
3097 fuse_fs_unlink(f->fs, path);
3098 }
else if (f->conf.nullpath_ok) {
3101 if (get_path(f, ino, &unlinkpath) == 0)
3102 fuse_fs_unlink(f->fs, unlinkpath);
3104 free_path(f, ino, unlinkpath);
3110 const char *name, mode_t mode,
3113 struct fuse *f = req_fuse_prepare(req);
3114 struct fuse_intr_data d;
3119 err = get_path_name(f, parent, name, &path);
3121 fuse_prepare_interrupt(f, req, &d);
3122 err = fuse_fs_create(f->fs, path, mode, fi);
3124 err = lookup_path(f, parent, name, path, &e, fi);
3126 fuse_fs_release(f->fs, path, fi);
3127 else if (!S_ISREG(e.
attr.st_mode)) {
3129 fuse_fs_release(f->fs, path, fi);
3130 forget_node(f, e.
ino, 1);
3132 if (f->conf.direct_io)
3134 if (f->conf.kernel_cache)
3139 fuse_finish_interrupt(f, req, &d);
3142 pthread_mutex_lock(&f->lock);
3143 get_node(f, e.
ino)->open_count++;
3144 pthread_mutex_unlock(&f->lock);
3148 fuse_do_release(f, e.
ino, path, fi);
3149 forget_node(f, e.
ino, 1);
3152 reply_err(req, err);
3155 free_path(f, parent, path);
3158 static double diff_timespec(
const struct timespec *t1,
3159 const struct timespec *t2)
3161 return (t1->tv_sec - t2->tv_sec) +
3162 ((double) t1->tv_nsec - (
double) t2->tv_nsec) / 1000000000.0;
3165 static void open_auto_cache(
struct fuse *f,
fuse_ino_t ino,
const char *path,
3170 pthread_mutex_lock(&f->lock);
3171 node = get_node(f, ino);
3172 if (node->cache_valid) {
3173 struct timespec now;
3176 if (diff_timespec(&now, &node->stat_updated) >
3177 f->conf.ac_attr_timeout) {
3180 pthread_mutex_unlock(&f->lock);
3181 err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
3182 pthread_mutex_lock(&f->lock);
3184 update_stat(node, &stbuf);
3186 node->cache_valid = 0;
3189 if (node->cache_valid)
3192 node->cache_valid = 1;
3193 pthread_mutex_unlock(&f->lock);
3199 struct fuse *f = req_fuse_prepare(req);
3200 struct fuse_intr_data d;
3204 err = get_path(f, ino, &path);
3206 fuse_prepare_interrupt(f, req, &d);
3207 err = fuse_fs_open(f->fs, path, fi);
3209 if (f->conf.direct_io)
3211 if (f->conf.kernel_cache)
3214 if (f->conf.auto_cache)
3215 open_auto_cache(f, ino, path, fi);
3217 fuse_finish_interrupt(f, req, &d);
3220 pthread_mutex_lock(&f->lock);
3221 get_node(f, ino)->open_count++;
3222 pthread_mutex_unlock(&f->lock);
3226 fuse_do_release(f, ino, path, fi);
3229 reply_err(req, err);
3231 free_path(f, ino, path);
3237 struct fuse *f = req_fuse_prepare(req);
3242 res = get_path_nullok(f, ino, &path);
3244 struct fuse_intr_data d;
3246 fuse_prepare_interrupt(f, req, &d);
3247 res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3248 fuse_finish_interrupt(f, req, &d);
3249 free_path(f, ino, path);
3255 reply_err(req, res);
3264 struct fuse *f = req_fuse_prepare(req);
3268 res = get_path_nullok(f, ino, &path);
3270 struct fuse_intr_data d;
3272 fuse_prepare_interrupt(f, req, &d);
3273 res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3274 fuse_finish_interrupt(f, req, &d);
3275 free_path(f, ino, path);
3281 reply_err(req, res);
3287 struct fuse *f = req_fuse_prepare(req);
3291 err = get_path_nullok(f, ino, &path);
3293 struct fuse_intr_data d;
3295 fuse_prepare_interrupt(f, req, &d);
3296 err = fuse_fs_fsync(f->fs, path, datasync, fi);
3297 fuse_finish_interrupt(f, req, &d);
3298 free_path(f, ino, path);
3300 reply_err(req, err);
3303 static struct fuse_dh *get_dirhandle(
const struct fuse_file_info *llfi,
3306 struct fuse_dh *dh = (
struct fuse_dh *) (uintptr_t) llfi->
fh;
3315 struct fuse *f = req_fuse_prepare(req);
3316 struct fuse_intr_data d;
3322 dh = (
struct fuse_dh *) malloc(
sizeof(
struct fuse_dh));
3324 reply_err(req, -ENOMEM);
3327 memset(dh, 0,
sizeof(
struct fuse_dh));
3329 dh->contents = NULL;
3334 fuse_mutex_init(&dh->lock);
3336 llfi->
fh = (uintptr_t) dh;
3338 memset(&fi, 0,
sizeof(fi));
3341 err = get_path(f, ino, &path);
3343 fuse_prepare_interrupt(f, req, &d);
3344 err = fuse_fs_opendir(f->fs, path, &fi);
3345 fuse_finish_interrupt(f, req, &d);
3352 fuse_fs_releasedir(f->fs, path, &fi);
3353 pthread_mutex_destroy(&dh->lock);
3357 reply_err(req, err);
3358 pthread_mutex_destroy(&dh->lock);
3361 free_path(f, ino, path);
3364 static int extend_contents(
struct fuse_dh *dh,
unsigned minsize)
3366 if (minsize > dh->size) {
3368 unsigned newsize = dh->size;
3371 while (newsize < minsize) {
3372 if (newsize >= 0x80000000)
3373 newsize = 0xffffffff;
3378 newptr = (
char *) realloc(dh->contents, newsize);
3380 dh->error = -ENOMEM;
3383 dh->contents = newptr;
3389 static int fuse_add_direntry_to_dh(
struct fuse_dh *dh,
const char *name,
3392 struct fuse_direntry *de;
3394 de = malloc(
sizeof(
struct fuse_direntry));
3396 dh->error = -ENOMEM;
3399 de->name = strdup(name);
3401 dh->error = -ENOMEM;
3409 dh->last = &de->next;
3420 pthread_mutex_lock(&f->lock);
3421 node = lookup_node(f, parent, name);
3424 pthread_mutex_unlock(&f->lock);
3429 static int fill_dir(
void *dh_,
const char *name,
const struct stat *statp,
3432 struct fuse_dh *dh = (
struct fuse_dh *) dh_;
3443 memset(&stbuf, 0,
sizeof(stbuf));
3444 stbuf.st_ino = FUSE_UNKNOWN_INO;
3447 if (!dh->fuse->conf.use_ino) {
3448 stbuf.st_ino = FUSE_UNKNOWN_INO;
3449 if (dh->fuse->conf.readdir_ino) {
3450 stbuf.st_ino = (ino_t)
3451 lookup_nodeid(dh->fuse, dh->nodeid, name);
3468 if (extend_contents(dh, dh->needlen) == -1)
3473 dh->needlen - dh->len, name,
3475 if (newlen > dh->needlen)
3482 if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3488 static int is_dot_or_dotdot(
const char *name)
3490 return name[0] ==
'.' && (name[1] ==
'\0' ||
3491 (name[1] ==
'.' && name[2] ==
'\0'));
3494 static int fill_dir_plus(
void *dh_,
const char *name,
const struct stat *statp,
3497 struct fuse_dh *dh = (
struct fuse_dh *) dh_;
3502 struct fuse *f = dh->fuse;
3513 if (!is_dot_or_dotdot(name)) {
3514 res = do_lookup(f, dh->nodeid, name, &e);
3521 e.
attr.st_ino = FUSE_UNKNOWN_INO;
3522 if (!f->conf.use_ino && f->conf.readdir_ino) {
3523 e.
attr.st_ino = (ino_t)
3524 lookup_nodeid(f, dh->nodeid, name);
3540 if (extend_contents(dh, dh->needlen) == -1)
3545 dh->needlen - dh->len, name,
3547 if (newlen > dh->needlen)
3553 if (fuse_add_direntry_to_dh(dh, name, &e.
attr) == -1)
3560 static void free_direntries(
struct fuse_direntry *de)
3563 struct fuse_direntry *next = de->next;
3571 size_t size, off_t off,
struct fuse_dh *dh,
3578 if (f->fs->op.readdir)
3579 err = get_path_nullok(f, ino, &path);
3581 err = get_path(f, ino, &path);
3583 struct fuse_intr_data d;
3587 filler = fill_dir_plus;
3589 free_direntries(dh->first);
3591 dh->last = &dh->first;
3597 fuse_prepare_interrupt(f, req, &d);
3598 err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3599 fuse_finish_interrupt(f, req, &d);
3605 free_path(f, ino, path);
3610 static int readdir_fill_from_list(
fuse_req_t req,
struct fuse_dh *dh,
3614 struct fuse_direntry *de = dh->first;
3618 if (extend_contents(dh, dh->needlen) == -1)
3621 for (pos = 0; pos < off; pos++) {
3628 char *p = dh->contents + dh->len;
3629 unsigned rem = dh->needlen - dh->len;
3634 if (flags & FUSE_READDIR_PLUS) {
3643 de->name, &de->stat, pos);
3645 newlen = dh->len + thislen;
3646 if (newlen > dh->needlen)
3658 struct fuse *f = req_fuse_prepare(req);
3660 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3663 pthread_mutex_lock(&dh->lock);
3670 err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3672 reply_err(req, err);
3678 err = readdir_fill_from_list(req, dh, off, flags);
3680 reply_err(req, err);
3686 pthread_mutex_unlock(&dh->lock);
3692 fuse_readdir_common(req, ino, size, off, llfi, 0);
3698 fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3704 struct fuse *f = req_fuse_prepare(req);
3705 struct fuse_intr_data d;
3707 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3710 get_path_nullok(f, ino, &path);
3712 fuse_prepare_interrupt(f, req, &d);
3713 fuse_fs_releasedir(f->fs, path, &fi);
3714 fuse_finish_interrupt(f, req, &d);
3715 free_path(f, ino, path);
3717 pthread_mutex_lock(&dh->lock);
3718 pthread_mutex_unlock(&dh->lock);
3719 pthread_mutex_destroy(&dh->lock);
3720 free_direntries(dh->first);
3729 struct fuse *f = req_fuse_prepare(req);
3734 get_dirhandle(llfi, &fi);
3736 err = get_path_nullok(f, ino, &path);
3738 struct fuse_intr_data d;
3739 fuse_prepare_interrupt(f, req, &d);
3740 err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3741 fuse_finish_interrupt(f, req, &d);
3742 free_path(f, ino, path);
3744 reply_err(req, err);
3749 struct fuse *f = req_fuse_prepare(req);
3754 memset(&buf, 0,
sizeof(buf));
3756 err = get_path(f, ino, &path);
3759 struct fuse_intr_data d;
3760 fuse_prepare_interrupt(f, req, &d);
3761 err = fuse_fs_statfs(f->fs, path ? path :
"/", &buf);
3762 fuse_finish_interrupt(f, req, &d);
3763 free_path(f, ino, path);
3769 reply_err(req, err);
3773 const char *value,
size_t size,
int flags)
3775 struct fuse *f = req_fuse_prepare(req);
3779 err = get_path(f, ino, &path);
3781 struct fuse_intr_data d;
3782 fuse_prepare_interrupt(f, req, &d);
3783 err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3784 fuse_finish_interrupt(f, req, &d);
3785 free_path(f, ino, path);
3787 reply_err(req, err);
3791 const char *name,
char *value,
size_t size)
3796 err = get_path(f, ino, &path);
3798 struct fuse_intr_data d;
3799 fuse_prepare_interrupt(f, req, &d);
3800 err = fuse_fs_getxattr(f->fs, path, name, value, size);
3801 fuse_finish_interrupt(f, req, &d);
3802 free_path(f, ino, path);
3810 struct fuse *f = req_fuse_prepare(req);
3814 char *value = (
char *) malloc(size);
3815 if (value == NULL) {
3816 reply_err(req, -ENOMEM);
3819 res = common_getxattr(f, req, ino, name, value, size);
3823 reply_err(req, res);
3826 res = common_getxattr(f, req, ino, name, NULL, 0);
3830 reply_err(req, res);
3835 char *list,
size_t size)
3840 err = get_path(f, ino, &path);
3842 struct fuse_intr_data d;
3843 fuse_prepare_interrupt(f, req, &d);
3844 err = fuse_fs_listxattr(f->fs, path, list, size);
3845 fuse_finish_interrupt(f, req, &d);
3846 free_path(f, ino, path);
3853 struct fuse *f = req_fuse_prepare(req);
3857 char *list = (
char *) malloc(size);
3859 reply_err(req, -ENOMEM);
3862 res = common_listxattr(f, req, ino, list, size);
3866 reply_err(req, res);
3869 res = common_listxattr(f, req, ino, NULL, 0);
3873 reply_err(req, res);
3880 struct fuse *f = req_fuse_prepare(req);
3884 err = get_path(f, ino, &path);
3886 struct fuse_intr_data d;
3887 fuse_prepare_interrupt(f, req, &d);
3888 err = fuse_fs_removexattr(f->fs, path, name);
3889 fuse_finish_interrupt(f, req, &d);
3890 free_path(f, ino, path);
3892 reply_err(req, err);
3895 static struct lock *locks_conflict(
struct node *node,
const struct lock *lock)
3899 for (l = node->locks; l; l = l->next)
3900 if (l->owner != lock->owner &&
3901 lock->start <= l->end && l->start <= lock->end &&
3902 (l->type == F_WRLCK || lock->type == F_WRLCK))
3908 static void delete_lock(
struct lock **lockp)
3910 struct lock *l = *lockp;
3915 static void insert_lock(
struct lock **pos,
struct lock *lock)
3921 static int locks_insert(
struct node *node,
struct lock *lock)
3924 struct lock *newl1 = NULL;
3925 struct lock *newl2 = NULL;
3927 if (lock->type != F_UNLCK || lock->start != 0 ||
3928 lock->end != OFFSET_MAX) {
3929 newl1 = malloc(
sizeof(
struct lock));
3930 newl2 = malloc(
sizeof(
struct lock));
3932 if (!newl1 || !newl2) {
3939 for (lp = &node->locks; *lp;) {
3940 struct lock *l = *lp;
3941 if (l->owner != lock->owner)
3944 if (lock->type == l->type) {
3945 if (l->end < lock->start - 1)
3947 if (lock->end < l->start - 1)
3949 if (l->start <= lock->start && lock->end <= l->end)
3951 if (l->start < lock->start)
3952 lock->start = l->start;
3953 if (lock->end < l->end)
3957 if (l->end < lock->start)
3959 if (lock->end < l->start)
3961 if (lock->start <= l->start && l->end <= lock->end)
3963 if (l->end <= lock->end) {
3964 l->end = lock->start - 1;
3967 if (lock->start <= l->start) {
3968 l->start = lock->end + 1;
3972 newl2->start = lock->end + 1;
3973 l->end = lock->start - 1;
3974 insert_lock(&l->next, newl2);
3984 if (lock->type != F_UNLCK) {
3986 insert_lock(lp, newl1);
3995 static void flock_to_lock(
struct flock *flock,
struct lock *lock)
3997 memset(lock, 0,
sizeof(
struct lock));
3998 lock->type = flock->l_type;
3999 lock->start = flock->l_start;
4001 flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4002 lock->pid = flock->l_pid;
4005 static void lock_to_flock(
struct lock *lock,
struct flock *flock)
4007 flock->l_type = lock->type;
4008 flock->l_start = lock->start;
4010 (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4011 flock->l_pid = lock->pid;
4017 struct fuse_intr_data d;
4023 fuse_prepare_interrupt(f, req, &d);
4024 memset(&lock, 0,
sizeof(lock));
4025 lock.l_type = F_UNLCK;
4026 lock.l_whence = SEEK_SET;
4027 err = fuse_fs_flush(f->fs, path, fi);
4028 errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4029 fuse_finish_interrupt(f, req, &d);
4031 if (errlock != -ENOSYS) {
4032 flock_to_lock(&lock, &l);
4034 pthread_mutex_lock(&f->lock);
4035 locks_insert(get_node(f, ino), &l);
4036 pthread_mutex_unlock(&f->lock);
4049 struct fuse *f = req_fuse_prepare(req);
4050 struct fuse_intr_data d;
4054 get_path_nullok(f, ino, &path);
4056 err = fuse_flush_common(f, req, ino, path, fi);
4061 fuse_prepare_interrupt(f, req, &d);
4062 fuse_do_release(f, ino, path, fi);
4063 fuse_finish_interrupt(f, req, &d);
4064 free_path(f, ino, path);
4066 reply_err(req, err);
4072 struct fuse *f = req_fuse_prepare(req);
4076 get_path_nullok(f, ino, &path);
4077 err = fuse_flush_common(f, req, ino, path, fi);
4078 free_path(f, ino, path);
4080 reply_err(req, err);
4087 struct fuse *f = req_fuse_prepare(req);
4091 err = get_path_nullok(f, ino, &path);
4093 struct fuse_intr_data d;
4094 fuse_prepare_interrupt(f, req, &d);
4095 err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4096 fuse_finish_interrupt(f, req, &d);
4097 free_path(f, ino, path);
4107 struct lock *conflict;
4108 struct fuse *f = req_fuse(req);
4110 flock_to_lock(lock, &l);
4112 pthread_mutex_lock(&f->lock);
4113 conflict = locks_conflict(get_node(f, ino), &l);
4115 lock_to_flock(conflict, lock);
4116 pthread_mutex_unlock(&f->lock);
4118 err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4125 reply_err(req, err);
4132 int err = fuse_lock_common(req, ino, fi, lock,
4133 sleep ? F_SETLKW : F_SETLK);
4135 struct fuse *f = req_fuse(req);
4137 flock_to_lock(lock, &l);
4139 pthread_mutex_lock(&f->lock);
4140 locks_insert(get_node(f, ino), &l);
4141 pthread_mutex_unlock(&f->lock);
4143 reply_err(req, err);
4149 struct fuse *f = req_fuse_prepare(req);
4153 err = get_path_nullok(f, ino, &path);
4155 struct fuse_intr_data d;
4156 fuse_prepare_interrupt(f, req, &d);
4157 err = fuse_fs_flock(f->fs, path, fi, op);
4158 fuse_finish_interrupt(f, req, &d);
4159 free_path(f, ino, path);
4161 reply_err(req, err);
4167 struct fuse *f = req_fuse_prepare(req);
4168 struct fuse_intr_data d;
4172 err = get_path(f, ino, &path);
4174 fuse_prepare_interrupt(f, req, &d);
4175 err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4176 fuse_finish_interrupt(f, req, &d);
4177 free_path(f, ino, path);
4182 reply_err(req, err);
4187 const void *in_buf,
size_t in_bufsz,
4190 struct fuse *f = req_fuse_prepare(req);
4191 struct fuse_intr_data d;
4193 char *path, *out_buf = NULL;
4197 if (flags & FUSE_IOCTL_UNRESTRICTED)
4200 if (flags & FUSE_IOCTL_DIR)
4201 get_dirhandle(llfi, &fi);
4207 out_buf = malloc(out_bufsz);
4212 assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4213 if (out_buf && in_bufsz)
4214 memcpy(out_buf, in_buf, in_bufsz);
4216 err = get_path_nullok(f, ino, &path);
4220 fuse_prepare_interrupt(f, req, &d);
4222 err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4223 out_buf ?: (
void *)in_buf);
4225 fuse_finish_interrupt(f, req, &d);
4226 free_path(f, ino, path);
4231 reply_err(req, err);
4239 struct fuse *f = req_fuse_prepare(req);
4240 struct fuse_intr_data d;
4243 unsigned revents = 0;
4245 err = get_path_nullok(f, ino, &path);
4247 fuse_prepare_interrupt(f, req, &d);
4248 err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4249 fuse_finish_interrupt(f, req, &d);
4250 free_path(f, ino, path);
4255 reply_err(req, err);
4261 struct fuse *f = req_fuse_prepare(req);
4262 struct fuse_intr_data d;
4266 err = get_path_nullok(f, ino, &path);
4268 fuse_prepare_interrupt(f, req, &d);
4269 err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4270 fuse_finish_interrupt(f, req, &d);
4271 free_path(f, ino, path);
4273 reply_err(req, err);
4276 static int clean_delay(
struct fuse *f)
4284 int max_sleep = 3600;
4285 int sleep_time = f->conf.remember / 10;
4287 if (sleep_time > max_sleep)
4289 if (sleep_time < min_sleep)
4296 struct node_lru *lnode;
4297 struct list_head *curr, *next;
4299 struct timespec now;
4301 pthread_mutex_lock(&f->lock);
4305 for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4309 lnode = list_entry(curr,
struct node_lru, lru);
4310 node = &lnode->node;
4312 age = diff_timespec(&now, &lnode->forget_time);
4313 if (age <= f->conf.remember)
4316 assert(node->nlookup == 1);
4319 if (node->refctr > 1)
4323 unhash_name(f, node);
4324 unref_node(f, node);
4326 pthread_mutex_unlock(&f->lock);
4328 return clean_delay(f);
4332 .
init = fuse_lib_init,
4333 .destroy = fuse_lib_destroy,
4334 .lookup = fuse_lib_lookup,
4335 .forget = fuse_lib_forget,
4336 .forget_multi = fuse_lib_forget_multi,
4337 .getattr = fuse_lib_getattr,
4338 .setattr = fuse_lib_setattr,
4339 .access = fuse_lib_access,
4340 .readlink = fuse_lib_readlink,
4341 .mknod = fuse_lib_mknod,
4342 .mkdir = fuse_lib_mkdir,
4343 .unlink = fuse_lib_unlink,
4344 .rmdir = fuse_lib_rmdir,
4345 .symlink = fuse_lib_symlink,
4346 .rename = fuse_lib_rename,
4347 .link = fuse_lib_link,
4348 .create = fuse_lib_create,
4349 .open = fuse_lib_open,
4350 .read = fuse_lib_read,
4351 .write_buf = fuse_lib_write_buf,
4352 .flush = fuse_lib_flush,
4353 .release = fuse_lib_release,
4354 .fsync = fuse_lib_fsync,
4355 .opendir = fuse_lib_opendir,
4356 .readdir = fuse_lib_readdir,
4357 .readdirplus = fuse_lib_readdirplus,
4358 .releasedir = fuse_lib_releasedir,
4359 .fsyncdir = fuse_lib_fsyncdir,
4360 .statfs = fuse_lib_statfs,
4361 .setxattr = fuse_lib_setxattr,
4362 .getxattr = fuse_lib_getxattr,
4363 .listxattr = fuse_lib_listxattr,
4364 .removexattr = fuse_lib_removexattr,
4365 .getlk = fuse_lib_getlk,
4366 .setlk = fuse_lib_setlk,
4367 .flock = fuse_lib_flock,
4368 .bmap = fuse_lib_bmap,
4369 .ioctl = fuse_lib_ioctl,
4370 .poll = fuse_lib_poll,
4371 .fallocate = fuse_lib_fallocate,
4374 int fuse_notify_poll(
struct fuse_pollhandle *ph)
4384 static int fuse_session_loop_remember(
struct fuse *f)
4386 struct fuse_session *se = f->se;
4388 struct timespec now;
4390 struct pollfd fds = {
4399 next_clean = now.tv_sec;
4404 if (now.tv_sec < next_clean)
4405 timeout = next_clean - now.tv_sec;
4409 res = poll(&fds, 1, timeout * 1000);
4411 if (errno == -EINTR)
4415 }
else if (res > 0) {
4416 res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4423 fuse_session_process_buf_int(se, &fbuf, NULL);
4427 next_clean = now.tv_sec + timeout;
4433 return res < 0 ? -1 : 0;
4442 return fuse_session_loop_remember(f);
4447 FUSE_SYMVER(
".symver fuse_loop_mt_32,fuse_loop_mt@@FUSE_3.2");
4463 FUSE_SYMVER(
".symver fuse_loop_mt_31,fuse_loop_mt@FUSE_3.0");
4469 return fuse_loop_mt_32(f, &config);
4479 struct fuse_context_i *c = fuse_get_context_internal();
4489 struct fuse_context_i *c = fuse_get_context_internal();
4498 struct fuse_context_i *c = fuse_get_context_internal();
4508 int err = lookup_path_in_cache(f, path, &ino);
4516 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v } 4518 static const struct fuse_opt fuse_lib_opts[] = {
4521 FUSE_LIB_OPT(
"debug", debug, 1),
4522 FUSE_LIB_OPT(
"-d", debug, 1),
4523 FUSE_LIB_OPT(
"kernel_cache", kernel_cache, 1),
4524 FUSE_LIB_OPT(
"auto_cache", auto_cache, 1),
4525 FUSE_LIB_OPT(
"noauto_cache", auto_cache, 0),
4526 FUSE_LIB_OPT(
"umask=", set_mode, 1),
4527 FUSE_LIB_OPT(
"umask=%o", umask, 0),
4528 FUSE_LIB_OPT(
"uid=", set_uid, 1),
4529 FUSE_LIB_OPT(
"uid=%d", uid, 0),
4530 FUSE_LIB_OPT(
"gid=", set_gid, 1),
4531 FUSE_LIB_OPT(
"gid=%d", gid, 0),
4532 FUSE_LIB_OPT(
"entry_timeout=%lf", entry_timeout, 0),
4533 FUSE_LIB_OPT(
"attr_timeout=%lf", attr_timeout, 0),
4534 FUSE_LIB_OPT(
"ac_attr_timeout=%lf", ac_attr_timeout, 0),
4535 FUSE_LIB_OPT(
"ac_attr_timeout=", ac_attr_timeout_set, 1),
4536 FUSE_LIB_OPT(
"negative_timeout=%lf", negative_timeout, 0),
4537 FUSE_LIB_OPT(
"noforget", remember, -1),
4538 FUSE_LIB_OPT(
"remember=%u", remember, 0),
4539 FUSE_LIB_OPT(
"modules=%s", modules, 0),
4543 static int fuse_lib_opt_proc(
void *data,
const char *arg,
int key,
4546 (void) arg; (void) outargs; (void) data; (void) key;
4553 static const struct fuse_opt fuse_help_opts[] = {
4554 FUSE_LIB_OPT(
"modules=%s", modules, 1),
4559 static void print_module_help(
const char *name,
4566 printf(
"\nOptions for %s module:\n", name);
4575 " -o kernel_cache cache files in kernel\n" 4576 " -o [no]auto_cache enable caching based on modification times (off)\n" 4577 " -o umask=M set file permissions (octal)\n" 4578 " -o uid=N set file owner\n" 4579 " -o gid=N set file group\n" 4580 " -o entry_timeout=T cache timeout for names (1.0s)\n" 4581 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n" 4582 " -o attr_timeout=T cache timeout for attributes (1.0s)\n" 4583 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n" 4584 " -o noforget never forget cached inodes\n" 4585 " -o remember=T remember cached inodes for T seconds (0s)\n" 4586 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4593 print_module_help(
"subdir", &fuse_module_subdir_factory);
4595 print_module_help(
"iconv", &fuse_module_iconv_factory);
4602 fuse_lib_opt_proc) == -1
4611 for (module = conf.modules; module; module = next) {
4613 for (p = module; *p && *p !=
':'; p++);
4614 next = *p ? p + 1 : NULL;
4617 m = fuse_get_module(module);
4619 print_module_help(module, &m->factory);
4625 static int fuse_init_intr_signal(
int signum,
int *installed)
4627 struct sigaction old_sa;
4629 if (sigaction(signum, NULL, &old_sa) == -1) {
4630 perror(
"fuse: cannot get old signal handler");
4634 if (old_sa.sa_handler == SIG_DFL) {
4635 struct sigaction sa;
4637 memset(&sa, 0,
sizeof(
struct sigaction));
4638 sa.sa_handler = fuse_intr_sighandler;
4639 sigemptyset(&sa.sa_mask);
4641 if (sigaction(signum, &sa, NULL) == -1) {
4642 perror(
"fuse: cannot set interrupt signal handler");
4650 static void fuse_restore_intr_signal(
int signum)
4652 struct sigaction sa;
4654 memset(&sa, 0,
sizeof(
struct sigaction));
4655 sa.sa_handler = SIG_DFL;
4656 sigaction(signum, &sa, NULL);
4660 static int fuse_push_module(
struct fuse *f,
const char *module,
4663 struct fuse_fs *fs[2] = { f->fs, NULL };
4664 struct fuse_fs *newfs;
4670 newfs = m->factory(args, fs);
4686 fprintf(stderr,
"fuse: warning: library too old, some operations may not not work\n");
4690 fs = (
struct fuse_fs *) calloc(1,
sizeof(
struct fuse_fs));
4692 fprintf(stderr,
"fuse: failed to allocate fuse_fs object\n");
4696 fs->user_data = user_data;
4698 memcpy(&fs->op, op, op_size);
4702 static int node_table_init(
struct node_table *t)
4704 t->size = NODE_TABLE_MIN_SIZE;
4705 t->array = (
struct node **) calloc(1,
sizeof(
struct node *) * t->size);
4706 if (t->array == NULL) {
4707 fprintf(stderr,
"fuse: memory allocation failed\n");
4716 static void *fuse_prune_nodes(
void *fuse)
4718 struct fuse *f = fuse;
4731 return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4738 if (lru_enabled(f)) {
4739 pthread_mutex_lock(&f->lock);
4740 pthread_cancel(f->prune_thread);
4741 pthread_mutex_unlock(&f->lock);
4742 pthread_join(f->prune_thread, NULL);
4747 FUSE_SYMVER(
".symver fuse_new_31,fuse_new@@FUSE_3.1");
4748 struct fuse *fuse_new_31(
struct fuse_args *args,
4750 size_t op_size,
void *user_data)
4757 f = (
struct fuse *) calloc(1,
sizeof(
struct fuse));
4759 fprintf(stderr,
"fuse: failed to allocate fuse object\n");
4763 f->conf.entry_timeout = 1.0;
4764 f->conf.attr_timeout = 1.0;
4765 f->conf.negative_timeout = 0.0;
4766 f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4770 fuse_lib_opt_proc) == -1)
4773 pthread_mutex_lock(&fuse_context_lock);
4774 static int builtin_modules_registered = 0;
4776 if (builtin_modules_registered == 0) {
4778 fuse_register_module(
"subdir", fuse_module_subdir_factory, NULL);
4780 fuse_register_module(
"iconv", fuse_module_iconv_factory, NULL);
4782 builtin_modules_registered= 1;
4784 pthread_mutex_unlock(&fuse_context_lock);
4786 if (fuse_create_context_key() == -1)
4791 goto out_delete_context_key;
4801 f->pagesize = getpagesize();
4802 init_list_head(&f->partial_slabs);
4803 init_list_head(&f->full_slabs);
4804 init_list_head(&f->lru_table);
4806 if (f->conf.modules) {
4810 for (module = f->conf.modules; module; module = next) {
4812 for (p = module; *p && *p !=
':'; p++);
4813 next = *p ? p + 1 : NULL;
4816 fuse_push_module(f, module, args) == -1)
4821 if (!f->conf.ac_attr_timeout_set)
4822 f->conf.ac_attr_timeout = f->conf.attr_timeout;
4824 #if defined(__FreeBSD__) || defined(__NetBSD__) 4829 f->conf.readdir_ino = 1;
4836 if (f->conf.debug) {
4837 fprintf(stderr,
"nullpath_ok: %i\n", f->conf.nullpath_ok);
4841 f->fs->debug = f->conf.debug;
4844 if (node_table_init(&f->name_table) == -1)
4845 goto out_free_session;
4847 if (node_table_init(&f->id_table) == -1)
4848 goto out_free_name_table;
4850 fuse_mutex_init(&f->lock);
4852 root = alloc_node(f);
4854 fprintf(stderr,
"fuse: memory allocation failed\n");
4855 goto out_free_id_table;
4857 if (lru_enabled(f)) {
4858 struct node_lru *lnode = node_lru(root);
4859 init_list_head(&lnode->lru);
4862 strcpy(root->inline_name,
"/");
4863 root->name = root->inline_name;
4866 fuse_init_intr_signal(f->conf.intr_signal,
4867 &f->intr_installed) == -1)
4870 root->parent = NULL;
4880 free(f->id_table.array);
4881 out_free_name_table:
4882 free(f->name_table.array);
4887 fuse_put_module(f->fs->m);
4889 free(f->conf.modules);
4890 out_delete_context_key:
4891 fuse_delete_context_key();
4900 size_t op_size,
void *private_data);
4901 FUSE_SYMVER(
".symver fuse_new_30,fuse_new@FUSE_3.0");
4902 struct fuse *fuse_new_30(
struct fuse_args *args,
4904 size_t op_size,
void *user_data)
4908 memset(&conf, 0,
sizeof(conf));
4911 FUSE_LIB_OPT(
"-h", show_help, 1),
4912 FUSE_LIB_OPT(
"--help", show_help, 1),
4917 fuse_lib_opt_proc) == -1)
4924 return fuse_new_31(args, op, op_size, user_data);
4931 if (f->conf.intr && f->intr_installed)
4932 fuse_restore_intr_signal(f->conf.intr_signal);
4935 fuse_create_context(f);
4937 for (i = 0; i < f->id_table.size; i++) {
4940 for (node = f->id_table.array[i]; node != NULL;
4941 node = node->id_next) {
4942 if (node->is_hidden) {
4944 if (try_get_path(f, node->nodeid, NULL, &path, NULL,
false) == 0) {
4945 fuse_fs_unlink(f->fs, path);
4952 for (i = 0; i < f->id_table.size; i++) {
4956 for (node = f->id_table.array[i]; node != NULL; node = next) {
4957 next = node->id_next;
4962 assert(list_empty(&f->partial_slabs));
4963 assert(list_empty(&f->full_slabs));
4965 free(f->id_table.array);
4966 free(f->name_table.array);
4967 pthread_mutex_destroy(&f->lock);
4969 free(f->conf.modules);
4971 fuse_delete_context_key();
4974 int fuse_mount(
struct fuse *f,
const char *mountpoint) {
4985 return FUSE_VERSION;
4990 return PACKAGE_VERSION;
int fuse_reply_write(fuse_req_t req, size_t count)
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
void fuse_session_reset(struct fuse_session *se)
struct fuse_req * fuse_req_t
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
unsigned int max_idle_threads
void fuse_exit(struct fuse *f)
#define FUSE_CAP_POSIX_LOCKS
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
const char * fuse_pkgversion(void)
void fuse_session_unmount(struct fuse_session *se)
#define FUSE_CAP_SPLICE_READ
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_session_loop(struct fuse_session *se)
int fuse_getgroups(int size, gid_t list[])
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
#define FUSE_CAP_FLOCK_LOCKS
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
void fuse_lowlevel_help(void)
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
int fuse_req_interrupted(fuse_req_t req)
int fuse_reply_poll(fuse_req_t req, unsigned revents)
int fuse_start_cleanup_thread(struct fuse *fuse)
int fuse_invalidate_path(struct fuse *f, const char *path)
#define FUSE_ARGS_INIT(argc, argv)
int fuse_reply_err(fuse_req_t req, int err)
void * fuse_req_userdata(fuse_req_t req)
enum fuse_buf_flags flags
void fuse_lib_help(struct fuse_args *args)
void fuse_reply_none(fuse_req_t req)
int fuse_session_exited(struct fuse_session *se)
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
void fuse_session_destroy(struct fuse_session *se)
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
void fuse_session_exit(struct fuse_session *se)
int fuse_reply_readlink(fuse_req_t req, const char *link)
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
void fuse_destroy(struct fuse *f)
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
void fuse_stop_cleanup_thread(struct fuse *fuse)
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
int fuse_clean_cache(struct fuse *fuse)
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
struct fuse_session * fuse_get_session(struct fuse *f)
int fuse_loop(struct fuse *f)
struct fuse_context * fuse_get_context(void)
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
#define FUSE_OPT_KEY(templ, key)
int fuse_interrupted(void)
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
#define FUSE_OPT_KEY_KEEP
int fuse_mount(struct fuse *f, const char *mountpoint)
#define FUSE_CAP_EXPORT_SUPPORT
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
void(* init)(void *userdata, struct fuse_conn_info *conn)
void fuse_unmount(struct fuse *f)
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
int fuse_reply_xattr(fuse_req_t req, size_t count)