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;
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) {
1083 wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1084 unlock_path(f, qe->nodeid1, wnode, NULL);
1085 qe->first_locked =
false;
1087 if (qe->second_locked) {
1088 wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1089 unlock_path(f, qe->nodeid2, wnode, NULL);
1090 qe->second_locked =
false;
1094 static void queue_element_wakeup(
struct fuse *f,
struct lock_queue_element *qe)
1097 bool first = (qe == f->lockq);
1101 if (get_node(f, qe->nodeid1)->treelock == 0)
1102 pthread_cond_signal(&qe->cond);
1107 if (!qe->first_locked) {
1108 err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1111 qe->first_locked =
true;
1112 else if (err != -EAGAIN)
1115 if (!qe->second_locked && qe->path2) {
1116 err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1119 qe->second_locked =
true;
1120 else if (err != -EAGAIN)
1124 if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1137 queue_element_unlock(f, qe);
1143 queue_element_unlock(f, qe);
1147 pthread_cond_signal(&qe->cond);
1150 static void wake_up_queued(
struct fuse *f)
1152 struct lock_queue_element *qe;
1154 for (qe = f->lockq; qe != NULL; qe = qe->next)
1155 queue_element_wakeup(f, qe);
1158 static void debug_path(
struct fuse *f,
const char *msg,
fuse_ino_t nodeid,
1159 const char *name,
bool wr)
1161 if (f->conf.debug) {
1162 struct node *wnode = NULL;
1165 wnode = lookup_node(f, nodeid, name);
1168 fprintf(stderr,
"%s %llu (w)\n",
1169 msg, (
unsigned long long) wnode->nodeid);
1171 fprintf(stderr,
"%s %llu\n",
1172 msg, (
unsigned long long) nodeid);
1177 static void queue_path(
struct fuse *f,
struct lock_queue_element *qe)
1179 struct lock_queue_element **qp;
1182 qe->first_locked =
false;
1183 qe->second_locked =
false;
1184 pthread_cond_init(&qe->cond, NULL);
1186 for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1190 static void dequeue_path(
struct fuse *f,
struct lock_queue_element *qe)
1192 struct lock_queue_element **qp;
1194 pthread_cond_destroy(&qe->cond);
1195 for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1199 static int wait_path(
struct fuse *f,
struct lock_queue_element *qe)
1204 pthread_cond_wait(&qe->cond, &f->lock);
1205 }
while (!qe->done);
1207 dequeue_path(f, qe);
1212 static int get_path_common(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1213 char **path,
struct node **wnode)
1217 pthread_mutex_lock(&f->lock);
1218 err = try_get_path(f, nodeid, name, path, wnode,
true);
1219 if (err == -EAGAIN) {
1220 struct lock_queue_element qe = {
1226 debug_path(f,
"QUEUE PATH", nodeid, name, !!wnode);
1227 err = wait_path(f, &qe);
1228 debug_path(f,
"DEQUEUE PATH", nodeid, name, !!wnode);
1230 pthread_mutex_unlock(&f->lock);
1235 static int get_path(
struct fuse *f,
fuse_ino_t nodeid,
char **path)
1237 return get_path_common(f, nodeid, NULL, path, NULL);
1240 static int get_path_nullok(
struct fuse *f,
fuse_ino_t nodeid,
char **path)
1244 if (f->conf.nullpath_ok) {
1247 err = get_path_common(f, nodeid, NULL, path, NULL);
1255 static int get_path_name(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1258 return get_path_common(f, nodeid, name, path, NULL);
1261 static int get_path_wrlock(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1262 char **path,
struct node **wnode)
1264 return get_path_common(f, nodeid, name, path, wnode);
1267 #if defined(__FreeBSD__) 1268 #define CHECK_DIR_LOOP 1271 #if defined(CHECK_DIR_LOOP) 1272 static int check_dir_loop(
struct fuse *f,
1276 struct node *node, *node1, *node2;
1279 node1 = lookup_node(f, nodeid1, name1);
1280 id1 = node1 ? node1->nodeid : nodeid1;
1282 node2 = lookup_node(f, nodeid2, name2);
1283 id2 = node2 ? node2->nodeid : nodeid2;
1285 for (node = get_node(f, id2); node->nodeid !=
FUSE_ROOT_ID;
1286 node = node->parent) {
1287 if (node->name == NULL || node->parent == NULL)
1290 if (node->nodeid != id2 && node->nodeid == id1)
1296 for (node = get_node(f, id1); node->nodeid !=
FUSE_ROOT_ID;
1297 node = node->parent) {
1298 if (node->name == NULL || node->parent == NULL)
1301 if (node->nodeid != id1 && node->nodeid == id2)
1310 static int try_get_path2(
struct fuse *f,
fuse_ino_t nodeid1,
const char *name1,
1312 char **path1,
char **path2,
1313 struct node **wnode1,
struct node **wnode2)
1318 err = try_get_path(f, nodeid1, name1, path1, wnode1,
true);
1320 err = try_get_path(f, nodeid2, name2, path2, wnode2,
true);
1322 struct node *wn1 = wnode1 ? *wnode1 : NULL;
1324 unlock_path(f, nodeid1, wn1, NULL);
1331 static int get_path2(
struct fuse *f,
fuse_ino_t nodeid1,
const char *name1,
1333 char **path1,
char **path2,
1334 struct node **wnode1,
struct node **wnode2)
1338 pthread_mutex_lock(&f->lock);
1340 #if defined(CHECK_DIR_LOOP) 1344 err = check_dir_loop(f, nodeid1, name1, nodeid2, name2);
1350 err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1351 path1, path2, wnode1, wnode2);
1352 if (err == -EAGAIN) {
1353 struct lock_queue_element qe = {
1364 debug_path(f,
"QUEUE PATH1", nodeid1, name1, !!wnode1);
1365 debug_path(f,
" PATH2", nodeid2, name2, !!wnode2);
1366 err = wait_path(f, &qe);
1367 debug_path(f,
"DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1368 debug_path(f,
" PATH2", nodeid2, name2, !!wnode2);
1371 #if defined(CHECK_DIR_LOOP) 1374 pthread_mutex_unlock(&f->lock);
1379 static void free_path_wrlock(
struct fuse *f,
fuse_ino_t nodeid,
1380 struct node *wnode,
char *path)
1382 pthread_mutex_lock(&f->lock);
1383 unlock_path(f, nodeid, wnode, NULL);
1386 pthread_mutex_unlock(&f->lock);
1390 static void free_path(
struct fuse *f,
fuse_ino_t nodeid,
char *path)
1393 free_path_wrlock(f, nodeid, NULL, path);
1397 struct node *wnode1,
struct node *wnode2,
1398 char *path1,
char *path2)
1400 pthread_mutex_lock(&f->lock);
1401 unlock_path(f, nodeid1, wnode1, NULL);
1402 unlock_path(f, nodeid2, wnode2, NULL);
1404 pthread_mutex_unlock(&f->lock);
1409 static void forget_node(
struct fuse *f,
fuse_ino_t nodeid, uint64_t nlookup)
1414 pthread_mutex_lock(&f->lock);
1415 node = get_node(f, nodeid);
1421 while (node->nlookup == nlookup && node->treelock) {
1422 struct lock_queue_element qe = {
1426 debug_path(f,
"QUEUE PATH (forget)", nodeid, NULL,
false);
1430 pthread_cond_wait(&qe.cond, &f->lock);
1431 }
while (node->nlookup == nlookup && node->treelock);
1433 dequeue_path(f, &qe);
1434 debug_path(f,
"DEQUEUE_PATH (forget)", nodeid, NULL,
false);
1437 assert(node->nlookup >= nlookup);
1438 node->nlookup -= nlookup;
1439 if (!node->nlookup) {
1440 unref_node(f, node);
1441 }
else if (lru_enabled(f) && node->nlookup == 1) {
1442 set_forget_time(f, node);
1444 pthread_mutex_unlock(&f->lock);
1447 static void unlink_node(
struct fuse *f,
struct node *node)
1449 if (f->conf.remember) {
1450 assert(node->nlookup > 1);
1453 unhash_name(f, node);
1456 static void remove_node(
struct fuse *f,
fuse_ino_t dir,
const char *name)
1460 pthread_mutex_lock(&f->lock);
1461 node = lookup_node(f, dir, name);
1463 unlink_node(f, node);
1464 pthread_mutex_unlock(&f->lock);
1467 static int rename_node(
struct fuse *f,
fuse_ino_t olddir,
const char *oldname,
1468 fuse_ino_t newdir,
const char *newname,
int hide)
1471 struct node *newnode;
1474 pthread_mutex_lock(&f->lock);
1475 node = lookup_node(f, olddir, oldname);
1476 newnode = lookup_node(f, newdir, newname);
1480 if (newnode != NULL) {
1482 fprintf(stderr,
"fuse: hidden file got created during hiding\n");
1486 unlink_node(f, newnode);
1489 unhash_name(f, node);
1490 if (hash_name(f, node, newdir, newname) == -1) {
1496 node->is_hidden = 1;
1499 pthread_mutex_unlock(&f->lock);
1503 static int exchange_node(
struct fuse *f,
fuse_ino_t olddir,
const char *oldname,
1506 struct node *oldnode;
1507 struct node *newnode;
1510 pthread_mutex_lock(&f->lock);
1511 oldnode = lookup_node(f, olddir, oldname);
1512 newnode = lookup_node(f, newdir, newname);
1515 unhash_name(f, oldnode);
1517 unhash_name(f, newnode);
1521 if (hash_name(f, oldnode, newdir, newname) == -1)
1525 if (hash_name(f, newnode, olddir, oldname) == -1)
1530 pthread_mutex_unlock(&f->lock);
1534 static void set_stat(
struct fuse *f,
fuse_ino_t nodeid,
struct stat *stbuf)
1536 if (!f->conf.use_ino)
1537 stbuf->st_ino = nodeid;
1538 if (f->conf.set_mode)
1539 stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1540 (0777 & ~f->conf.umask);
1541 if (f->conf.set_uid)
1542 stbuf->st_uid = f->conf.uid;
1543 if (f->conf.set_gid)
1544 stbuf->st_gid = f->conf.gid;
1552 static void fuse_intr_sighandler(
int sig)
1558 struct fuse_intr_data {
1560 pthread_cond_t cond;
1564 static void fuse_interrupt(
fuse_req_t req,
void *d_)
1566 struct fuse_intr_data *d = d_;
1567 struct fuse *f = req_fuse(req);
1569 if (d->id == pthread_self())
1572 pthread_mutex_lock(&f->lock);
1573 while (!d->finished) {
1575 struct timespec timeout;
1577 pthread_kill(d->id, f->conf.intr_signal);
1578 gettimeofday(&now, NULL);
1579 timeout.tv_sec = now.tv_sec + 1;
1580 timeout.tv_nsec = now.tv_usec * 1000;
1581 pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1583 pthread_mutex_unlock(&f->lock);
1586 static void fuse_do_finish_interrupt(
struct fuse *f,
fuse_req_t req,
1587 struct fuse_intr_data *d)
1589 pthread_mutex_lock(&f->lock);
1591 pthread_cond_broadcast(&d->cond);
1592 pthread_mutex_unlock(&f->lock);
1594 pthread_cond_destroy(&d->cond);
1597 static void fuse_do_prepare_interrupt(
fuse_req_t req,
struct fuse_intr_data *d)
1599 d->id = pthread_self();
1600 pthread_cond_init(&d->cond, NULL);
1605 static inline void fuse_finish_interrupt(
struct fuse *f,
fuse_req_t req,
1606 struct fuse_intr_data *d)
1609 fuse_do_finish_interrupt(f, req, d);
1612 static inline void fuse_prepare_interrupt(
struct fuse *f,
fuse_req_t req,
1613 struct fuse_intr_data *d)
1616 fuse_do_prepare_interrupt(req, d);
1620 char* buf,
size_t len)
1624 snprintf(buf, len,
"%llu", (
unsigned long long) fi->
fh);
1628 int fuse_fs_getattr(
struct fuse_fs *fs,
const char *path,
struct stat *buf,
1632 if (fs->op.getattr) {
1635 fprintf(stderr,
"getattr[%s] %s\n",
1636 file_info_string(fi, buf,
sizeof(buf)),
1639 return fs->op.getattr(path, buf, fi);
1645 int fuse_fs_rename(
struct fuse_fs *fs,
const char *oldpath,
1646 const char *newpath,
unsigned int flags)
1649 if (fs->op.rename) {
1651 fprintf(stderr,
"rename %s %s 0x%x\n", oldpath, newpath,
1654 return fs->op.rename(oldpath, newpath, flags);
1660 int fuse_fs_unlink(
struct fuse_fs *fs,
const char *path)
1663 if (fs->op.unlink) {
1665 fprintf(stderr,
"unlink %s\n", path);
1667 return fs->op.unlink(path);
1673 int fuse_fs_rmdir(
struct fuse_fs *fs,
const char *path)
1678 fprintf(stderr,
"rmdir %s\n", path);
1680 return fs->op.rmdir(path);
1686 int fuse_fs_symlink(
struct fuse_fs *fs,
const char *linkname,
const char *path)
1689 if (fs->op.symlink) {
1691 fprintf(stderr,
"symlink %s %s\n", linkname, path);
1693 return fs->op.symlink(linkname, path);
1699 int fuse_fs_link(
struct fuse_fs *fs,
const char *oldpath,
const char *newpath)
1704 fprintf(stderr,
"link %s %s\n", oldpath, newpath);
1706 return fs->op.link(oldpath, newpath);
1712 int fuse_fs_release(
struct fuse_fs *fs,
const char *path,
1716 if (fs->op.release) {
1718 fprintf(stderr,
"release%s[%llu] flags: 0x%x\n",
1719 fi->
flush ?
"+flush" :
"",
1720 (
unsigned long long) fi->
fh, fi->
flags);
1722 return fs->op.release(path, fi);
1728 int fuse_fs_opendir(
struct fuse_fs *fs,
const char *path,
1732 if (fs->op.opendir) {
1736 fprintf(stderr,
"opendir flags: 0x%x %s\n", fi->
flags,
1739 err = fs->op.opendir(path, fi);
1741 if (fs->debug && !err)
1742 fprintf(stderr,
" opendir[%llu] flags: 0x%x %s\n",
1743 (
unsigned long long) fi->
fh, fi->
flags, path);
1751 int fuse_fs_open(
struct fuse_fs *fs,
const char *path,
1759 fprintf(stderr,
"open flags: 0x%x %s\n", fi->
flags,
1762 err = fs->op.open(path, fi);
1764 if (fs->debug && !err)
1765 fprintf(stderr,
" open[%llu] flags: 0x%x %s\n",
1766 (
unsigned long long) fi->
fh, fi->
flags, path);
1774 static void fuse_free_buf(
struct fuse_bufvec *buf)
1779 for (i = 0; i < buf->
count; i++)
1786 int fuse_fs_read_buf(
struct fuse_fs *fs,
const char *path,
1787 struct fuse_bufvec **bufp,
size_t size, off_t off,
1791 if (fs->op.read || fs->op.read_buf) {
1796 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1797 (
unsigned long long) fi->
fh,
1798 size, (
unsigned long long) off, fi->
flags);
1800 if (fs->op.read_buf) {
1801 res = fs->op.read_buf(path, bufp, size, off, fi);
1815 *buf = FUSE_BUFVEC_INIT(size);
1819 res = fs->op.read(path, mem, size, off, fi);
1824 if (fs->debug && res >= 0)
1825 fprintf(stderr,
" read[%llu] %zu bytes from %llu\n",
1826 (
unsigned long long) fi->
fh,
1828 (
unsigned long long) off);
1830 fprintf(stderr,
"fuse: read too many bytes\n");
1841 int fuse_fs_read(
struct fuse_fs *fs,
const char *path,
char *mem,
size_t size,
1845 if (fs->op.read || fs->op.read_buf) {
1850 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1851 (
unsigned long long) fi->
fh,
1852 size, (
unsigned long long) off, fi->
flags);
1854 if (fs->op.read_buf) {
1857 res = fs->op.read_buf(path, &buf, size, off, fi);
1866 res = fs->op.read(path, mem, size, off, fi);
1869 if (fs->debug && res >= 0)
1870 fprintf(stderr,
" read[%llu] %u bytes from %llu\n",
1871 (
unsigned long long) fi->
fh,
1873 (
unsigned long long) off);
1874 if (res >= 0 && res > (
int) size)
1875 fprintf(stderr,
"fuse: read too many bytes\n");
1883 int fuse_fs_write_buf(
struct fuse_fs *fs,
const char *path,
1888 if (fs->op.write_buf || fs->op.write) {
1892 assert(buf->
idx == 0 && buf->
off == 0);
1895 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1897 (
unsigned long long) fi->
fh,
1899 (
unsigned long long) off,
1902 if (fs->op.write_buf) {
1903 res = fs->op.write_buf(path, buf, off, fi);
1909 if (buf->
count == 1 &&
1911 flatbuf = &buf->
buf[0];
1924 flatbuf = &tmp.
buf[0];
1927 res = fs->op.write(path, flatbuf->
mem, flatbuf->
size,
1933 if (fs->debug && res >= 0)
1934 fprintf(stderr,
" write%s[%llu] %u bytes to %llu\n",
1936 (
unsigned long long) fi->
fh, res,
1937 (
unsigned long long) off);
1938 if (res > (
int) size)
1939 fprintf(stderr,
"fuse: wrote too many bytes\n");
1947 int fuse_fs_write(
struct fuse_fs *fs,
const char *path,
const char *mem,
1952 bufv.
buf[0].
mem = (
void *) mem;
1954 return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1957 int fuse_fs_fsync(
struct fuse_fs *fs,
const char *path,
int datasync,
1963 fprintf(stderr,
"fsync[%llu] datasync: %i\n",
1964 (
unsigned long long) fi->
fh, datasync);
1966 return fs->op.fsync(path, datasync, fi);
1972 int fuse_fs_fsyncdir(
struct fuse_fs *fs,
const char *path,
int datasync,
1976 if (fs->op.fsyncdir) {
1978 fprintf(stderr,
"fsyncdir[%llu] datasync: %i\n",
1979 (
unsigned long long) fi->
fh, datasync);
1981 return fs->op.fsyncdir(path, datasync, fi);
1987 int fuse_fs_flush(
struct fuse_fs *fs,
const char *path,
1993 fprintf(stderr,
"flush[%llu]\n",
1994 (
unsigned long long) fi->
fh);
1996 return fs->op.flush(path, fi);
2002 int fuse_fs_statfs(
struct fuse_fs *fs,
const char *path,
struct statvfs *buf)
2005 if (fs->op.statfs) {
2007 fprintf(stderr,
"statfs %s\n", path);
2009 return fs->op.statfs(path, buf);
2011 buf->f_namemax = 255;
2017 int fuse_fs_releasedir(
struct fuse_fs *fs,
const char *path,
2021 if (fs->op.releasedir) {
2023 fprintf(stderr,
"releasedir[%llu] flags: 0x%x\n",
2024 (
unsigned long long) fi->
fh, fi->
flags);
2026 return fs->op.releasedir(path, fi);
2032 int fuse_fs_readdir(
struct fuse_fs *fs,
const char *path,
void *buf,
2038 if (fs->op.readdir) {
2040 fprintf(stderr,
"readdir%s[%llu] from %llu\n",
2042 (
unsigned long long) fi->
fh,
2043 (
unsigned long long) off);
2046 return fs->op.readdir(path, buf, filler, off, fi, flags);
2052 int fuse_fs_create(
struct fuse_fs *fs,
const char *path, mode_t mode,
2056 if (fs->op.create) {
2061 "create flags: 0x%x %s 0%o umask=0%03o\n",
2062 fi->
flags, path, mode,
2065 err = fs->op.create(path, mode, fi);
2067 if (fs->debug && !err)
2068 fprintf(stderr,
" create[%llu] flags: 0x%x %s\n",
2069 (
unsigned long long) fi->
fh, fi->
flags, path);
2077 int fuse_fs_lock(
struct fuse_fs *fs,
const char *path,
2083 fprintf(stderr,
"lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2084 (
unsigned long long) fi->
fh,
2085 (cmd == F_GETLK ?
"F_GETLK" :
2086 (cmd == F_SETLK ?
"F_SETLK" :
2087 (cmd == F_SETLKW ?
"F_SETLKW" :
"???"))),
2088 (lock->l_type == F_RDLCK ?
"F_RDLCK" :
2089 (lock->l_type == F_WRLCK ?
"F_WRLCK" :
2090 (lock->l_type == F_UNLCK ?
"F_UNLCK" :
2092 (
unsigned long long) lock->l_start,
2093 (
unsigned long long) lock->l_len,
2094 (
unsigned long long) lock->l_pid);
2096 return fs->op.lock(path, fi, cmd, lock);
2102 int fuse_fs_flock(
struct fuse_fs *fs,
const char *path,
2108 int xop = op & ~LOCK_NB;
2110 fprintf(stderr,
"lock[%llu] %s%s\n",
2111 (
unsigned long long) fi->
fh,
2112 xop == LOCK_SH ?
"LOCK_SH" :
2113 (xop == LOCK_EX ?
"LOCK_EX" :
2114 (xop == LOCK_UN ?
"LOCK_UN" :
"???")),
2115 (op & LOCK_NB) ?
"|LOCK_NB" :
"");
2117 return fs->op.flock(path, fi, op);
2123 int fuse_fs_chown(
struct fuse_fs *fs,
const char *path, uid_t uid,
2130 fprintf(stderr,
"chown[%s] %s %lu %lu\n",
2131 file_info_string(fi, buf,
sizeof(buf)),
2132 path, (
unsigned long) uid, (
unsigned long) gid);
2134 return fs->op.chown(path, uid, gid, fi);
2140 int fuse_fs_truncate(
struct fuse_fs *fs,
const char *path, off_t size,
2144 if (fs->op.truncate) {
2147 fprintf(stderr,
"truncate[%s] %llu\n",
2148 file_info_string(fi, buf,
sizeof(buf)),
2149 (
unsigned long long) size);
2151 return fs->op.truncate(path, size, fi);
2157 int fuse_fs_utimens(
struct fuse_fs *fs,
const char *path,
2161 if (fs->op.utimens) {
2164 fprintf(stderr,
"utimens[%s] %s %li.%09lu %li.%09lu\n",
2165 file_info_string(fi, buf,
sizeof(buf)),
2166 path, tv[0].tv_sec, tv[0].tv_nsec,
2167 tv[1].tv_sec, tv[1].tv_nsec);
2169 return fs->op.utimens(path, tv, fi);
2175 int fuse_fs_access(
struct fuse_fs *fs,
const char *path,
int mask)
2178 if (fs->op.access) {
2180 fprintf(stderr,
"access %s 0%o\n", path, mask);
2182 return fs->op.access(path, mask);
2188 int fuse_fs_readlink(
struct fuse_fs *fs,
const char *path,
char *buf,
2192 if (fs->op.readlink) {
2194 fprintf(stderr,
"readlink %s %lu\n", path,
2195 (
unsigned long) len);
2197 return fs->op.readlink(path, buf, len);
2203 int fuse_fs_mknod(
struct fuse_fs *fs,
const char *path, mode_t mode,
2209 fprintf(stderr,
"mknod %s 0%o 0x%llx umask=0%03o\n",
2210 path, mode, (
unsigned long long) rdev,
2213 return fs->op.mknod(path, mode, rdev);
2219 int fuse_fs_mkdir(
struct fuse_fs *fs,
const char *path, mode_t mode)
2224 fprintf(stderr,
"mkdir %s 0%o umask=0%03o\n",
2227 return fs->op.mkdir(path, mode);
2233 int fuse_fs_setxattr(
struct fuse_fs *fs,
const char *path,
const char *name,
2234 const char *value,
size_t size,
int flags)
2237 if (fs->op.setxattr) {
2239 fprintf(stderr,
"setxattr %s %s %lu 0x%x\n",
2240 path, name, (
unsigned long) size, flags);
2242 return fs->op.setxattr(path, name, value, size, flags);
2248 int fuse_fs_getxattr(
struct fuse_fs *fs,
const char *path,
const char *name,
2249 char *value,
size_t size)
2252 if (fs->op.getxattr) {
2254 fprintf(stderr,
"getxattr %s %s %lu\n",
2255 path, name, (
unsigned long) size);
2257 return fs->op.getxattr(path, name, value, size);
2263 int fuse_fs_listxattr(
struct fuse_fs *fs,
const char *path,
char *list,
2267 if (fs->op.listxattr) {
2269 fprintf(stderr,
"listxattr %s %lu\n",
2270 path, (
unsigned long) size);
2272 return fs->op.listxattr(path, list, size);
2278 int fuse_fs_bmap(
struct fuse_fs *fs,
const char *path,
size_t blocksize,
2284 fprintf(stderr,
"bmap %s blocksize: %lu index: %llu\n",
2285 path, (
unsigned long) blocksize,
2286 (
unsigned long long) *idx);
2288 return fs->op.bmap(path, blocksize, idx);
2294 int fuse_fs_removexattr(
struct fuse_fs *fs,
const char *path,
const char *name)
2297 if (fs->op.removexattr) {
2299 fprintf(stderr,
"removexattr %s %s\n", path, name);
2301 return fs->op.removexattr(path, name);
2307 int fuse_fs_ioctl(
struct fuse_fs *fs,
const char *path,
unsigned int cmd,
2314 fprintf(stderr,
"ioctl[%llu] 0x%x flags: 0x%x\n",
2315 (
unsigned long long) fi->
fh, cmd, flags);
2317 return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2322 int fuse_fs_poll(
struct fuse_fs *fs,
const char *path,
2331 fprintf(stderr,
"poll[%llu] ph: %p, events 0x%x\n",
2332 (
unsigned long long) fi->
fh, ph,
2335 res = fs->op.poll(path, fi, ph, reventsp);
2337 if (fs->debug && !res)
2338 fprintf(stderr,
" poll[%llu] revents: 0x%x\n",
2339 (
unsigned long long) fi->
fh, *reventsp);
2346 int fuse_fs_fallocate(
struct fuse_fs *fs,
const char *path,
int mode,
2350 if (fs->op.fallocate) {
2352 fprintf(stderr,
"fallocate %s mode %x, offset: %llu, length: %llu\n",
2355 (
unsigned long long) offset,
2356 (
unsigned long long) length);
2358 return fs->op.fallocate(path, mode, offset, length, fi);
2363 ssize_t fuse_fs_copy_file_range(
struct fuse_fs *fs,
const char *path_in,
2365 const char *path_out,
2367 size_t len,
int flags)
2370 if (fs->op.copy_file_range) {
2372 fprintf(stderr,
"copy_file_range from %s:%llu to " 2373 "%s:%llu, length: %llu\n",
2375 (
unsigned long long) off_in,
2377 (
unsigned long long) off_out,
2378 (
unsigned long long) len);
2380 return fs->op.copy_file_range(path_in, fi_in, off_in, path_out,
2381 fi_out, off_out, len, flags);
2386 static int is_open(
struct fuse *f,
fuse_ino_t dir,
const char *name)
2390 pthread_mutex_lock(&f->lock);
2391 node = lookup_node(f, dir, name);
2392 if (node && node->open_count > 0)
2394 pthread_mutex_unlock(&f->lock);
2398 static char *hidden_name(
struct fuse *f,
fuse_ino_t dir,
const char *oldname,
2399 char *newname,
size_t bufsize)
2403 struct node *newnode;
2409 pthread_mutex_lock(&f->lock);
2410 node = lookup_node(f, dir, oldname);
2412 pthread_mutex_unlock(&f->lock);
2417 snprintf(newname, bufsize,
".fuse_hidden%08x%08x",
2418 (
unsigned int) node->nodeid, f->hidectr);
2419 newnode = lookup_node(f, dir, newname);
2422 res = try_get_path(f, dir, newname, &newpath, NULL,
false);
2423 pthread_mutex_unlock(&f->lock);
2427 memset(&buf, 0,
sizeof(buf));
2428 res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
2433 }
while(res == 0 && --failctr);
2438 static int hide_node(
struct fuse *f,
const char *oldpath,
2445 newpath = hidden_name(f, dir, oldname, newname,
sizeof(newname));
2447 err = fuse_fs_rename(f->fs, oldpath, newpath, 0);
2449 err = rename_node(f, dir, oldname, dir, newname, 1);
2455 static int mtime_eq(
const struct stat *stbuf,
const struct timespec *ts)
2457 return stbuf->st_mtime == ts->tv_sec &&
2458 ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2461 #ifndef CLOCK_MONOTONIC 2462 #define CLOCK_MONOTONIC CLOCK_REALTIME 2465 static void curr_time(
struct timespec *now)
2467 static clockid_t clockid = CLOCK_MONOTONIC;
2468 int res = clock_gettime(clockid, now);
2469 if (res == -1 && errno == EINVAL) {
2470 clockid = CLOCK_REALTIME;
2471 res = clock_gettime(clockid, now);
2474 perror(
"fuse: clock_gettime");
2479 static void update_stat(
struct node *node,
const struct stat *stbuf)
2481 if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2482 stbuf->st_size != node->size))
2483 node->cache_valid = 0;
2484 node->mtime.tv_sec = stbuf->st_mtime;
2485 node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2486 node->size = stbuf->st_size;
2487 curr_time(&node->stat_updated);
2490 static int do_lookup(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
2495 node = find_node(f, nodeid, name);
2499 e->
ino = node->nodeid;
2503 if (f->conf.auto_cache) {
2504 pthread_mutex_lock(&f->lock);
2505 update_stat(node, &e->
attr);
2506 pthread_mutex_unlock(&f->lock);
2508 set_stat(f, e->
ino, &e->
attr);
2512 static int lookup_path(
struct fuse *f,
fuse_ino_t nodeid,
2513 const char *name,
const char *path,
2519 res = fuse_fs_getattr(f->fs, path, &e->
attr, fi);
2521 res = do_lookup(f, nodeid, name, e);
2522 if (res == 0 && f->conf.debug) {
2523 fprintf(stderr,
" NODEID: %llu\n",
2524 (
unsigned long long) e->
ino);
2530 static struct fuse_context_i *fuse_get_context_internal(
void)
2532 return (
struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2535 static struct fuse_context_i *fuse_create_context(
struct fuse *f)
2537 struct fuse_context_i *c = fuse_get_context_internal();
2539 c = (
struct fuse_context_i *)
2540 calloc(1,
sizeof(
struct fuse_context_i));
2546 fprintf(stderr,
"fuse: failed to allocate thread specific data\n");
2549 pthread_setspecific(fuse_context_key, c);
2551 memset(c, 0,
sizeof(*c));
2558 static void fuse_freecontext(
void *data)
2563 static int fuse_create_context_key(
void)
2566 pthread_mutex_lock(&fuse_context_lock);
2567 if (!fuse_context_ref) {
2568 err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2570 fprintf(stderr,
"fuse: failed to create thread specific key: %s\n",
2572 pthread_mutex_unlock(&fuse_context_lock);
2577 pthread_mutex_unlock(&fuse_context_lock);
2581 static void fuse_delete_context_key(
void)
2583 pthread_mutex_lock(&fuse_context_lock);
2585 if (!fuse_context_ref) {
2586 free(pthread_getspecific(fuse_context_key));
2587 pthread_key_delete(fuse_context_key);
2589 pthread_mutex_unlock(&fuse_context_lock);
2592 static struct fuse *req_fuse_prepare(
fuse_req_t req)
2594 struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2597 c->ctx.uid = ctx->
uid;
2598 c->ctx.gid = ctx->
gid;
2599 c->ctx.pid = ctx->
pid;
2600 c->ctx.umask = ctx->
umask;
2604 static inline void reply_err(
fuse_req_t req,
int err)
2614 struct fuse *f = req_fuse(req);
2618 forget_node(f, e->
ino, 1);
2621 reply_err(req, err);
2624 void fuse_fs_init(
struct fuse_fs *fs,
struct fuse_conn_info *conn,
2628 if (!fs->op.write_buf)
2635 fs->user_data = fs->op.init(conn, cfg);
2638 static void fuse_lib_init(
void *data,
struct fuse_conn_info *conn)
2640 struct fuse *f = (
struct fuse *) data;
2642 fuse_create_context(f);
2645 fuse_fs_init(f->fs, conn, &f->conf);
2648 void fuse_fs_destroy(
struct fuse_fs *fs)
2652 fs->op.destroy(fs->user_data);
2654 fuse_put_module(fs->m);
2658 static void fuse_lib_destroy(
void *data)
2660 struct fuse *f = (
struct fuse *) data;
2662 fuse_create_context(f);
2663 fuse_fs_destroy(f->fs);
2670 struct fuse *f = req_fuse_prepare(req);
2674 struct node *dot = NULL;
2676 if (name[0] ==
'.') {
2677 int len = strlen(name);
2679 if (len == 1 || (name[1] ==
'.' && len == 2)) {
2680 pthread_mutex_lock(&f->lock);
2683 fprintf(stderr,
"LOOKUP-DOT\n");
2684 dot = get_node_nocheck(f, parent);
2686 pthread_mutex_unlock(&f->lock);
2687 reply_entry(req, &e, -ESTALE);
2693 fprintf(stderr,
"LOOKUP-DOTDOT\n");
2694 parent = get_node(f, parent)->parent->nodeid;
2696 pthread_mutex_unlock(&f->lock);
2701 err = get_path_name(f, parent, name, &path);
2703 struct fuse_intr_data d;
2705 fprintf(stderr,
"LOOKUP %s\n", path);
2706 fuse_prepare_interrupt(f, req, &d);
2707 err = lookup_path(f, parent, name, path, &e, NULL);
2708 if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2713 fuse_finish_interrupt(f, req, &d);
2714 free_path(f, parent, path);
2717 pthread_mutex_lock(&f->lock);
2719 pthread_mutex_unlock(&f->lock);
2721 reply_entry(req, &e, err);
2724 static void do_forget(
struct fuse *f,
fuse_ino_t ino, uint64_t nlookup)
2727 fprintf(stderr,
"FORGET %llu/%llu\n", (
unsigned long long)ino,
2728 (
unsigned long long) nlookup);
2729 forget_node(f, ino, nlookup);
2734 do_forget(req_fuse(req), ino, nlookup);
2738 static void fuse_lib_forget_multi(
fuse_req_t req,
size_t count,
2739 struct fuse_forget_data *forgets)
2741 struct fuse *f = req_fuse(req);
2744 for (i = 0; i < count; i++)
2745 do_forget(f, forgets[i].ino, forgets[i].nlookup);
2754 struct fuse *f = req_fuse_prepare(req);
2759 memset(&buf, 0,
sizeof(buf));
2762 err = get_path_nullok(f, ino, &path);
2764 err = get_path(f, ino, &path);
2766 struct fuse_intr_data d;
2767 fuse_prepare_interrupt(f, req, &d);
2768 err = fuse_fs_getattr(f->fs, path, &buf, fi);
2769 fuse_finish_interrupt(f, req, &d);
2770 free_path(f, ino, path);
2775 pthread_mutex_lock(&f->lock);
2776 node = get_node(f, ino);
2777 if (node->is_hidden && buf.st_nlink > 0)
2779 if (f->conf.auto_cache)
2780 update_stat(node, &buf);
2781 pthread_mutex_unlock(&f->lock);
2782 set_stat(f, ino, &buf);
2785 reply_err(req, err);
2788 int fuse_fs_chmod(
struct fuse_fs *fs,
const char *path, mode_t mode,
2795 fprintf(stderr,
"chmod[%s] %s %llo\n",
2796 file_info_string(fi, buf,
sizeof(buf)),
2797 path, (
unsigned long long) mode);
2799 return fs->op.chmod(path, mode, fi);
2808 struct fuse *f = req_fuse_prepare(req);
2813 memset(&buf, 0,
sizeof(buf));
2815 err = get_path_nullok(f, ino, &path);
2817 err = get_path(f, ino, &path);
2819 struct fuse_intr_data d;
2820 fuse_prepare_interrupt(f, req, &d);
2822 if (!err && (valid & FUSE_SET_ATTR_MODE))
2823 err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
2824 if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2825 uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2826 attr->st_uid : (uid_t) -1;
2827 gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2828 attr->st_gid : (gid_t) -1;
2829 err = fuse_fs_chown(f->fs, path, uid, gid, fi);
2831 if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2832 err = fuse_fs_truncate(f->fs, path,
2835 #ifdef HAVE_UTIMENSAT 2837 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2838 struct timespec tv[2];
2842 tv[0].tv_nsec = UTIME_OMIT;
2843 tv[1].tv_nsec = UTIME_OMIT;
2845 if (valid & FUSE_SET_ATTR_ATIME_NOW)
2846 tv[0].tv_nsec = UTIME_NOW;
2847 else if (valid & FUSE_SET_ATTR_ATIME)
2848 tv[0] = attr->st_atim;
2850 if (valid & FUSE_SET_ATTR_MTIME_NOW)
2851 tv[1].tv_nsec = UTIME_NOW;
2852 else if (valid & FUSE_SET_ATTR_MTIME)
2853 tv[1] = attr->st_mtim;
2855 err = fuse_fs_utimens(f->fs, path, tv, fi);
2859 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2860 (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2861 struct timespec tv[2];
2862 tv[0].tv_sec = attr->st_atime;
2863 tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2864 tv[1].tv_sec = attr->st_mtime;
2865 tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2866 err = fuse_fs_utimens(f->fs, path, tv, fi);
2869 err = fuse_fs_getattr(f->fs, path, &buf, fi);
2871 fuse_finish_interrupt(f, req, &d);
2872 free_path(f, ino, path);
2875 if (f->conf.auto_cache) {
2876 pthread_mutex_lock(&f->lock);
2877 update_stat(get_node(f, ino), &buf);
2878 pthread_mutex_unlock(&f->lock);
2880 set_stat(f, ino, &buf);
2883 reply_err(req, err);
2888 struct fuse *f = req_fuse_prepare(req);
2892 err = get_path(f, ino, &path);
2894 struct fuse_intr_data d;
2896 fuse_prepare_interrupt(f, req, &d);
2897 err = fuse_fs_access(f->fs, path, mask);
2898 fuse_finish_interrupt(f, req, &d);
2899 free_path(f, ino, path);
2901 reply_err(req, err);
2906 struct fuse *f = req_fuse_prepare(req);
2907 char linkname[PATH_MAX + 1];
2911 err = get_path(f, ino, &path);
2913 struct fuse_intr_data d;
2914 fuse_prepare_interrupt(f, req, &d);
2915 err = fuse_fs_readlink(f->fs, path, linkname,
sizeof(linkname));
2916 fuse_finish_interrupt(f, req, &d);
2917 free_path(f, ino, path);
2920 linkname[PATH_MAX] =
'\0';
2923 reply_err(req, err);
2927 mode_t mode, dev_t rdev)
2929 struct fuse *f = req_fuse_prepare(req);
2934 err = get_path_name(f, parent, name, &path);
2936 struct fuse_intr_data d;
2938 fuse_prepare_interrupt(f, req, &d);
2940 if (S_ISREG(mode)) {
2943 memset(&fi, 0,
sizeof(fi));
2944 fi.
flags = O_CREAT | O_EXCL | O_WRONLY;
2945 err = fuse_fs_create(f->fs, path, mode, &fi);
2947 err = lookup_path(f, parent, name, path, &e,
2949 fuse_fs_release(f->fs, path, &fi);
2952 if (err == -ENOSYS) {
2953 err = fuse_fs_mknod(f->fs, path, mode, rdev);
2955 err = lookup_path(f, parent, name, path, &e,
2958 fuse_finish_interrupt(f, req, &d);
2959 free_path(f, parent, path);
2961 reply_entry(req, &e, err);
2967 struct fuse *f = req_fuse_prepare(req);
2972 err = get_path_name(f, parent, name, &path);
2974 struct fuse_intr_data d;
2976 fuse_prepare_interrupt(f, req, &d);
2977 err = fuse_fs_mkdir(f->fs, path, mode);
2979 err = lookup_path(f, parent, name, path, &e, NULL);
2980 fuse_finish_interrupt(f, req, &d);
2981 free_path(f, parent, path);
2983 reply_entry(req, &e, err);
2989 struct fuse *f = req_fuse_prepare(req);
2994 err = get_path_wrlock(f, parent, name, &path, &wnode);
2996 struct fuse_intr_data d;
2998 fuse_prepare_interrupt(f, req, &d);
2999 if (!f->conf.hard_remove && is_open(f, parent, name)) {
3000 err = hide_node(f, path, parent, name);
3002 err = fuse_fs_unlink(f->fs, path);
3004 remove_node(f, parent, name);
3006 fuse_finish_interrupt(f, req, &d);
3007 free_path_wrlock(f, parent, wnode, path);
3009 reply_err(req, err);
3014 struct fuse *f = req_fuse_prepare(req);
3019 err = get_path_wrlock(f, parent, name, &path, &wnode);
3021 struct fuse_intr_data d;
3023 fuse_prepare_interrupt(f, req, &d);
3024 err = fuse_fs_rmdir(f->fs, path);
3025 fuse_finish_interrupt(f, req, &d);
3027 remove_node(f, parent, name);
3028 free_path_wrlock(f, parent, wnode, path);
3030 reply_err(req, err);
3033 static void fuse_lib_symlink(
fuse_req_t req,
const char *linkname,
3036 struct fuse *f = req_fuse_prepare(req);
3041 err = get_path_name(f, parent, name, &path);
3043 struct fuse_intr_data d;
3045 fuse_prepare_interrupt(f, req, &d);
3046 err = fuse_fs_symlink(f->fs, linkname, path);
3048 err = lookup_path(f, parent, name, path, &e, NULL);
3049 fuse_finish_interrupt(f, req, &d);
3050 free_path(f, parent, path);
3052 reply_entry(req, &e, err);
3057 const char *newname,
unsigned int flags)
3059 struct fuse *f = req_fuse_prepare(req);
3062 struct node *wnode1;
3063 struct node *wnode2;
3066 err = get_path2(f, olddir, oldname, newdir, newname,
3067 &oldpath, &newpath, &wnode1, &wnode2);
3069 struct fuse_intr_data d;
3071 fuse_prepare_interrupt(f, req, &d);
3072 if (!f->conf.hard_remove && !(flags & RENAME_EXCHANGE) &&
3073 is_open(f, newdir, newname))
3074 err = hide_node(f, newpath, newdir, newname);
3076 err = fuse_fs_rename(f->fs, oldpath, newpath, flags);
3078 if (flags & RENAME_EXCHANGE) {
3079 err = exchange_node(f, olddir, oldname,
3082 err = rename_node(f, olddir, oldname,
3083 newdir, newname, 0);
3087 fuse_finish_interrupt(f, req, &d);
3088 free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3090 reply_err(req, err);
3094 const char *newname)
3096 struct fuse *f = req_fuse_prepare(req);
3102 err = get_path2(f, ino, NULL, newparent, newname,
3103 &oldpath, &newpath, NULL, NULL);
3105 struct fuse_intr_data d;
3107 fuse_prepare_interrupt(f, req, &d);
3108 err = fuse_fs_link(f->fs, oldpath, newpath);
3110 err = lookup_path(f, newparent, newname, newpath,
3112 fuse_finish_interrupt(f, req, &d);
3113 free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3115 reply_entry(req, &e, err);
3118 static void fuse_do_release(
struct fuse *f,
fuse_ino_t ino,
const char *path,
3122 int unlink_hidden = 0;
3124 fuse_fs_release(f->fs, path, fi);
3126 pthread_mutex_lock(&f->lock);
3127 node = get_node(f, ino);
3128 assert(node->open_count > 0);
3130 if (node->is_hidden && !node->open_count) {
3132 node->is_hidden = 0;
3134 pthread_mutex_unlock(&f->lock);
3138 fuse_fs_unlink(f->fs, path);
3139 }
else if (f->conf.nullpath_ok) {
3142 if (get_path(f, ino, &unlinkpath) == 0)
3143 fuse_fs_unlink(f->fs, unlinkpath);
3145 free_path(f, ino, unlinkpath);
3151 const char *name, mode_t mode,
3154 struct fuse *f = req_fuse_prepare(req);
3155 struct fuse_intr_data d;
3160 err = get_path_name(f, parent, name, &path);
3162 fuse_prepare_interrupt(f, req, &d);
3163 err = fuse_fs_create(f->fs, path, mode, fi);
3165 err = lookup_path(f, parent, name, path, &e, fi);
3167 fuse_fs_release(f->fs, path, fi);
3168 else if (!S_ISREG(e.
attr.st_mode)) {
3170 fuse_fs_release(f->fs, path, fi);
3171 forget_node(f, e.
ino, 1);
3173 if (f->conf.direct_io)
3175 if (f->conf.kernel_cache)
3180 fuse_finish_interrupt(f, req, &d);
3183 pthread_mutex_lock(&f->lock);
3184 get_node(f, e.
ino)->open_count++;
3185 pthread_mutex_unlock(&f->lock);
3189 fuse_do_release(f, e.
ino, path, fi);
3190 forget_node(f, e.
ino, 1);
3193 reply_err(req, err);
3196 free_path(f, parent, path);
3199 static double diff_timespec(
const struct timespec *t1,
3200 const struct timespec *t2)
3202 return (t1->tv_sec - t2->tv_sec) +
3203 ((double) t1->tv_nsec - (
double) t2->tv_nsec) / 1000000000.0;
3206 static void open_auto_cache(
struct fuse *f,
fuse_ino_t ino,
const char *path,
3211 pthread_mutex_lock(&f->lock);
3212 node = get_node(f, ino);
3213 if (node->cache_valid) {
3214 struct timespec now;
3217 if (diff_timespec(&now, &node->stat_updated) >
3218 f->conf.ac_attr_timeout) {
3221 pthread_mutex_unlock(&f->lock);
3222 err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
3223 pthread_mutex_lock(&f->lock);
3225 update_stat(node, &stbuf);
3227 node->cache_valid = 0;
3230 if (node->cache_valid)
3233 node->cache_valid = 1;
3234 pthread_mutex_unlock(&f->lock);
3240 struct fuse *f = req_fuse_prepare(req);
3241 struct fuse_intr_data d;
3245 err = get_path(f, ino, &path);
3247 fuse_prepare_interrupt(f, req, &d);
3248 err = fuse_fs_open(f->fs, path, fi);
3250 if (f->conf.direct_io)
3252 if (f->conf.kernel_cache)
3255 if (f->conf.auto_cache)
3256 open_auto_cache(f, ino, path, fi);
3258 fuse_finish_interrupt(f, req, &d);
3261 pthread_mutex_lock(&f->lock);
3262 get_node(f, ino)->open_count++;
3263 pthread_mutex_unlock(&f->lock);
3267 fuse_do_release(f, ino, path, fi);
3270 reply_err(req, err);
3272 free_path(f, ino, path);
3278 struct fuse *f = req_fuse_prepare(req);
3283 res = get_path_nullok(f, ino, &path);
3285 struct fuse_intr_data d;
3287 fuse_prepare_interrupt(f, req, &d);
3288 res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3289 fuse_finish_interrupt(f, req, &d);
3290 free_path(f, ino, path);
3296 reply_err(req, res);
3305 struct fuse *f = req_fuse_prepare(req);
3309 res = get_path_nullok(f, ino, &path);
3311 struct fuse_intr_data d;
3313 fuse_prepare_interrupt(f, req, &d);
3314 res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3315 fuse_finish_interrupt(f, req, &d);
3316 free_path(f, ino, path);
3322 reply_err(req, res);
3328 struct fuse *f = req_fuse_prepare(req);
3332 err = get_path_nullok(f, ino, &path);
3334 struct fuse_intr_data d;
3336 fuse_prepare_interrupt(f, req, &d);
3337 err = fuse_fs_fsync(f->fs, path, datasync, fi);
3338 fuse_finish_interrupt(f, req, &d);
3339 free_path(f, ino, path);
3341 reply_err(req, err);
3344 static struct fuse_dh *get_dirhandle(
const struct fuse_file_info *llfi,
3347 struct fuse_dh *dh = (
struct fuse_dh *) (uintptr_t) llfi->
fh;
3356 struct fuse *f = req_fuse_prepare(req);
3357 struct fuse_intr_data d;
3363 dh = (
struct fuse_dh *) malloc(
sizeof(
struct fuse_dh));
3365 reply_err(req, -ENOMEM);
3368 memset(dh, 0,
sizeof(
struct fuse_dh));
3370 dh->contents = NULL;
3375 fuse_mutex_init(&dh->lock);
3377 llfi->
fh = (uintptr_t) dh;
3379 memset(&fi, 0,
sizeof(fi));
3382 err = get_path(f, ino, &path);
3384 fuse_prepare_interrupt(f, req, &d);
3385 err = fuse_fs_opendir(f->fs, path, &fi);
3386 fuse_finish_interrupt(f, req, &d);
3393 fuse_fs_releasedir(f->fs, path, &fi);
3394 pthread_mutex_destroy(&dh->lock);
3398 reply_err(req, err);
3399 pthread_mutex_destroy(&dh->lock);
3402 free_path(f, ino, path);
3405 static int extend_contents(
struct fuse_dh *dh,
unsigned minsize)
3407 if (minsize > dh->size) {
3409 unsigned newsize = dh->size;
3412 while (newsize < minsize) {
3413 if (newsize >= 0x80000000)
3414 newsize = 0xffffffff;
3419 newptr = (
char *) realloc(dh->contents, newsize);
3421 dh->error = -ENOMEM;
3424 dh->contents = newptr;
3430 static int fuse_add_direntry_to_dh(
struct fuse_dh *dh,
const char *name,
3433 struct fuse_direntry *de;
3435 de = malloc(
sizeof(
struct fuse_direntry));
3437 dh->error = -ENOMEM;
3440 de->name = strdup(name);
3442 dh->error = -ENOMEM;
3450 dh->last = &de->next;
3461 pthread_mutex_lock(&f->lock);
3462 node = lookup_node(f, parent, name);
3465 pthread_mutex_unlock(&f->lock);
3470 static int fill_dir(
void *dh_,
const char *name,
const struct stat *statp,
3473 struct fuse_dh *dh = (
struct fuse_dh *) dh_;
3484 memset(&stbuf, 0,
sizeof(stbuf));
3485 stbuf.st_ino = FUSE_UNKNOWN_INO;
3488 if (!dh->fuse->conf.use_ino) {
3489 stbuf.st_ino = FUSE_UNKNOWN_INO;
3490 if (dh->fuse->conf.readdir_ino) {
3491 stbuf.st_ino = (ino_t)
3492 lookup_nodeid(dh->fuse, dh->nodeid, name);
3509 if (extend_contents(dh, dh->needlen) == -1)
3514 dh->needlen - dh->len, name,
3516 if (newlen > dh->needlen)
3523 if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3529 static int is_dot_or_dotdot(
const char *name)
3531 return name[0] ==
'.' && (name[1] ==
'\0' ||
3532 (name[1] ==
'.' && name[2] ==
'\0'));
3535 static int fill_dir_plus(
void *dh_,
const char *name,
const struct stat *statp,
3538 struct fuse_dh *dh = (
struct fuse_dh *) dh_;
3543 struct fuse *f = dh->fuse;
3554 if (!is_dot_or_dotdot(name)) {
3555 res = do_lookup(f, dh->nodeid, name, &e);
3562 e.
attr.st_ino = FUSE_UNKNOWN_INO;
3563 if (!f->conf.use_ino && f->conf.readdir_ino) {
3564 e.
attr.st_ino = (ino_t)
3565 lookup_nodeid(f, dh->nodeid, name);
3581 if (extend_contents(dh, dh->needlen) == -1)
3586 dh->needlen - dh->len, name,
3588 if (newlen > dh->needlen)
3594 if (fuse_add_direntry_to_dh(dh, name, &e.
attr) == -1)
3601 static void free_direntries(
struct fuse_direntry *de)
3604 struct fuse_direntry *next = de->next;
3612 size_t size, off_t off,
struct fuse_dh *dh,
3619 if (f->fs->op.readdir)
3620 err = get_path_nullok(f, ino, &path);
3622 err = get_path(f, ino, &path);
3624 struct fuse_intr_data d;
3628 filler = fill_dir_plus;
3630 free_direntries(dh->first);
3632 dh->last = &dh->first;
3638 fuse_prepare_interrupt(f, req, &d);
3639 err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3640 fuse_finish_interrupt(f, req, &d);
3646 free_path(f, ino, path);
3651 static int readdir_fill_from_list(
fuse_req_t req,
struct fuse_dh *dh,
3655 struct fuse_direntry *de = dh->first;
3659 if (extend_contents(dh, dh->needlen) == -1)
3662 for (pos = 0; pos < off; pos++) {
3669 char *p = dh->contents + dh->len;
3670 unsigned rem = dh->needlen - dh->len;
3675 if (flags & FUSE_READDIR_PLUS) {
3684 de->name, &de->stat, pos);
3686 newlen = dh->len + thislen;
3687 if (newlen > dh->needlen)
3699 struct fuse *f = req_fuse_prepare(req);
3701 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3704 pthread_mutex_lock(&dh->lock);
3711 err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3713 reply_err(req, err);
3719 err = readdir_fill_from_list(req, dh, off, flags);
3721 reply_err(req, err);
3727 pthread_mutex_unlock(&dh->lock);
3733 fuse_readdir_common(req, ino, size, off, llfi, 0);
3739 fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3745 struct fuse *f = req_fuse_prepare(req);
3746 struct fuse_intr_data d;
3748 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3751 get_path_nullok(f, ino, &path);
3753 fuse_prepare_interrupt(f, req, &d);
3754 fuse_fs_releasedir(f->fs, path, &fi);
3755 fuse_finish_interrupt(f, req, &d);
3756 free_path(f, ino, path);
3758 pthread_mutex_lock(&dh->lock);
3759 pthread_mutex_unlock(&dh->lock);
3760 pthread_mutex_destroy(&dh->lock);
3761 free_direntries(dh->first);
3770 struct fuse *f = req_fuse_prepare(req);
3775 get_dirhandle(llfi, &fi);
3777 err = get_path_nullok(f, ino, &path);
3779 struct fuse_intr_data d;
3780 fuse_prepare_interrupt(f, req, &d);
3781 err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3782 fuse_finish_interrupt(f, req, &d);
3783 free_path(f, ino, path);
3785 reply_err(req, err);
3790 struct fuse *f = req_fuse_prepare(req);
3795 memset(&buf, 0,
sizeof(buf));
3797 err = get_path(f, ino, &path);
3800 struct fuse_intr_data d;
3801 fuse_prepare_interrupt(f, req, &d);
3802 err = fuse_fs_statfs(f->fs, path ? path :
"/", &buf);
3803 fuse_finish_interrupt(f, req, &d);
3804 free_path(f, ino, path);
3810 reply_err(req, err);
3814 const char *value,
size_t size,
int flags)
3816 struct fuse *f = req_fuse_prepare(req);
3820 err = get_path(f, ino, &path);
3822 struct fuse_intr_data d;
3823 fuse_prepare_interrupt(f, req, &d);
3824 err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3825 fuse_finish_interrupt(f, req, &d);
3826 free_path(f, ino, path);
3828 reply_err(req, err);
3832 const char *name,
char *value,
size_t size)
3837 err = get_path(f, ino, &path);
3839 struct fuse_intr_data d;
3840 fuse_prepare_interrupt(f, req, &d);
3841 err = fuse_fs_getxattr(f->fs, path, name, value, size);
3842 fuse_finish_interrupt(f, req, &d);
3843 free_path(f, ino, path);
3851 struct fuse *f = req_fuse_prepare(req);
3855 char *value = (
char *) malloc(size);
3856 if (value == NULL) {
3857 reply_err(req, -ENOMEM);
3860 res = common_getxattr(f, req, ino, name, value, size);
3864 reply_err(req, res);
3867 res = common_getxattr(f, req, ino, name, NULL, 0);
3871 reply_err(req, res);
3876 char *list,
size_t size)
3881 err = get_path(f, ino, &path);
3883 struct fuse_intr_data d;
3884 fuse_prepare_interrupt(f, req, &d);
3885 err = fuse_fs_listxattr(f->fs, path, list, size);
3886 fuse_finish_interrupt(f, req, &d);
3887 free_path(f, ino, path);
3894 struct fuse *f = req_fuse_prepare(req);
3898 char *list = (
char *) malloc(size);
3900 reply_err(req, -ENOMEM);
3903 res = common_listxattr(f, req, ino, list, size);
3907 reply_err(req, res);
3910 res = common_listxattr(f, req, ino, NULL, 0);
3914 reply_err(req, res);
3921 struct fuse *f = req_fuse_prepare(req);
3925 err = get_path(f, ino, &path);
3927 struct fuse_intr_data d;
3928 fuse_prepare_interrupt(f, req, &d);
3929 err = fuse_fs_removexattr(f->fs, path, name);
3930 fuse_finish_interrupt(f, req, &d);
3931 free_path(f, ino, path);
3933 reply_err(req, err);
3936 static struct lock *locks_conflict(
struct node *node,
const struct lock *lock)
3940 for (l = node->locks; l; l = l->next)
3941 if (l->owner != lock->owner &&
3942 lock->start <= l->end && l->start <= lock->end &&
3943 (l->type == F_WRLCK || lock->type == F_WRLCK))
3949 static void delete_lock(
struct lock **lockp)
3951 struct lock *l = *lockp;
3956 static void insert_lock(
struct lock **pos,
struct lock *lock)
3962 static int locks_insert(
struct node *node,
struct lock *lock)
3965 struct lock *newl1 = NULL;
3966 struct lock *newl2 = NULL;
3968 if (lock->type != F_UNLCK || lock->start != 0 ||
3969 lock->end != OFFSET_MAX) {
3970 newl1 = malloc(
sizeof(
struct lock));
3971 newl2 = malloc(
sizeof(
struct lock));
3973 if (!newl1 || !newl2) {
3980 for (lp = &node->locks; *lp;) {
3981 struct lock *l = *lp;
3982 if (l->owner != lock->owner)
3985 if (lock->type == l->type) {
3986 if (l->end < lock->start - 1)
3988 if (lock->end < l->start - 1)
3990 if (l->start <= lock->start && lock->end <= l->end)
3992 if (l->start < lock->start)
3993 lock->start = l->start;
3994 if (lock->end < l->end)
3998 if (l->end < lock->start)
4000 if (lock->end < l->start)
4002 if (lock->start <= l->start && l->end <= lock->end)
4004 if (l->end <= lock->end) {
4005 l->end = lock->start - 1;
4008 if (lock->start <= l->start) {
4009 l->start = lock->end + 1;
4013 newl2->start = lock->end + 1;
4014 l->end = lock->start - 1;
4015 insert_lock(&l->next, newl2);
4025 if (lock->type != F_UNLCK) {
4027 insert_lock(lp, newl1);
4036 static void flock_to_lock(
struct flock *flock,
struct lock *lock)
4038 memset(lock, 0,
sizeof(
struct lock));
4039 lock->type = flock->l_type;
4040 lock->start = flock->l_start;
4042 flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4043 lock->pid = flock->l_pid;
4046 static void lock_to_flock(
struct lock *lock,
struct flock *flock)
4048 flock->l_type = lock->type;
4049 flock->l_start = lock->start;
4051 (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4052 flock->l_pid = lock->pid;
4058 struct fuse_intr_data d;
4064 fuse_prepare_interrupt(f, req, &d);
4065 memset(&lock, 0,
sizeof(lock));
4066 lock.l_type = F_UNLCK;
4067 lock.l_whence = SEEK_SET;
4068 err = fuse_fs_flush(f->fs, path, fi);
4069 errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4070 fuse_finish_interrupt(f, req, &d);
4072 if (errlock != -ENOSYS) {
4073 flock_to_lock(&lock, &l);
4075 pthread_mutex_lock(&f->lock);
4076 locks_insert(get_node(f, ino), &l);
4077 pthread_mutex_unlock(&f->lock);
4090 struct fuse *f = req_fuse_prepare(req);
4091 struct fuse_intr_data d;
4095 get_path_nullok(f, ino, &path);
4097 err = fuse_flush_common(f, req, ino, path, fi);
4102 fuse_prepare_interrupt(f, req, &d);
4103 fuse_do_release(f, ino, path, fi);
4104 fuse_finish_interrupt(f, req, &d);
4105 free_path(f, ino, path);
4107 reply_err(req, err);
4113 struct fuse *f = req_fuse_prepare(req);
4117 get_path_nullok(f, ino, &path);
4118 err = fuse_flush_common(f, req, ino, path, fi);
4119 free_path(f, ino, path);
4121 reply_err(req, err);
4128 struct fuse *f = req_fuse_prepare(req);
4132 err = get_path_nullok(f, ino, &path);
4134 struct fuse_intr_data d;
4135 fuse_prepare_interrupt(f, req, &d);
4136 err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4137 fuse_finish_interrupt(f, req, &d);
4138 free_path(f, ino, path);
4148 struct lock *conflict;
4149 struct fuse *f = req_fuse(req);
4151 flock_to_lock(lock, &l);
4153 pthread_mutex_lock(&f->lock);
4154 conflict = locks_conflict(get_node(f, ino), &l);
4156 lock_to_flock(conflict, lock);
4157 pthread_mutex_unlock(&f->lock);
4159 err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4166 reply_err(req, err);
4173 int err = fuse_lock_common(req, ino, fi, lock,
4174 sleep ? F_SETLKW : F_SETLK);
4176 struct fuse *f = req_fuse(req);
4178 flock_to_lock(lock, &l);
4180 pthread_mutex_lock(&f->lock);
4181 locks_insert(get_node(f, ino), &l);
4182 pthread_mutex_unlock(&f->lock);
4184 reply_err(req, err);
4190 struct fuse *f = req_fuse_prepare(req);
4194 err = get_path_nullok(f, ino, &path);
4196 struct fuse_intr_data d;
4197 fuse_prepare_interrupt(f, req, &d);
4198 err = fuse_fs_flock(f->fs, path, fi, op);
4199 fuse_finish_interrupt(f, req, &d);
4200 free_path(f, ino, path);
4202 reply_err(req, err);
4208 struct fuse *f = req_fuse_prepare(req);
4209 struct fuse_intr_data d;
4213 err = get_path(f, ino, &path);
4215 fuse_prepare_interrupt(f, req, &d);
4216 err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4217 fuse_finish_interrupt(f, req, &d);
4218 free_path(f, ino, path);
4223 reply_err(req, err);
4228 unsigned int flags,
const void *in_buf,
4229 size_t in_bufsz,
size_t out_bufsz)
4231 struct fuse *f = req_fuse_prepare(req);
4232 struct fuse_intr_data d;
4234 char *path, *out_buf = NULL;
4238 if (flags & FUSE_IOCTL_UNRESTRICTED)
4241 if (flags & FUSE_IOCTL_DIR)
4242 get_dirhandle(llfi, &fi);
4248 out_buf = malloc(out_bufsz);
4253 assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4254 if (out_buf && in_bufsz)
4255 memcpy(out_buf, in_buf, in_bufsz);
4257 err = get_path_nullok(f, ino, &path);
4261 fuse_prepare_interrupt(f, req, &d);
4263 err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4264 out_buf ? out_buf : (
void *)in_buf);
4266 fuse_finish_interrupt(f, req, &d);
4267 free_path(f, ino, path);
4272 reply_err(req, err);
4280 struct fuse *f = req_fuse_prepare(req);
4281 struct fuse_intr_data d;
4284 unsigned revents = 0;
4286 err = get_path_nullok(f, ino, &path);
4288 fuse_prepare_interrupt(f, req, &d);
4289 err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4290 fuse_finish_interrupt(f, req, &d);
4291 free_path(f, ino, path);
4296 reply_err(req, err);
4302 struct fuse *f = req_fuse_prepare(req);
4303 struct fuse_intr_data d;
4307 err = get_path_nullok(f, ino, &path);
4309 fuse_prepare_interrupt(f, req, &d);
4310 err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4311 fuse_finish_interrupt(f, req, &d);
4312 free_path(f, ino, path);
4314 reply_err(req, err);
4323 struct fuse *f = req_fuse_prepare(req);
4324 struct fuse_intr_data d;
4325 char *path_in, *path_out;
4329 err = get_path_nullok(f, nodeid_in, &path_in);
4331 reply_err(req, err);
4335 err = get_path_nullok(f, nodeid_out, &path_out);
4337 free_path(f, nodeid_in, path_in);
4338 reply_err(req, err);
4342 fuse_prepare_interrupt(f, req, &d);
4343 res = fuse_fs_copy_file_range(f->fs, path_in, fi_in, off_in, path_out,
4344 fi_out, off_out, len, flags);
4345 fuse_finish_interrupt(f, req, &d);
4350 reply_err(req, res);
4352 free_path(f, nodeid_in, path_in);
4353 free_path(f, nodeid_out, path_out);
4356 static int clean_delay(
struct fuse *f)
4364 int max_sleep = 3600;
4365 int sleep_time = f->conf.remember / 10;
4367 if (sleep_time > max_sleep)
4369 if (sleep_time < min_sleep)
4376 struct node_lru *lnode;
4377 struct list_head *curr, *next;
4379 struct timespec now;
4381 pthread_mutex_lock(&f->lock);
4385 for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4389 lnode = list_entry(curr,
struct node_lru, lru);
4390 node = &lnode->node;
4392 age = diff_timespec(&now, &lnode->forget_time);
4393 if (age <= f->conf.remember)
4396 assert(node->nlookup == 1);
4399 if (node->refctr > 1)
4403 unhash_name(f, node);
4404 unref_node(f, node);
4406 pthread_mutex_unlock(&f->lock);
4408 return clean_delay(f);
4412 .
init = fuse_lib_init,
4413 .destroy = fuse_lib_destroy,
4414 .lookup = fuse_lib_lookup,
4415 .forget = fuse_lib_forget,
4416 .forget_multi = fuse_lib_forget_multi,
4417 .getattr = fuse_lib_getattr,
4418 .setattr = fuse_lib_setattr,
4419 .access = fuse_lib_access,
4420 .readlink = fuse_lib_readlink,
4421 .mknod = fuse_lib_mknod,
4422 .mkdir = fuse_lib_mkdir,
4423 .unlink = fuse_lib_unlink,
4424 .rmdir = fuse_lib_rmdir,
4425 .symlink = fuse_lib_symlink,
4426 .rename = fuse_lib_rename,
4427 .link = fuse_lib_link,
4428 .create = fuse_lib_create,
4429 .open = fuse_lib_open,
4430 .read = fuse_lib_read,
4431 .write_buf = fuse_lib_write_buf,
4432 .flush = fuse_lib_flush,
4433 .release = fuse_lib_release,
4434 .fsync = fuse_lib_fsync,
4435 .opendir = fuse_lib_opendir,
4436 .readdir = fuse_lib_readdir,
4437 .readdirplus = fuse_lib_readdirplus,
4438 .releasedir = fuse_lib_releasedir,
4439 .fsyncdir = fuse_lib_fsyncdir,
4440 .statfs = fuse_lib_statfs,
4441 .setxattr = fuse_lib_setxattr,
4442 .getxattr = fuse_lib_getxattr,
4443 .listxattr = fuse_lib_listxattr,
4444 .removexattr = fuse_lib_removexattr,
4445 .getlk = fuse_lib_getlk,
4446 .setlk = fuse_lib_setlk,
4447 .flock = fuse_lib_flock,
4448 .bmap = fuse_lib_bmap,
4449 .ioctl = fuse_lib_ioctl,
4450 .poll = fuse_lib_poll,
4451 .fallocate = fuse_lib_fallocate,
4452 .copy_file_range = fuse_lib_copy_file_range,
4455 int fuse_notify_poll(
struct fuse_pollhandle *ph)
4465 static int fuse_session_loop_remember(
struct fuse *f)
4467 struct fuse_session *se = f->se;
4469 struct timespec now;
4471 struct pollfd fds = {
4480 next_clean = now.tv_sec;
4485 if (now.tv_sec < next_clean)
4486 timeout = next_clean - now.tv_sec;
4490 res = poll(&fds, 1, timeout * 1000);
4492 if (errno == -EINTR)
4496 }
else if (res > 0) {
4497 res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4504 fuse_session_process_buf_int(se, &fbuf, NULL);
4508 next_clean = now.tv_sec + timeout;
4514 return res < 0 ? -1 : 0;
4523 return fuse_session_loop_remember(f);
4528 FUSE_SYMVER(
".symver fuse_loop_mt_32,fuse_loop_mt@@FUSE_3.2");
4544 FUSE_SYMVER(
".symver fuse_loop_mt_31,fuse_loop_mt@FUSE_3.0");
4550 return fuse_loop_mt_32(f, &config);
4560 struct fuse_context_i *c = fuse_get_context_internal();
4570 struct fuse_context_i *c = fuse_get_context_internal();
4579 struct fuse_context_i *c = fuse_get_context_internal();
4589 int err = lookup_path_in_cache(f, path, &ino);
4597 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v } 4599 static const struct fuse_opt fuse_lib_opts[] = {
4602 FUSE_LIB_OPT(
"debug", debug, 1),
4603 FUSE_LIB_OPT(
"-d", debug, 1),
4604 FUSE_LIB_OPT(
"kernel_cache", kernel_cache, 1),
4605 FUSE_LIB_OPT(
"auto_cache", auto_cache, 1),
4606 FUSE_LIB_OPT(
"noauto_cache", auto_cache, 0),
4607 FUSE_LIB_OPT(
"umask=", set_mode, 1),
4608 FUSE_LIB_OPT(
"umask=%o", umask, 0),
4609 FUSE_LIB_OPT(
"uid=", set_uid, 1),
4610 FUSE_LIB_OPT(
"uid=%d", uid, 0),
4611 FUSE_LIB_OPT(
"gid=", set_gid, 1),
4612 FUSE_LIB_OPT(
"gid=%d", gid, 0),
4613 FUSE_LIB_OPT(
"entry_timeout=%lf", entry_timeout, 0),
4614 FUSE_LIB_OPT(
"attr_timeout=%lf", attr_timeout, 0),
4615 FUSE_LIB_OPT(
"ac_attr_timeout=%lf", ac_attr_timeout, 0),
4616 FUSE_LIB_OPT(
"ac_attr_timeout=", ac_attr_timeout_set, 1),
4617 FUSE_LIB_OPT(
"negative_timeout=%lf", negative_timeout, 0),
4618 FUSE_LIB_OPT(
"noforget", remember, -1),
4619 FUSE_LIB_OPT(
"remember=%u", remember, 0),
4620 FUSE_LIB_OPT(
"modules=%s", modules, 0),
4624 static int fuse_lib_opt_proc(
void *data,
const char *arg,
int key,
4627 (void) arg; (void) outargs; (void) data; (void) key;
4634 static const struct fuse_opt fuse_help_opts[] = {
4635 FUSE_LIB_OPT(
"modules=%s", modules, 1),
4640 static void print_module_help(
const char *name,
4647 printf(
"\nOptions for %s module:\n", name);
4657 " -o kernel_cache cache files in kernel\n" 4658 " -o [no]auto_cache enable caching based on modification times (off)\n" 4659 " -o umask=M set file permissions (octal)\n" 4660 " -o uid=N set file owner\n" 4661 " -o gid=N set file group\n" 4662 " -o entry_timeout=T cache timeout for names (1.0s)\n" 4663 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n" 4664 " -o attr_timeout=T cache timeout for attributes (1.0s)\n" 4665 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n" 4666 " -o noforget never forget cached inodes\n" 4667 " -o remember=T remember cached inodes for T seconds (0s)\n" 4668 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4675 print_module_help(
"subdir", &fuse_module_subdir_factory);
4677 print_module_help(
"iconv", &fuse_module_iconv_factory);
4684 fuse_lib_opt_proc) == -1
4693 for (module = conf.modules; module; module = next) {
4695 for (p = module; *p && *p !=
':'; p++);
4696 next = *p ? p + 1 : NULL;
4699 m = fuse_get_module(module);
4701 print_module_help(module, &m->factory);
4707 static int fuse_init_intr_signal(
int signum,
int *installed)
4709 struct sigaction old_sa;
4711 if (sigaction(signum, NULL, &old_sa) == -1) {
4712 perror(
"fuse: cannot get old signal handler");
4716 if (old_sa.sa_handler == SIG_DFL) {
4717 struct sigaction sa;
4719 memset(&sa, 0,
sizeof(
struct sigaction));
4720 sa.sa_handler = fuse_intr_sighandler;
4721 sigemptyset(&sa.sa_mask);
4723 if (sigaction(signum, &sa, NULL) == -1) {
4724 perror(
"fuse: cannot set interrupt signal handler");
4732 static void fuse_restore_intr_signal(
int signum)
4734 struct sigaction sa;
4736 memset(&sa, 0,
sizeof(
struct sigaction));
4737 sa.sa_handler = SIG_DFL;
4738 sigaction(signum, &sa, NULL);
4742 static int fuse_push_module(
struct fuse *f,
const char *module,
4745 struct fuse_fs *fs[2] = { f->fs, NULL };
4746 struct fuse_fs *newfs;
4752 newfs = m->factory(args, fs);
4768 fprintf(stderr,
"fuse: warning: library too old, some operations may not not work\n");
4772 fs = (
struct fuse_fs *) calloc(1,
sizeof(
struct fuse_fs));
4774 fprintf(stderr,
"fuse: failed to allocate fuse_fs object\n");
4778 fs->user_data = user_data;
4780 memcpy(&fs->op, op, op_size);
4784 static int node_table_init(
struct node_table *t)
4786 t->size = NODE_TABLE_MIN_SIZE;
4787 t->array = (
struct node **) calloc(1,
sizeof(
struct node *) * t->size);
4788 if (t->array == NULL) {
4789 fprintf(stderr,
"fuse: memory allocation failed\n");
4798 static void *fuse_prune_nodes(
void *fuse)
4800 struct fuse *f = fuse;
4813 return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4820 if (lru_enabled(f)) {
4821 pthread_mutex_lock(&f->lock);
4822 pthread_cancel(f->prune_thread);
4823 pthread_mutex_unlock(&f->lock);
4824 pthread_join(f->prune_thread, NULL);
4829 FUSE_SYMVER(
".symver fuse_new_31,fuse_new@@FUSE_3.1");
4830 struct fuse *fuse_new_31(
struct fuse_args *args,
4832 size_t op_size,
void *user_data)
4839 f = (
struct fuse *) calloc(1,
sizeof(
struct fuse));
4841 fprintf(stderr,
"fuse: failed to allocate fuse object\n");
4845 f->conf.entry_timeout = 1.0;
4846 f->conf.attr_timeout = 1.0;
4847 f->conf.negative_timeout = 0.0;
4848 f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4852 fuse_lib_opt_proc) == -1)
4855 pthread_mutex_lock(&fuse_context_lock);
4856 static int builtin_modules_registered = 0;
4858 if (builtin_modules_registered == 0) {
4860 fuse_register_module(
"subdir", fuse_module_subdir_factory, NULL);
4862 fuse_register_module(
"iconv", fuse_module_iconv_factory, NULL);
4864 builtin_modules_registered= 1;
4866 pthread_mutex_unlock(&fuse_context_lock);
4868 if (fuse_create_context_key() == -1)
4873 goto out_delete_context_key;
4883 f->pagesize = getpagesize();
4884 init_list_head(&f->partial_slabs);
4885 init_list_head(&f->full_slabs);
4886 init_list_head(&f->lru_table);
4888 if (f->conf.modules) {
4892 for (module = f->conf.modules; module; module = next) {
4894 for (p = module; *p && *p !=
':'; p++);
4895 next = *p ? p + 1 : NULL;
4898 fuse_push_module(f, module, args) == -1)
4903 if (!f->conf.ac_attr_timeout_set)
4904 f->conf.ac_attr_timeout = f->conf.attr_timeout;
4906 #if defined(__FreeBSD__) || defined(__NetBSD__) 4911 f->conf.readdir_ino = 1;
4918 if (f->conf.debug) {
4919 fprintf(stderr,
"nullpath_ok: %i\n", f->conf.nullpath_ok);
4923 f->fs->debug = f->conf.debug;
4926 if (node_table_init(&f->name_table) == -1)
4927 goto out_free_session;
4929 if (node_table_init(&f->id_table) == -1)
4930 goto out_free_name_table;
4932 fuse_mutex_init(&f->lock);
4934 root = alloc_node(f);
4936 fprintf(stderr,
"fuse: memory allocation failed\n");
4937 goto out_free_id_table;
4939 if (lru_enabled(f)) {
4940 struct node_lru *lnode = node_lru(root);
4941 init_list_head(&lnode->lru);
4944 strcpy(root->inline_name,
"/");
4945 root->name = root->inline_name;
4948 fuse_init_intr_signal(f->conf.intr_signal,
4949 &f->intr_installed) == -1)
4952 root->parent = NULL;
4962 free(f->id_table.array);
4963 out_free_name_table:
4964 free(f->name_table.array);
4969 fuse_put_module(f->fs->m);
4971 free(f->conf.modules);
4972 out_delete_context_key:
4973 fuse_delete_context_key();
4982 size_t op_size,
void *private_data);
4983 FUSE_SYMVER(
".symver fuse_new_30,fuse_new@FUSE_3.0");
4984 struct fuse *fuse_new_30(
struct fuse_args *args,
4986 size_t op_size,
void *user_data)
4990 memset(&conf, 0,
sizeof(conf));
4993 FUSE_LIB_OPT(
"-h", show_help, 1),
4994 FUSE_LIB_OPT(
"--help", show_help, 1),
4999 fuse_lib_opt_proc) == -1)
5006 return fuse_new_31(args, op, op_size, user_data);
5013 if (f->conf.intr && f->intr_installed)
5014 fuse_restore_intr_signal(f->conf.intr_signal);
5017 fuse_create_context(f);
5019 for (i = 0; i < f->id_table.size; i++) {
5022 for (node = f->id_table.array[i]; node != NULL;
5023 node = node->id_next) {
5024 if (node->is_hidden) {
5026 if (try_get_path(f, node->nodeid, NULL, &path, NULL,
false) == 0) {
5027 fuse_fs_unlink(f->fs, path);
5034 for (i = 0; i < f->id_table.size; i++) {
5038 for (node = f->id_table.array[i]; node != NULL; node = next) {
5039 next = node->id_next;
5044 assert(list_empty(&f->partial_slabs));
5045 assert(list_empty(&f->full_slabs));
5047 while (fuse_modules) {
5048 fuse_put_module(fuse_modules);
5050 free(f->id_table.array);
5051 free(f->name_table.array);
5052 pthread_mutex_destroy(&f->lock);
5054 free(f->conf.modules);
5056 fuse_delete_context_key();
5070 return FUSE_VERSION;
5075 return PACKAGE_VERSION;
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
#define FUSE_OPT_KEY_KEEP
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
#define FUSE_CAP_EXPORT_SUPPORT
void fuse_session_unmount(struct fuse_session *se)
int fuse_getgroups(int size, gid_t list[])
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
void fuse_stop_cleanup_thread(struct fuse *fuse)
int fuse_session_loop(struct fuse_session *se)
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
unsigned int max_idle_threads
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
void fuse_unmount(struct fuse *f)
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
int fuse_loop(struct fuse *f)
int fuse_req_interrupted(fuse_req_t req)
int fuse_reply_poll(fuse_req_t req, unsigned revents)
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
const char * fuse_pkgversion(void)
int fuse_reply_err(fuse_req_t req, int err)
void fuse_session_reset(struct fuse_session *se)
struct fuse_req * fuse_req_t
int fuse_clean_cache(struct fuse *fuse)
void * fuse_req_userdata(fuse_req_t req)
#define FUSE_ARGS_INIT(argc, argv)
struct fuse_session * fuse_get_session(struct fuse *f)
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
void fuse_reply_none(fuse_req_t req)
#define FUSE_CAP_FLOCK_LOCKS
#define FUSE_CAP_POSIX_LOCKS
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
void fuse_session_destroy(struct fuse_session *se)
void fuse_session_exit(struct fuse_session *se)
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_readlink(fuse_req_t req, const char *link)
int fuse_start_cleanup_thread(struct fuse *fuse)
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
enum fuse_buf_flags flags
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
void fuse_lowlevel_help(void)
int fuse_interrupted(void)
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
void fuse_destroy(struct fuse *f)
int fuse_mount(struct fuse *f, const char *mountpoint)
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
int fuse_invalidate_path(struct fuse *f, const char *path)
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
int fuse_session_exited(struct fuse_session *se)
int fuse_reply_xattr(fuse_req_t req, size_t count)
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
int fuse_reply_write(fuse_req_t req, size_t count)
#define FUSE_CAP_SPLICE_READ
void(* init)(void *userdata, struct fuse_conn_info *conn)
void fuse_exit(struct fuse *f)
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
struct fuse_context * fuse_get_context(void)
void fuse_opt_free_args(struct fuse_args *args)
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
void fuse_lib_help(struct fuse_args *args)
#define FUSE_OPT_KEY(templ, key)