15 #include "fuse_lowlevel.h" 17 #include "fuse_misc.h" 18 #include "fuse_common_compat.h" 19 #include "fuse_compat.h" 20 #include "fuse_kernel.h" 36 #include <sys/param.h> 42 #define FUSE_NODE_SLAB 1 48 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1 50 #define FUSE_UNKNOWN_INO 0xffffffff 51 #define OFFSET_MAX 0x7fffffffffffffffLL 53 #define NODE_TABLE_MIN_SIZE 8192 62 double ac_attr_timeout;
95 struct lock_queue_element {
96 struct lock_queue_element *next;
101 struct node **wnode1;
105 struct node **wnode2;
107 bool first_locked : 1;
108 bool second_locked : 1;
119 #define container_of(ptr, type, member) ({ \ 120 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 121 (type *)( (char *)__mptr - offsetof(type,member) );}) 123 #define list_entry(ptr, type, member) \ 124 container_of(ptr, type, member) 127 struct list_head *next;
128 struct list_head *prev;
132 struct list_head list;
133 struct list_head freelist;
138 struct fuse_session *se;
139 struct node_table name_table;
140 struct node_table id_table;
141 struct list_head lru_table;
143 unsigned int generation;
144 unsigned int hidectr;
145 pthread_mutex_t lock;
151 struct lock_queue_element *lockq;
153 struct list_head partial_slabs;
154 struct list_head full_slabs;
155 pthread_t prune_thread;
168 struct node *name_next;
169 struct node *id_next;
171 unsigned int generation;
177 struct timespec stat_updated;
178 struct timespec mtime;
181 unsigned int is_hidden : 1;
182 unsigned int cache_valid : 1;
184 char inline_name[32];
187 #define TREELOCK_WRITE -1 188 #define TREELOCK_WAIT_OFFSET INT_MIN 192 struct list_head lru;
193 struct timespec forget_time;
197 pthread_mutex_t lock;
212 struct fuse_dirhandle {
217 struct fuse_context_i {
222 static pthread_key_t fuse_context_key;
223 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
224 static int fuse_context_ref;
225 static struct fusemod_so *fuse_current_so;
228 static int fuse_load_so_name(
const char *soname)
230 struct fusemod_so *so;
232 so = calloc(1,
sizeof(
struct fusemod_so));
234 fprintf(stderr,
"fuse: memory allocation failed\n");
238 fuse_current_so = so;
239 so->handle = dlopen(soname, RTLD_NOW);
240 fuse_current_so = NULL;
242 fprintf(stderr,
"fuse: %s\n", dlerror());
246 fprintf(stderr,
"fuse: %s did not register any modules\n",
259 static int fuse_load_so_module(
const char *module)
262 char *soname = malloc(strlen(module) + 64);
264 fprintf(stderr,
"fuse: memory allocation failed\n");
267 sprintf(soname,
"libfusemod_%s.so", module);
268 res = fuse_load_so_name(soname);
273 static struct fuse_module *fuse_find_module(
const char *module)
276 for (m = fuse_modules; m; m = m->next) {
277 if (strcmp(module, m->name) == 0) {
285 static struct fuse_module *fuse_get_module(
const char *module)
289 pthread_mutex_lock(&fuse_context_lock);
290 m = fuse_find_module(module);
292 int err = fuse_load_so_module(module);
294 m = fuse_find_module(module);
296 pthread_mutex_unlock(&fuse_context_lock);
302 pthread_mutex_lock(&fuse_context_lock);
305 if (!m->ctr && m->so) {
306 struct fusemod_so *so = m->so;
311 for (mp = &fuse_modules; *mp;) {
321 pthread_mutex_unlock(&fuse_context_lock);
324 static void init_list_head(
struct list_head *list)
330 static int list_empty(
const struct list_head *head)
332 return head->next == head;
335 static void list_add(
struct list_head *
new,
struct list_head *prev,
336 struct list_head *next)
344 static inline void list_add_head(
struct list_head *
new,
struct list_head *head)
346 list_add(
new, head, head->next);
349 static inline void list_add_tail(
struct list_head *
new,
struct list_head *head)
351 list_add(
new, head->prev, head);
354 static inline void list_del(
struct list_head *entry)
356 struct list_head *prev = entry->prev;
357 struct list_head *next = entry->next;
363 static inline int lru_enabled(
struct fuse *f)
365 return f->conf.remember > 0;
368 static struct node_lru *node_lru(
struct node *node)
370 return (
struct node_lru *) node;
373 static size_t get_node_size(
struct fuse *f)
376 return sizeof(
struct node_lru);
378 return sizeof(
struct node);
381 #ifdef FUSE_NODE_SLAB 382 static struct node_slab *list_to_slab(
struct list_head *head)
384 return (
struct node_slab *) head;
387 static struct node_slab *node_to_slab(
struct fuse *f,
struct node *node)
389 return (
struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
392 static int alloc_slab(
struct fuse *f)
395 struct node_slab *slab;
399 size_t node_size = get_node_size(f);
401 mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
402 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
404 if (mem == MAP_FAILED)
408 init_list_head(&slab->freelist);
410 num = (f->pagesize -
sizeof(
struct node_slab)) / node_size;
412 start = (
char *) mem + f->pagesize - num * node_size;
413 for (i = 0; i < num; i++) {
416 n = (
struct list_head *) (start + i * node_size);
417 list_add_tail(n, &slab->freelist);
419 list_add_tail(&slab->list, &f->partial_slabs);
424 static struct node *alloc_node(
struct fuse *f)
426 struct node_slab *slab;
427 struct list_head *node;
429 if (list_empty(&f->partial_slabs)) {
430 int res = alloc_slab(f);
434 slab = list_to_slab(f->partial_slabs.next);
436 node = slab->freelist.next;
438 if (list_empty(&slab->freelist)) {
439 list_del(&slab->list);
440 list_add_tail(&slab->list, &f->full_slabs);
442 memset(node, 0,
sizeof(
struct node));
444 return (
struct node *) node;
447 static void free_slab(
struct fuse *f,
struct node_slab *slab)
451 list_del(&slab->list);
452 res = munmap(slab, f->pagesize);
454 fprintf(stderr,
"fuse warning: munmap(%p) failed\n", slab);
457 static void free_node_mem(
struct fuse *f,
struct node *node)
459 struct node_slab *slab = node_to_slab(f, node);
460 struct list_head *n = (
struct list_head *) node;
464 if (list_empty(&slab->freelist)) {
465 list_del(&slab->list);
466 list_add_tail(&slab->list, &f->partial_slabs);
468 list_add_head(n, &slab->freelist);
474 static struct node *alloc_node(
struct fuse *f)
476 return (
struct node *) calloc(1, get_node_size(f));
479 static void free_node_mem(
struct fuse *f,
struct node *node)
486 static size_t id_hash(
struct fuse *f,
fuse_ino_t ino)
488 uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
489 uint64_t oldhash = hash % (f->id_table.size / 2);
491 if (oldhash >= f->id_table.split)
497 static struct node *get_node_nocheck(
struct fuse *f,
fuse_ino_t nodeid)
499 size_t hash = id_hash(f, nodeid);
502 for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
503 if (node->nodeid == nodeid)
509 static struct node *get_node(
struct fuse *f,
fuse_ino_t nodeid)
511 struct node *node = get_node_nocheck(f, nodeid);
513 fprintf(stderr,
"fuse internal error: node %llu not found\n",
514 (
unsigned long long) nodeid);
520 static void curr_time(
struct timespec *now);
521 static double diff_timespec(
const struct timespec *t1,
522 const struct timespec *t2);
524 static void remove_node_lru(
struct node *node)
526 struct node_lru *lnode = node_lru(node);
527 list_del(&lnode->lru);
528 init_list_head(&lnode->lru);
531 static void set_forget_time(
struct fuse *f,
struct node *node)
533 struct node_lru *lnode = node_lru(node);
535 list_del(&lnode->lru);
536 list_add_tail(&lnode->lru, &f->lru_table);
537 curr_time(&lnode->forget_time);
540 static void free_node(
struct fuse *f,
struct node *node)
542 if (node->name != node->inline_name)
544 free_node_mem(f, node);
547 static void node_table_reduce(
struct node_table *t)
549 size_t newsize = t->size / 2;
552 if (newsize < NODE_TABLE_MIN_SIZE)
555 newarray = realloc(t->array,
sizeof(
struct node *) * newsize);
556 if (newarray != NULL)
560 t->split = t->size / 2;
563 static void remerge_id(
struct fuse *f)
565 struct node_table *t = &f->id_table;
569 node_table_reduce(t);
571 for (iter = 8; t->split > 0 && iter; iter--) {
575 upper = &t->array[t->split + t->size / 2];
579 for (nodep = &t->array[t->split]; *nodep;
580 nodep = &(*nodep)->id_next);
589 static void unhash_id(
struct fuse *f,
struct node *node)
591 struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
593 for (; *nodep != NULL; nodep = &(*nodep)->id_next)
594 if (*nodep == node) {
595 *nodep = node->id_next;
598 if(f->id_table.use < f->id_table.size / 4)
604 static int node_table_resize(
struct node_table *t)
606 size_t newsize = t->size * 2;
609 newarray = realloc(t->array,
sizeof(
struct node *) * newsize);
610 if (newarray == NULL)
614 memset(t->array + t->size, 0, t->size *
sizeof(
struct node *));
621 static void rehash_id(
struct fuse *f)
623 struct node_table *t = &f->id_table;
628 if (t->split == t->size / 2)
633 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
634 struct node *node = *nodep;
635 size_t newhash = id_hash(f, node->nodeid);
637 if (newhash != hash) {
639 *nodep = node->id_next;
640 node->id_next = t->array[newhash];
641 t->array[newhash] = node;
643 next = &node->id_next;
646 if (t->split == t->size / 2)
647 node_table_resize(t);
650 static void hash_id(
struct fuse *f,
struct node *node)
652 size_t hash = id_hash(f, node->nodeid);
653 node->id_next = f->id_table.array[hash];
654 f->id_table.array[hash] = node;
657 if (f->id_table.use >= f->id_table.size / 2)
661 static size_t name_hash(
struct fuse *f,
fuse_ino_t parent,
664 uint64_t hash = parent;
667 for (; *name; name++)
668 hash = hash * 31 + (
unsigned char) *name;
670 hash %= f->name_table.size;
671 oldhash = hash % (f->name_table.size / 2);
672 if (oldhash >= f->name_table.split)
678 static void unref_node(
struct fuse *f,
struct node *node);
680 static void remerge_name(
struct fuse *f)
682 struct node_table *t = &f->name_table;
686 node_table_reduce(t);
688 for (iter = 8; t->split > 0 && iter; iter--) {
692 upper = &t->array[t->split + t->size / 2];
696 for (nodep = &t->array[t->split]; *nodep;
697 nodep = &(*nodep)->name_next);
706 static void unhash_name(
struct fuse *f,
struct node *node)
709 size_t hash = name_hash(f, node->parent->nodeid, node->name);
710 struct node **nodep = &f->name_table.array[hash];
712 for (; *nodep != NULL; nodep = &(*nodep)->name_next)
713 if (*nodep == node) {
714 *nodep = node->name_next;
715 node->name_next = NULL;
716 unref_node(f, node->parent);
717 if (node->name != node->inline_name)
723 if (f->name_table.use < f->name_table.size / 4)
728 "fuse internal error: unable to unhash node: %llu\n",
729 (
unsigned long long) node->nodeid);
734 static void rehash_name(
struct fuse *f)
736 struct node_table *t = &f->name_table;
741 if (t->split == t->size / 2)
746 for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
747 struct node *node = *nodep;
748 size_t newhash = name_hash(f, node->parent->nodeid, node->name);
750 if (newhash != hash) {
752 *nodep = node->name_next;
753 node->name_next = t->array[newhash];
754 t->array[newhash] = node;
756 next = &node->name_next;
759 if (t->split == t->size / 2)
760 node_table_resize(t);
763 static int hash_name(
struct fuse *f,
struct node *node,
fuse_ino_t parentid,
766 size_t hash = name_hash(f, parentid, name);
767 struct node *parent = get_node(f, parentid);
768 if (strlen(name) <
sizeof(node->inline_name)) {
769 strcpy(node->inline_name, name);
770 node->name = node->inline_name;
772 node->name = strdup(name);
773 if (node->name == NULL)
778 node->parent = parent;
779 node->name_next = f->name_table.array[hash];
780 f->name_table.array[hash] = node;
783 if (f->name_table.use >= f->name_table.size / 2)
789 static void delete_node(
struct fuse *f,
struct node *node)
792 fprintf(stderr,
"DELETE: %llu\n",
793 (
unsigned long long) node->nodeid);
795 assert(node->treelock == 0);
796 unhash_name(f, node);
798 remove_node_lru(node);
803 static void unref_node(
struct fuse *f,
struct node *node)
805 assert(node->refctr > 0);
808 delete_node(f, node);
814 f->ctr = (f->ctr + 1) & 0xffffffff;
817 }
while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
818 get_node_nocheck(f, f->ctr) != NULL);
822 static struct node *lookup_node(
struct fuse *f,
fuse_ino_t parent,
825 size_t hash = name_hash(f, parent, name);
828 for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
829 if (node->parent->nodeid == parent &&
830 strcmp(node->name, name) == 0)
836 static void inc_nlookup(
struct node *node)
843 static struct node *find_node(
struct fuse *f,
fuse_ino_t parent,
848 pthread_mutex_lock(&f->lock);
850 node = get_node(f, parent);
852 node = lookup_node(f, parent, name);
854 node = alloc_node(f);
858 node->nodeid = next_id(f);
859 node->generation = f->generation;
860 if (f->conf.remember)
863 if (hash_name(f, node, parent, name) == -1) {
869 if (lru_enabled(f)) {
870 struct node_lru *lnode = node_lru(node);
871 init_list_head(&lnode->lru);
873 }
else if (lru_enabled(f) && node->nlookup == 1) {
874 remove_node_lru(node);
878 pthread_mutex_unlock(&f->lock);
882 static char *add_name(
char **buf,
unsigned *bufsize,
char *s,
const char *name)
884 size_t len = strlen(name);
886 if (s - len <= *buf) {
887 unsigned pathlen = *bufsize - (s - *buf);
888 unsigned newbufsize = *bufsize;
891 while (newbufsize < pathlen + len + 1) {
892 if (newbufsize >= 0x80000000)
893 newbufsize = 0xffffffff;
898 newbuf = realloc(*buf, newbufsize);
903 s = newbuf + newbufsize - pathlen;
904 memmove(s, newbuf + *bufsize - pathlen, pathlen);
905 *bufsize = newbufsize;
908 strncpy(s, name, len);
915 static void unlock_path(
struct fuse *f,
fuse_ino_t nodeid,
struct node *wnode,
921 assert(wnode->treelock == TREELOCK_WRITE);
925 for (node = get_node(f, nodeid);
926 node != end && node->nodeid !=
FUSE_ROOT_ID; node = node->parent) {
927 assert(node->treelock != 0);
928 assert(node->treelock != TREELOCK_WAIT_OFFSET);
929 assert(node->treelock != TREELOCK_WRITE);
931 if (node->treelock == TREELOCK_WAIT_OFFSET)
936 static int try_get_path(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
937 char **path,
struct node **wnodep,
bool need_lock)
939 unsigned bufsize = 256;
943 struct node *wnode = NULL;
949 buf = malloc(bufsize);
953 s = buf + bufsize - 1;
957 s = add_name(&buf, &bufsize, s, name);
965 wnode = lookup_node(f, nodeid, name);
967 if (wnode->treelock != 0) {
968 if (wnode->treelock > 0)
969 wnode->treelock += TREELOCK_WAIT_OFFSET;
973 wnode->treelock = TREELOCK_WRITE;
977 for (node = get_node(f, nodeid); node->nodeid !=
FUSE_ROOT_ID;
978 node = node->parent) {
980 if (node->name == NULL || node->parent == NULL)
984 s = add_name(&buf, &bufsize, s, node->name);
990 if (node->treelock < 0)
998 memmove(buf, s, bufsize - (s - buf));
1010 unlock_path(f, nodeid, wnode, node);
1018 static void queue_element_unlock(
struct fuse *f,
struct lock_queue_element *qe)
1022 if (qe->first_locked) {
1023 wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1024 unlock_path(f, qe->nodeid1, wnode, NULL);
1025 qe->first_locked =
false;
1027 if (qe->second_locked) {
1028 wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1029 unlock_path(f, qe->nodeid2, wnode, NULL);
1030 qe->second_locked =
false;
1034 static void queue_element_wakeup(
struct fuse *f,
struct lock_queue_element *qe)
1037 bool first = (qe == f->lockq);
1041 if (get_node(f, qe->nodeid1)->treelock == 0)
1042 pthread_cond_signal(&qe->cond);
1047 if (!qe->first_locked) {
1048 err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1051 qe->first_locked =
true;
1052 else if (err != -EAGAIN)
1055 if (!qe->second_locked && qe->path2) {
1056 err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1059 qe->second_locked =
true;
1060 else if (err != -EAGAIN)
1064 if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1077 queue_element_unlock(f, qe);
1083 queue_element_unlock(f, qe);
1087 pthread_cond_signal(&qe->cond);
1090 static void wake_up_queued(
struct fuse *f)
1092 struct lock_queue_element *qe;
1094 for (qe = f->lockq; qe != NULL; qe = qe->next)
1095 queue_element_wakeup(f, qe);
1098 static void debug_path(
struct fuse *f,
const char *msg,
fuse_ino_t nodeid,
1099 const char *name,
bool wr)
1101 if (f->conf.debug) {
1102 struct node *wnode = NULL;
1105 wnode = lookup_node(f, nodeid, name);
1108 fprintf(stderr,
"%s %li (w)\n", msg, wnode->nodeid);
1110 fprintf(stderr,
"%s %li\n", msg, nodeid);
1114 static void queue_path(
struct fuse *f,
struct lock_queue_element *qe)
1116 struct lock_queue_element **qp;
1119 qe->first_locked =
false;
1120 qe->second_locked =
false;
1121 pthread_cond_init(&qe->cond, NULL);
1123 for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1127 static void dequeue_path(
struct fuse *f,
struct lock_queue_element *qe)
1129 struct lock_queue_element **qp;
1131 pthread_cond_destroy(&qe->cond);
1132 for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1136 static int wait_path(
struct fuse *f,
struct lock_queue_element *qe)
1141 pthread_cond_wait(&qe->cond, &f->lock);
1142 }
while (!qe->done);
1144 dequeue_path(f, qe);
1149 static int get_path_common(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1150 char **path,
struct node **wnode)
1154 pthread_mutex_lock(&f->lock);
1155 err = try_get_path(f, nodeid, name, path, wnode,
true);
1156 if (err == -EAGAIN) {
1157 struct lock_queue_element qe = {
1163 debug_path(f,
"QUEUE PATH", nodeid, name, !!wnode);
1164 err = wait_path(f, &qe);
1165 debug_path(f,
"DEQUEUE PATH", nodeid, name, !!wnode);
1167 pthread_mutex_unlock(&f->lock);
1172 static int get_path(
struct fuse *f,
fuse_ino_t nodeid,
char **path)
1174 return get_path_common(f, nodeid, NULL, path, NULL);
1177 static int get_path_nullok(
struct fuse *f,
fuse_ino_t nodeid,
char **path)
1181 if (f->conf.nopath) {
1184 err = get_path_common(f, nodeid, NULL, path, NULL);
1185 if (err == -ENOENT && f->nullpath_ok)
1192 static int get_path_name(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1195 return get_path_common(f, nodeid, name, path, NULL);
1198 static int get_path_wrlock(
struct fuse *f,
fuse_ino_t nodeid,
const char *name,
1199 char **path,
struct node **wnode)
1201 return get_path_common(f, nodeid, name, path, wnode);
1204 static int try_get_path2(
struct fuse *f,
fuse_ino_t nodeid1,
const char *name1,
1206 char **path1,
char **path2,
1207 struct node **wnode1,
struct node **wnode2)
1212 err = try_get_path(f, nodeid1, name1, path1, wnode1,
true);
1214 err = try_get_path(f, nodeid2, name2, path2, wnode2,
true);
1216 struct node *wn1 = wnode1 ? *wnode1 : NULL;
1218 unlock_path(f, nodeid1, wn1, NULL);
1225 static int get_path2(
struct fuse *f,
fuse_ino_t nodeid1,
const char *name1,
1227 char **path1,
char **path2,
1228 struct node **wnode1,
struct node **wnode2)
1232 pthread_mutex_lock(&f->lock);
1233 err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1234 path1, path2, wnode1, wnode2);
1235 if (err == -EAGAIN) {
1236 struct lock_queue_element qe = {
1247 debug_path(f,
"QUEUE PATH1", nodeid1, name1, !!wnode1);
1248 debug_path(f,
" PATH2", nodeid2, name2, !!wnode2);
1249 err = wait_path(f, &qe);
1250 debug_path(f,
"DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1251 debug_path(f,
" PATH2", nodeid2, name2, !!wnode2);
1253 pthread_mutex_unlock(&f->lock);
1258 static void free_path_wrlock(
struct fuse *f,
fuse_ino_t nodeid,
1259 struct node *wnode,
char *path)
1261 pthread_mutex_lock(&f->lock);
1262 unlock_path(f, nodeid, wnode, NULL);
1265 pthread_mutex_unlock(&f->lock);
1269 static void free_path(
struct fuse *f,
fuse_ino_t nodeid,
char *path)
1272 free_path_wrlock(f, nodeid, NULL, path);
1276 struct node *wnode1,
struct node *wnode2,
1277 char *path1,
char *path2)
1279 pthread_mutex_lock(&f->lock);
1280 unlock_path(f, nodeid1, wnode1, NULL);
1281 unlock_path(f, nodeid2, wnode2, NULL);
1283 pthread_mutex_unlock(&f->lock);
1288 static void forget_node(
struct fuse *f,
fuse_ino_t nodeid, uint64_t nlookup)
1293 pthread_mutex_lock(&f->lock);
1294 node = get_node(f, nodeid);
1300 while (node->nlookup == nlookup && node->treelock) {
1301 struct lock_queue_element qe = {
1305 debug_path(f,
"QUEUE PATH (forget)", nodeid, NULL,
false);
1309 pthread_cond_wait(&qe.cond, &f->lock);
1310 }
while (node->nlookup == nlookup && node->treelock);
1312 dequeue_path(f, &qe);
1313 debug_path(f,
"DEQUEUE_PATH (forget)", nodeid, NULL,
false);
1316 assert(node->nlookup >= nlookup);
1317 node->nlookup -= nlookup;
1318 if (!node->nlookup) {
1319 unref_node(f, node);
1320 }
else if (lru_enabled(f) && node->nlookup == 1) {
1321 set_forget_time(f, node);
1323 pthread_mutex_unlock(&f->lock);
1326 static void unlink_node(
struct fuse *f,
struct node *node)
1328 if (f->conf.remember) {
1329 assert(node->nlookup > 1);
1332 unhash_name(f, node);
1335 static void remove_node(
struct fuse *f,
fuse_ino_t dir,
const char *name)
1339 pthread_mutex_lock(&f->lock);
1340 node = lookup_node(f, dir, name);
1342 unlink_node(f, node);
1343 pthread_mutex_unlock(&f->lock);
1346 static int rename_node(
struct fuse *f,
fuse_ino_t olddir,
const char *oldname,
1347 fuse_ino_t newdir,
const char *newname,
int hide)
1350 struct node *newnode;
1353 pthread_mutex_lock(&f->lock);
1354 node = lookup_node(f, olddir, oldname);
1355 newnode = lookup_node(f, newdir, newname);
1359 if (newnode != NULL) {
1361 fprintf(stderr,
"fuse: hidden file got created during hiding\n");
1365 unlink_node(f, newnode);
1368 unhash_name(f, node);
1369 if (hash_name(f, node, newdir, newname) == -1) {
1375 node->is_hidden = 1;
1378 pthread_mutex_unlock(&f->lock);
1382 static void set_stat(
struct fuse *f,
fuse_ino_t nodeid,
struct stat *stbuf)
1384 if (!f->conf.use_ino)
1385 stbuf->st_ino = nodeid;
1386 if (f->conf.set_mode)
1387 stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1388 (0777 & ~f->conf.umask);
1389 if (f->conf.set_uid)
1390 stbuf->st_uid = f->conf.uid;
1391 if (f->conf.set_gid)
1392 stbuf->st_gid = f->conf.gid;
1400 static void fuse_intr_sighandler(
int sig)
1406 struct fuse_intr_data {
1408 pthread_cond_t cond;
1412 static void fuse_interrupt(
fuse_req_t req,
void *d_)
1414 struct fuse_intr_data *d = d_;
1415 struct fuse *f = req_fuse(req);
1417 if (d->id == pthread_self())
1420 pthread_mutex_lock(&f->lock);
1421 while (!d->finished) {
1423 struct timespec timeout;
1425 pthread_kill(d->id, f->conf.intr_signal);
1426 gettimeofday(&now, NULL);
1427 timeout.tv_sec = now.tv_sec + 1;
1428 timeout.tv_nsec = now.tv_usec * 1000;
1429 pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1431 pthread_mutex_unlock(&f->lock);
1434 static void fuse_do_finish_interrupt(
struct fuse *f,
fuse_req_t req,
1435 struct fuse_intr_data *d)
1437 pthread_mutex_lock(&f->lock);
1439 pthread_cond_broadcast(&d->cond);
1440 pthread_mutex_unlock(&f->lock);
1442 pthread_cond_destroy(&d->cond);
1445 static void fuse_do_prepare_interrupt(
fuse_req_t req,
struct fuse_intr_data *d)
1447 d->id = pthread_self();
1448 pthread_cond_init(&d->cond, NULL);
1453 static inline void fuse_finish_interrupt(
struct fuse *f,
fuse_req_t req,
1454 struct fuse_intr_data *d)
1457 fuse_do_finish_interrupt(f, req, d);
1460 static inline void fuse_prepare_interrupt(
struct fuse *f,
fuse_req_t req,
1461 struct fuse_intr_data *d)
1464 fuse_do_prepare_interrupt(req, d);
1467 #if !defined(__FreeBSD__) && !defined(__NetBSD__) 1469 static int fuse_compat_open(
struct fuse_fs *fs,
const char *path,
1473 if (!fs->compat || fs->compat >= 25)
1474 err = fs->op.open(path, fi);
1475 else if (fs->compat == 22) {
1476 struct fuse_file_info_compat tmp;
1477 memcpy(&tmp, fi,
sizeof(tmp));
1478 err = ((
struct fuse_operations_compat22 *) &fs->op)->open(path,
1480 memcpy(fi, &tmp,
sizeof(tmp));
1483 err = ((
struct fuse_operations_compat2 *) &fs->op)
1484 ->open(path, fi->
flags);
1488 static int fuse_compat_release(
struct fuse_fs *fs,
const char *path,
1491 if (!fs->compat || fs->compat >= 22)
1492 return fs->op.release(path, fi);
1494 return ((
struct fuse_operations_compat2 *) &fs->op)
1495 ->release(path, fi->
flags);
1498 static int fuse_compat_opendir(
struct fuse_fs *fs,
const char *path,
1501 if (!fs->compat || fs->compat >= 25)
1502 return fs->op.opendir(path, fi);
1505 struct fuse_file_info_compat tmp;
1506 memcpy(&tmp, fi,
sizeof(tmp));
1507 err = ((
struct fuse_operations_compat22 *) &fs->op)
1508 ->opendir(path, &tmp);
1509 memcpy(fi, &tmp,
sizeof(tmp));
1515 static void convert_statfs_compat(
struct fuse_statfs_compat1 *compatbuf,
1516 struct statvfs *stbuf)
1518 stbuf->f_bsize = compatbuf->block_size;
1519 stbuf->f_blocks = compatbuf->blocks;
1520 stbuf->f_bfree = compatbuf->blocks_free;
1521 stbuf->f_bavail = compatbuf->blocks_free;
1522 stbuf->f_files = compatbuf->files;
1523 stbuf->f_ffree = compatbuf->files_free;
1524 stbuf->f_namemax = compatbuf->namelen;
1527 static void convert_statfs_old(
struct statfs *oldbuf,
struct statvfs *stbuf)
1529 stbuf->f_bsize = oldbuf->f_bsize;
1530 stbuf->f_blocks = oldbuf->f_blocks;
1531 stbuf->f_bfree = oldbuf->f_bfree;
1532 stbuf->f_bavail = oldbuf->f_bavail;
1533 stbuf->f_files = oldbuf->f_files;
1534 stbuf->f_ffree = oldbuf->f_ffree;
1535 stbuf->f_namemax = oldbuf->f_namelen;
1538 static int fuse_compat_statfs(
struct fuse_fs *fs,
const char *path,
1539 struct statvfs *buf)
1543 if (!fs->compat || fs->compat >= 25) {
1544 err = fs->op.statfs(fs->compat == 25 ?
"/" : path, buf);
1545 }
else if (fs->compat > 11) {
1546 struct statfs oldbuf;
1547 err = ((
struct fuse_operations_compat22 *) &fs->op)
1548 ->statfs(
"/", &oldbuf);
1550 convert_statfs_old(&oldbuf, buf);
1552 struct fuse_statfs_compat1 compatbuf;
1553 memset(&compatbuf, 0,
sizeof(
struct fuse_statfs_compat1));
1554 err = ((
struct fuse_operations_compat1 *) &fs->op)
1555 ->statfs(&compatbuf);
1557 convert_statfs_compat(&compatbuf, buf);
1564 static inline int fuse_compat_open(
struct fuse_fs *fs,
char *path,
1567 return fs->op.open(path, fi);
1570 static inline int fuse_compat_release(
struct fuse_fs *fs,
const char *path,
1573 return fs->op.release(path, fi);
1576 static inline int fuse_compat_opendir(
struct fuse_fs *fs,
const char *path,
1579 return fs->op.opendir(path, fi);
1582 static inline int fuse_compat_statfs(
struct fuse_fs *fs,
const char *path,
1583 struct statvfs *buf)
1585 return fs->op.statfs(fs->compat == 25 ?
"/" : path, buf);
1590 int fuse_fs_getattr(
struct fuse_fs *fs,
const char *path,
struct stat *buf)
1593 if (fs->op.getattr) {
1595 fprintf(stderr,
"getattr %s\n", path);
1597 return fs->op.getattr(path, buf);
1603 int fuse_fs_fgetattr(
struct fuse_fs *fs,
const char *path,
struct stat *buf,
1607 if (fs->op.fgetattr) {
1609 fprintf(stderr,
"fgetattr[%llu] %s\n",
1610 (
unsigned long long) fi->
fh, path);
1612 return fs->op.fgetattr(path, buf, fi);
1613 }
else if (path && fs->op.getattr) {
1615 fprintf(stderr,
"getattr %s\n", path);
1617 return fs->op.getattr(path, buf);
1623 int fuse_fs_rename(
struct fuse_fs *fs,
const char *oldpath,
1624 const char *newpath)
1627 if (fs->op.rename) {
1629 fprintf(stderr,
"rename %s %s\n", oldpath, newpath);
1631 return fs->op.rename(oldpath, newpath);
1637 int fuse_fs_unlink(
struct fuse_fs *fs,
const char *path)
1640 if (fs->op.unlink) {
1642 fprintf(stderr,
"unlink %s\n", path);
1644 return fs->op.unlink(path);
1650 int fuse_fs_rmdir(
struct fuse_fs *fs,
const char *path)
1655 fprintf(stderr,
"rmdir %s\n", path);
1657 return fs->op.rmdir(path);
1663 int fuse_fs_symlink(
struct fuse_fs *fs,
const char *linkname,
const char *path)
1666 if (fs->op.symlink) {
1668 fprintf(stderr,
"symlink %s %s\n", linkname, path);
1670 return fs->op.symlink(linkname, path);
1676 int fuse_fs_link(
struct fuse_fs *fs,
const char *oldpath,
const char *newpath)
1681 fprintf(stderr,
"link %s %s\n", oldpath, newpath);
1683 return fs->op.link(oldpath, newpath);
1689 int fuse_fs_release(
struct fuse_fs *fs,
const char *path,
1693 if (fs->op.release) {
1695 fprintf(stderr,
"release%s[%llu] flags: 0x%x\n",
1696 fi->
flush ?
"+flush" :
"",
1697 (
unsigned long long) fi->
fh, fi->
flags);
1699 return fuse_compat_release(fs, path, fi);
1705 int fuse_fs_opendir(
struct fuse_fs *fs,
const char *path,
1709 if (fs->op.opendir) {
1713 fprintf(stderr,
"opendir flags: 0x%x %s\n", fi->
flags,
1716 err = fuse_compat_opendir(fs, path, fi);
1718 if (fs->debug && !err)
1719 fprintf(stderr,
" opendir[%lli] flags: 0x%x %s\n",
1720 (
unsigned long long) fi->
fh, fi->
flags, path);
1728 int fuse_fs_open(
struct fuse_fs *fs,
const char *path,
1736 fprintf(stderr,
"open flags: 0x%x %s\n", fi->
flags,
1739 err = fuse_compat_open(fs, path, fi);
1741 if (fs->debug && !err)
1742 fprintf(stderr,
" open[%lli] flags: 0x%x %s\n",
1743 (
unsigned long long) fi->
fh, fi->
flags, path);
1751 static void fuse_free_buf(
struct fuse_bufvec *buf)
1756 for (i = 0; i < buf->
count; i++)
1762 int fuse_fs_read_buf(
struct fuse_fs *fs,
const char *path,
1763 struct fuse_bufvec **bufp,
size_t size, off_t off,
1767 if (fs->op.read || fs->op.read_buf) {
1772 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1773 (
unsigned long long) fi->
fh,
1774 size, (
unsigned long long) off, fi->
flags);
1776 if (fs->op.read_buf) {
1777 res = fs->op.read_buf(path, bufp, size, off, fi);
1791 *buf = FUSE_BUFVEC_INIT(size);
1795 res = fs->op.read(path, mem, size, off, fi);
1800 if (fs->debug && res >= 0)
1801 fprintf(stderr,
" read[%llu] %zu bytes from %llu\n",
1802 (
unsigned long long) fi->
fh,
1804 (
unsigned long long) off);
1806 fprintf(stderr,
"fuse: read too many bytes\n");
1817 int fuse_fs_read(
struct fuse_fs *fs,
const char *path,
char *mem,
size_t size,
1823 res = fuse_fs_read_buf(fs, path, &buf, size, off, fi);
1835 int fuse_fs_write_buf(
struct fuse_fs *fs,
const char *path,
1840 if (fs->op.write_buf || fs->op.write) {
1844 assert(buf->
idx == 0 && buf->
off == 0);
1847 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1849 (
unsigned long long) fi->
fh,
1851 (
unsigned long long) off,
1854 if (fs->op.write_buf) {
1855 res = fs->op.write_buf(path, buf, off, fi);
1861 if (buf->
count == 1 &&
1863 flatbuf = &buf->
buf[0];
1876 flatbuf = &tmp.
buf[0];
1879 res = fs->op.write(path, flatbuf->
mem, flatbuf->
size,
1885 if (fs->debug && res >= 0)
1886 fprintf(stderr,
" write%s[%llu] %u bytes to %llu\n",
1888 (
unsigned long long) fi->
fh, res,
1889 (
unsigned long long) off);
1890 if (res > (
int) size)
1891 fprintf(stderr,
"fuse: wrote too many bytes\n");
1899 int fuse_fs_write(
struct fuse_fs *fs,
const char *path,
const char *mem,
1904 bufv.
buf[0].
mem = (
void *) mem;
1906 return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1909 int fuse_fs_fsync(
struct fuse_fs *fs,
const char *path,
int datasync,
1915 fprintf(stderr,
"fsync[%llu] datasync: %i\n",
1916 (
unsigned long long) fi->
fh, datasync);
1918 return fs->op.fsync(path, datasync, fi);
1924 int fuse_fs_fsyncdir(
struct fuse_fs *fs,
const char *path,
int datasync,
1928 if (fs->op.fsyncdir) {
1930 fprintf(stderr,
"fsyncdir[%llu] datasync: %i\n",
1931 (
unsigned long long) fi->
fh, datasync);
1933 return fs->op.fsyncdir(path, datasync, fi);
1939 int fuse_fs_flush(
struct fuse_fs *fs,
const char *path,
1945 fprintf(stderr,
"flush[%llu]\n",
1946 (
unsigned long long) fi->
fh);
1948 return fs->op.flush(path, fi);
1954 int fuse_fs_statfs(
struct fuse_fs *fs,
const char *path,
struct statvfs *buf)
1957 if (fs->op.statfs) {
1959 fprintf(stderr,
"statfs %s\n", path);
1961 return fuse_compat_statfs(fs, path, buf);
1963 buf->f_namemax = 255;
1969 int fuse_fs_releasedir(
struct fuse_fs *fs,
const char *path,
1973 if (fs->op.releasedir) {
1975 fprintf(stderr,
"releasedir[%llu] flags: 0x%x\n",
1976 (
unsigned long long) fi->
fh, fi->
flags);
1978 return fs->op.releasedir(path, fi);
1984 static int fill_dir_old(
struct fuse_dirhandle *dh,
const char *name,
int type,
1990 memset(&stbuf, 0,
sizeof(stbuf));
1991 stbuf.st_mode = type << 12;
1994 res = dh->filler(dh->buf, name, &stbuf, 0);
1995 return res ? -ENOMEM : 0;
1998 int fuse_fs_readdir(
struct fuse_fs *fs,
const char *path,
void *buf,
2003 if (fs->op.readdir) {
2005 fprintf(stderr,
"readdir[%llu] from %llu\n",
2006 (
unsigned long long) fi->
fh,
2007 (
unsigned long long) off);
2009 return fs->op.readdir(path, buf, filler, off, fi);
2010 }
else if (fs->op.getdir) {
2011 struct fuse_dirhandle dh;
2014 fprintf(stderr,
"getdir[%llu]\n",
2015 (
unsigned long long) fi->
fh);
2019 return fs->op.getdir(path, &dh, fill_dir_old);
2025 int fuse_fs_create(
struct fuse_fs *fs,
const char *path, mode_t mode,
2029 if (fs->op.create) {
2034 "create flags: 0x%x %s 0%o umask=0%03o\n",
2035 fi->
flags, path, mode,
2038 err = fs->op.create(path, mode, fi);
2040 if (fs->debug && !err)
2041 fprintf(stderr,
" create[%llu] flags: 0x%x %s\n",
2042 (
unsigned long long) fi->
fh, fi->
flags, path);
2050 int fuse_fs_lock(
struct fuse_fs *fs,
const char *path,
2056 fprintf(stderr,
"lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2057 (
unsigned long long) fi->
fh,
2058 (cmd == F_GETLK ?
"F_GETLK" :
2059 (cmd == F_SETLK ?
"F_SETLK" :
2060 (cmd == F_SETLKW ?
"F_SETLKW" :
"???"))),
2061 (lock->l_type == F_RDLCK ?
"F_RDLCK" :
2062 (lock->l_type == F_WRLCK ?
"F_WRLCK" :
2063 (lock->l_type == F_UNLCK ?
"F_UNLCK" :
2065 (
unsigned long long) lock->l_start,
2066 (
unsigned long long) lock->l_len,
2067 (
unsigned long long) lock->l_pid);
2069 return fs->op.lock(path, fi, cmd, lock);
2075 int fuse_fs_flock(
struct fuse_fs *fs,
const char *path,
2081 int xop = op & ~LOCK_NB;
2083 fprintf(stderr,
"lock[%llu] %s%s\n",
2084 (
unsigned long long) fi->
fh,
2085 xop == LOCK_SH ?
"LOCK_SH" :
2086 (xop == LOCK_EX ?
"LOCK_EX" :
2087 (xop == LOCK_UN ?
"LOCK_UN" :
"???")),
2088 (op & LOCK_NB) ?
"|LOCK_NB" :
"");
2090 return fs->op.flock(path, fi, op);
2096 int fuse_fs_chown(
struct fuse_fs *fs,
const char *path, uid_t uid, gid_t gid)
2101 fprintf(stderr,
"chown %s %lu %lu\n", path,
2102 (
unsigned long) uid, (
unsigned long) gid);
2104 return fs->op.chown(path, uid, gid);
2110 int fuse_fs_truncate(
struct fuse_fs *fs,
const char *path, off_t size)
2113 if (fs->op.truncate) {
2115 fprintf(stderr,
"truncate %s %llu\n", path,
2116 (
unsigned long long) size);
2118 return fs->op.truncate(path, size);
2124 int fuse_fs_ftruncate(
struct fuse_fs *fs,
const char *path, off_t size,
2128 if (fs->op.ftruncate) {
2130 fprintf(stderr,
"ftruncate[%llu] %llu\n",
2131 (
unsigned long long) fi->
fh,
2132 (
unsigned long long) size);
2134 return fs->op.ftruncate(path, size, fi);
2135 }
else if (path && fs->op.truncate) {
2137 fprintf(stderr,
"truncate %s %llu\n", path,
2138 (
unsigned long long) size);
2140 return fs->op.truncate(path, size);
2146 int fuse_fs_utimens(
struct fuse_fs *fs,
const char *path,
2147 const struct timespec tv[2])
2150 if (fs->op.utimens) {
2152 fprintf(stderr,
"utimens %s %li.%09lu %li.%09lu\n",
2153 path, tv[0].tv_sec, tv[0].tv_nsec,
2154 tv[1].tv_sec, tv[1].tv_nsec);
2156 return fs->op.utimens(path, tv);
2157 }
else if(fs->op.utime) {
2161 fprintf(stderr,
"utime %s %li %li\n", path,
2162 tv[0].tv_sec, tv[1].tv_sec);
2164 buf.actime = tv[0].tv_sec;
2165 buf.modtime = tv[1].tv_sec;
2166 return fs->op.utime(path, &buf);
2172 int fuse_fs_access(
struct fuse_fs *fs,
const char *path,
int mask)
2175 if (fs->op.access) {
2177 fprintf(stderr,
"access %s 0%o\n", path, mask);
2179 return fs->op.access(path, mask);
2185 int fuse_fs_readlink(
struct fuse_fs *fs,
const char *path,
char *buf,
2189 if (fs->op.readlink) {
2191 fprintf(stderr,
"readlink %s %lu\n", path,
2192 (
unsigned long) len);
2194 return fs->op.readlink(path, buf, len);
2200 int fuse_fs_mknod(
struct fuse_fs *fs,
const char *path, mode_t mode,
2206 fprintf(stderr,
"mknod %s 0%o 0x%llx umask=0%03o\n",
2207 path, mode, (
unsigned long long) rdev,
2210 return fs->op.mknod(path, mode, rdev);
2216 int fuse_fs_mkdir(
struct fuse_fs *fs,
const char *path, mode_t mode)
2221 fprintf(stderr,
"mkdir %s 0%o umask=0%03o\n",
2224 return fs->op.mkdir(path, mode);
2230 int fuse_fs_setxattr(
struct fuse_fs *fs,
const char *path,
const char *name,
2231 const char *value,
size_t size,
int flags)
2234 if (fs->op.setxattr) {
2236 fprintf(stderr,
"setxattr %s %s %lu 0x%x\n",
2237 path, name, (
unsigned long) size, flags);
2239 return fs->op.setxattr(path, name, value, size, flags);
2245 int fuse_fs_getxattr(
struct fuse_fs *fs,
const char *path,
const char *name,
2246 char *value,
size_t size)
2249 if (fs->op.getxattr) {
2251 fprintf(stderr,
"getxattr %s %s %lu\n",
2252 path, name, (
unsigned long) size);
2254 return fs->op.getxattr(path, name, value, size);
2260 int fuse_fs_listxattr(
struct fuse_fs *fs,
const char *path,
char *list,
2264 if (fs->op.listxattr) {
2266 fprintf(stderr,
"listxattr %s %lu\n",
2267 path, (
unsigned long) size);
2269 return fs->op.listxattr(path, list, size);
2275 int fuse_fs_bmap(
struct fuse_fs *fs,
const char *path,
size_t blocksize,
2281 fprintf(stderr,
"bmap %s blocksize: %lu index: %llu\n",
2282 path, (
unsigned long) blocksize,
2283 (
unsigned long long) *idx);
2285 return fs->op.bmap(path, blocksize, idx);
2291 int fuse_fs_removexattr(
struct fuse_fs *fs,
const char *path,
const char *name)
2294 if (fs->op.removexattr) {
2296 fprintf(stderr,
"removexattr %s %s\n", path, name);
2298 return fs->op.removexattr(path, name);
2304 int fuse_fs_ioctl(
struct fuse_fs *fs,
const char *path,
int cmd,
void *arg,
2310 fprintf(stderr,
"ioctl[%llu] 0x%x flags: 0x%x\n",
2311 (
unsigned long long) fi->
fh, cmd, flags);
2313 return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2318 int fuse_fs_poll(
struct fuse_fs *fs,
const char *path,
2327 fprintf(stderr,
"poll[%llu] ph: %p\n",
2328 (
unsigned long long) fi->
fh, ph);
2330 res = fs->op.poll(path, fi, ph, reventsp);
2332 if (fs->debug && !res)
2333 fprintf(stderr,
" poll[%llu] revents: 0x%x\n",
2334 (
unsigned long long) fi->
fh, *reventsp);
2341 int fuse_fs_fallocate(
struct fuse_fs *fs,
const char *path,
int mode,
2345 if (fs->op.fallocate) {
2347 fprintf(stderr,
"fallocate %s mode %x, offset: %llu, length: %llu\n",
2350 (
unsigned long long) offset,
2351 (
unsigned long long) length);
2353 return fs->op.fallocate(path, mode, offset, length, fi);
2358 static int is_open(
struct fuse *f,
fuse_ino_t dir,
const char *name)
2362 pthread_mutex_lock(&f->lock);
2363 node = lookup_node(f, dir, name);
2364 if (node && node->open_count > 0)
2366 pthread_mutex_unlock(&f->lock);
2370 static char *hidden_name(
struct fuse *f,
fuse_ino_t dir,
const char *oldname,
2371 char *newname,
size_t bufsize)
2375 struct node *newnode;
2381 pthread_mutex_lock(&f->lock);
2382 node = lookup_node(f, dir, oldname);
2384 pthread_mutex_unlock(&f->lock);
2389 snprintf(newname, bufsize,
".fuse_hidden%08x%08x",
2390 (
unsigned int) node->nodeid, f->hidectr);
2391 newnode = lookup_node(f, dir, newname);
2394 res = try_get_path(f, dir, newname, &newpath, NULL,
false);
2395 pthread_mutex_unlock(&f->lock);
2399 memset(&buf, 0,
sizeof(buf));
2400 res = fuse_fs_getattr(f->fs, newpath, &buf);
2405 }
while(res == 0 && --failctr);
2410 static int hide_node(
struct fuse *f,
const char *oldpath,
2417 newpath = hidden_name(f, dir, oldname, newname,
sizeof(newname));
2419 err = fuse_fs_rename(f->fs, oldpath, newpath);
2421 err = rename_node(f, dir, oldname, dir, newname, 1);
2427 static int mtime_eq(
const struct stat *stbuf,
const struct timespec *ts)
2429 return stbuf->st_mtime == ts->tv_sec &&
2430 ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2433 #ifndef CLOCK_MONOTONIC 2434 #define CLOCK_MONOTONIC CLOCK_REALTIME 2437 static void curr_time(
struct timespec *now)
2439 static clockid_t clockid = CLOCK_MONOTONIC;
2440 int res = clock_gettime(clockid, now);
2441 if (res == -1 && errno == EINVAL) {
2442 clockid = CLOCK_REALTIME;
2443 res = clock_gettime(clockid, now);
2446 perror(
"fuse: clock_gettime");
2451 static void update_stat(
struct node *node,
const struct stat *stbuf)
2453 if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2454 stbuf->st_size != node->size))
2455 node->cache_valid = 0;
2456 node->mtime.tv_sec = stbuf->st_mtime;
2457 node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2458 node->size = stbuf->st_size;
2459 curr_time(&node->stat_updated);
2462 static int lookup_path(
struct fuse *f,
fuse_ino_t nodeid,
2463 const char *name,
const char *path,
2470 res = fuse_fs_fgetattr(f->fs, path, &e->
attr, fi);
2472 res = fuse_fs_getattr(f->fs, path, &e->
attr);
2476 node = find_node(f, nodeid, name);
2480 e->
ino = node->nodeid;
2484 if (f->conf.auto_cache) {
2485 pthread_mutex_lock(&f->lock);
2486 update_stat(node, &e->
attr);
2487 pthread_mutex_unlock(&f->lock);
2489 set_stat(f, e->
ino, &e->
attr);
2491 fprintf(stderr,
" NODEID: %lu\n",
2492 (
unsigned long) e->
ino);
2498 static struct fuse_context_i *fuse_get_context_internal(
void)
2500 struct fuse_context_i *c;
2502 c = (
struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2504 c = (
struct fuse_context_i *)
2505 calloc(1,
sizeof(
struct fuse_context_i));
2511 fprintf(stderr,
"fuse: failed to allocate thread specific data\n");
2514 pthread_setspecific(fuse_context_key, c);
2519 static void fuse_freecontext(
void *data)
2524 static int fuse_create_context_key(
void)
2527 pthread_mutex_lock(&fuse_context_lock);
2528 if (!fuse_context_ref) {
2529 err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2531 fprintf(stderr,
"fuse: failed to create thread specific key: %s\n",
2533 pthread_mutex_unlock(&fuse_context_lock);
2538 pthread_mutex_unlock(&fuse_context_lock);
2542 static void fuse_delete_context_key(
void)
2544 pthread_mutex_lock(&fuse_context_lock);
2546 if (!fuse_context_ref) {
2547 free(pthread_getspecific(fuse_context_key));
2548 pthread_key_delete(fuse_context_key);
2550 pthread_mutex_unlock(&fuse_context_lock);
2553 static struct fuse *req_fuse_prepare(
fuse_req_t req)
2555 struct fuse_context_i *c = fuse_get_context_internal();
2558 c->ctx.fuse = req_fuse(req);
2559 c->ctx.uid = ctx->
uid;
2560 c->ctx.gid = ctx->
gid;
2561 c->ctx.pid = ctx->
pid;
2562 c->ctx.umask = ctx->
umask;
2566 static inline void reply_err(
fuse_req_t req,
int err)
2576 struct fuse *f = req_fuse(req);
2580 forget_node(f, e->
ino, 1);
2583 reply_err(req, err);
2586 void fuse_fs_init(
struct fuse_fs *fs,
struct fuse_conn_info *conn)
2589 if (!fs->op.write_buf)
2596 fs->user_data = fs->op.init(conn);
2599 static void fuse_lib_init(
void *data,
struct fuse_conn_info *conn)
2601 struct fuse *f = (
struct fuse *) data;
2602 struct fuse_context_i *c = fuse_get_context_internal();
2604 memset(c, 0,
sizeof(*c));
2607 fuse_fs_init(f->fs, conn);
2610 void fuse_fs_destroy(
struct fuse_fs *fs)
2614 fs->op.destroy(fs->user_data);
2616 fuse_put_module(fs->m);
2620 static void fuse_lib_destroy(
void *data)
2622 struct fuse *f = (
struct fuse *) data;
2623 struct fuse_context_i *c = fuse_get_context_internal();
2625 memset(c, 0,
sizeof(*c));
2627 fuse_fs_destroy(f->fs);
2634 struct fuse *f = req_fuse_prepare(req);
2638 struct node *dot = NULL;
2640 if (name[0] ==
'.') {
2641 int len = strlen(name);
2643 if (len == 1 || (name[1] ==
'.' && len == 2)) {
2644 pthread_mutex_lock(&f->lock);
2647 fprintf(stderr,
"LOOKUP-DOT\n");
2648 dot = get_node_nocheck(f, parent);
2650 pthread_mutex_unlock(&f->lock);
2651 reply_entry(req, &e, -ESTALE);
2657 fprintf(stderr,
"LOOKUP-DOTDOT\n");
2658 parent = get_node(f, parent)->parent->nodeid;
2660 pthread_mutex_unlock(&f->lock);
2665 err = get_path_name(f, parent, name, &path);
2667 struct fuse_intr_data d;
2669 fprintf(stderr,
"LOOKUP %s\n", path);
2670 fuse_prepare_interrupt(f, req, &d);
2671 err = lookup_path(f, parent, name, path, &e, NULL);
2672 if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2677 fuse_finish_interrupt(f, req, &d);
2678 free_path(f, parent, path);
2681 pthread_mutex_lock(&f->lock);
2683 pthread_mutex_unlock(&f->lock);
2685 reply_entry(req, &e, err);
2688 static void do_forget(
struct fuse *f,
fuse_ino_t ino, uint64_t nlookup)
2691 fprintf(stderr,
"FORGET %llu/%llu\n", (
unsigned long long)ino,
2692 (
unsigned long long) nlookup);
2693 forget_node(f, ino, nlookup);
2697 unsigned long nlookup)
2699 do_forget(req_fuse(req), ino, nlookup);
2703 static void fuse_lib_forget_multi(
fuse_req_t req,
size_t count,
2704 struct fuse_forget_data *forgets)
2706 struct fuse *f = req_fuse(req);
2709 for (i = 0; i < count; i++)
2710 do_forget(f, forgets[i].ino, forgets[i].nlookup);
2719 struct fuse *f = req_fuse_prepare(req);
2724 memset(&buf, 0,
sizeof(buf));
2726 if (fi != NULL && f->fs->op.fgetattr)
2727 err = get_path_nullok(f, ino, &path);
2729 err = get_path(f, ino, &path);
2731 struct fuse_intr_data d;
2732 fuse_prepare_interrupt(f, req, &d);
2734 err = fuse_fs_fgetattr(f->fs, path, &buf, fi);
2736 err = fuse_fs_getattr(f->fs, path, &buf);
2737 fuse_finish_interrupt(f, req, &d);
2738 free_path(f, ino, path);
2743 pthread_mutex_lock(&f->lock);
2744 node = get_node(f, ino);
2745 if (node->is_hidden && buf.st_nlink > 0)
2747 if (f->conf.auto_cache)
2748 update_stat(node, &buf);
2749 pthread_mutex_unlock(&f->lock);
2750 set_stat(f, ino, &buf);
2753 reply_err(req, err);
2756 int fuse_fs_chmod(
struct fuse_fs *fs,
const char *path, mode_t mode)
2760 return fs->op.chmod(path, mode);
2768 struct fuse *f = req_fuse_prepare(req);
2773 memset(&buf, 0,
sizeof(buf));
2774 if (valid == FUSE_SET_ATTR_SIZE && fi != NULL &&
2775 f->fs->op.ftruncate && f->fs->op.fgetattr)
2776 err = get_path_nullok(f, ino, &path);
2778 err = get_path(f, ino, &path);
2780 struct fuse_intr_data d;
2781 fuse_prepare_interrupt(f, req, &d);
2783 if (!err && (valid & FUSE_SET_ATTR_MODE))
2784 err = fuse_fs_chmod(f->fs, path, attr->st_mode);
2785 if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2786 uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2787 attr->st_uid : (uid_t) -1;
2788 gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2789 attr->st_gid : (gid_t) -1;
2790 err = fuse_fs_chown(f->fs, path, uid, gid);
2792 if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2794 err = fuse_fs_ftruncate(f->fs, path,
2797 err = fuse_fs_truncate(f->fs, path,
2800 #ifdef HAVE_UTIMENSAT 2801 if (!err && f->utime_omit_ok &&
2802 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2803 struct timespec tv[2];
2807 tv[0].tv_nsec = UTIME_OMIT;
2808 tv[1].tv_nsec = UTIME_OMIT;
2810 if (valid & FUSE_SET_ATTR_ATIME_NOW)
2811 tv[0].tv_nsec = UTIME_NOW;
2812 else if (valid & FUSE_SET_ATTR_ATIME)
2813 tv[0] = attr->st_atim;
2815 if (valid & FUSE_SET_ATTR_MTIME_NOW)
2816 tv[1].tv_nsec = UTIME_NOW;
2817 else if (valid & FUSE_SET_ATTR_MTIME)
2818 tv[1] = attr->st_mtim;
2820 err = fuse_fs_utimens(f->fs, path, tv);
2824 (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2825 (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2826 struct timespec tv[2];
2827 tv[0].tv_sec = attr->st_atime;
2828 tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2829 tv[1].tv_sec = attr->st_mtime;
2830 tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2831 err = fuse_fs_utimens(f->fs, path, tv);
2835 err = fuse_fs_fgetattr(f->fs, path, &buf, fi);
2837 err = fuse_fs_getattr(f->fs, path, &buf);
2839 fuse_finish_interrupt(f, req, &d);
2840 free_path(f, ino, path);
2843 if (f->conf.auto_cache) {
2844 pthread_mutex_lock(&f->lock);
2845 update_stat(get_node(f, ino), &buf);
2846 pthread_mutex_unlock(&f->lock);
2848 set_stat(f, ino, &buf);
2851 reply_err(req, err);
2856 struct fuse *f = req_fuse_prepare(req);
2860 err = get_path(f, ino, &path);
2862 struct fuse_intr_data d;
2864 fuse_prepare_interrupt(f, req, &d);
2865 err = fuse_fs_access(f->fs, path, mask);
2866 fuse_finish_interrupt(f, req, &d);
2867 free_path(f, ino, path);
2869 reply_err(req, err);
2874 struct fuse *f = req_fuse_prepare(req);
2875 char linkname[PATH_MAX + 1];
2879 err = get_path(f, ino, &path);
2881 struct fuse_intr_data d;
2882 fuse_prepare_interrupt(f, req, &d);
2883 err = fuse_fs_readlink(f->fs, path, linkname,
sizeof(linkname));
2884 fuse_finish_interrupt(f, req, &d);
2885 free_path(f, ino, path);
2888 linkname[PATH_MAX] =
'\0';
2891 reply_err(req, err);
2895 mode_t mode, dev_t rdev)
2897 struct fuse *f = req_fuse_prepare(req);
2902 err = get_path_name(f, parent, name, &path);
2904 struct fuse_intr_data d;
2906 fuse_prepare_interrupt(f, req, &d);
2908 if (S_ISREG(mode)) {
2911 memset(&fi, 0,
sizeof(fi));
2912 fi.
flags = O_CREAT | O_EXCL | O_WRONLY;
2913 err = fuse_fs_create(f->fs, path, mode, &fi);
2915 err = lookup_path(f, parent, name, path, &e,
2917 fuse_fs_release(f->fs, path, &fi);
2920 if (err == -ENOSYS) {
2921 err = fuse_fs_mknod(f->fs, path, mode, rdev);
2923 err = lookup_path(f, parent, name, path, &e,
2926 fuse_finish_interrupt(f, req, &d);
2927 free_path(f, parent, path);
2929 reply_entry(req, &e, err);
2935 struct fuse *f = req_fuse_prepare(req);
2940 err = get_path_name(f, parent, name, &path);
2942 struct fuse_intr_data d;
2944 fuse_prepare_interrupt(f, req, &d);
2945 err = fuse_fs_mkdir(f->fs, path, mode);
2947 err = lookup_path(f, parent, name, path, &e, NULL);
2948 fuse_finish_interrupt(f, req, &d);
2949 free_path(f, parent, path);
2951 reply_entry(req, &e, err);
2957 struct fuse *f = req_fuse_prepare(req);
2962 err = get_path_wrlock(f, parent, name, &path, &wnode);
2964 struct fuse_intr_data d;
2966 fuse_prepare_interrupt(f, req, &d);
2967 if (!f->conf.hard_remove && is_open(f, parent, name)) {
2968 err = hide_node(f, path, parent, name);
2970 err = fuse_fs_unlink(f->fs, path);
2972 remove_node(f, parent, name);
2974 fuse_finish_interrupt(f, req, &d);
2975 free_path_wrlock(f, parent, wnode, path);
2977 reply_err(req, err);
2982 struct fuse *f = req_fuse_prepare(req);
2987 err = get_path_wrlock(f, parent, name, &path, &wnode);
2989 struct fuse_intr_data d;
2991 fuse_prepare_interrupt(f, req, &d);
2992 err = fuse_fs_rmdir(f->fs, path);
2993 fuse_finish_interrupt(f, req, &d);
2995 remove_node(f, parent, name);
2996 free_path_wrlock(f, parent, wnode, path);
2998 reply_err(req, err);
3001 static void fuse_lib_symlink(
fuse_req_t req,
const char *linkname,
3004 struct fuse *f = req_fuse_prepare(req);
3009 err = get_path_name(f, parent, name, &path);
3011 struct fuse_intr_data d;
3013 fuse_prepare_interrupt(f, req, &d);
3014 err = fuse_fs_symlink(f->fs, linkname, path);
3016 err = lookup_path(f, parent, name, path, &e, NULL);
3017 fuse_finish_interrupt(f, req, &d);
3018 free_path(f, parent, path);
3020 reply_entry(req, &e, err);
3025 const char *newname)
3027 struct fuse *f = req_fuse_prepare(req);
3030 struct node *wnode1;
3031 struct node *wnode2;
3034 err = get_path2(f, olddir, oldname, newdir, newname,
3035 &oldpath, &newpath, &wnode1, &wnode2);
3037 struct fuse_intr_data d;
3039 fuse_prepare_interrupt(f, req, &d);
3040 if (!f->conf.hard_remove && is_open(f, newdir, newname))
3041 err = hide_node(f, newpath, newdir, newname);
3043 err = fuse_fs_rename(f->fs, oldpath, newpath);
3045 err = rename_node(f, olddir, oldname, newdir,
3048 fuse_finish_interrupt(f, req, &d);
3049 free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3051 reply_err(req, err);
3055 const char *newname)
3057 struct fuse *f = req_fuse_prepare(req);
3063 err = get_path2(f, ino, NULL, newparent, newname,
3064 &oldpath, &newpath, NULL, NULL);
3066 struct fuse_intr_data d;
3068 fuse_prepare_interrupt(f, req, &d);
3069 err = fuse_fs_link(f->fs, oldpath, newpath);
3071 err = lookup_path(f, newparent, newname, newpath,
3073 fuse_finish_interrupt(f, req, &d);
3074 free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3076 reply_entry(req, &e, err);
3079 static void fuse_do_release(
struct fuse *f,
fuse_ino_t ino,
const char *path,
3083 int unlink_hidden = 0;
3084 const char *compatpath;
3086 if (path != NULL || f->nullpath_ok || f->conf.nopath)
3091 fuse_fs_release(f->fs, compatpath, fi);
3093 pthread_mutex_lock(&f->lock);
3094 node = get_node(f, ino);
3095 assert(node->open_count > 0);
3097 if (node->is_hidden && !node->open_count) {
3099 node->is_hidden = 0;
3101 pthread_mutex_unlock(&f->lock);
3105 fuse_fs_unlink(f->fs, path);
3106 }
else if (f->conf.nopath) {
3109 if (get_path(f, ino, &unlinkpath) == 0)
3110 fuse_fs_unlink(f->fs, unlinkpath);
3112 free_path(f, ino, unlinkpath);
3118 const char *name, mode_t mode,
3121 struct fuse *f = req_fuse_prepare(req);
3122 struct fuse_intr_data d;
3127 err = get_path_name(f, parent, name, &path);
3129 fuse_prepare_interrupt(f, req, &d);
3130 err = fuse_fs_create(f->fs, path, mode, fi);
3132 err = lookup_path(f, parent, name, path, &e, fi);
3134 fuse_fs_release(f->fs, path, fi);
3135 else if (!S_ISREG(e.
attr.st_mode)) {
3137 fuse_fs_release(f->fs, path, fi);
3138 forget_node(f, e.
ino, 1);
3140 if (f->conf.direct_io)
3142 if (f->conf.kernel_cache)
3147 fuse_finish_interrupt(f, req, &d);
3150 pthread_mutex_lock(&f->lock);
3151 get_node(f, e.
ino)->open_count++;
3152 pthread_mutex_unlock(&f->lock);
3156 fuse_do_release(f, e.
ino, path, fi);
3157 forget_node(f, e.
ino, 1);
3160 reply_err(req, err);
3163 free_path(f, parent, path);
3166 static double diff_timespec(
const struct timespec *t1,
3167 const struct timespec *t2)
3169 return (t1->tv_sec - t2->tv_sec) +
3170 ((double) t1->tv_nsec - (
double) t2->tv_nsec) / 1000000000.0;
3173 static void open_auto_cache(
struct fuse *f,
fuse_ino_t ino,
const char *path,
3178 pthread_mutex_lock(&f->lock);
3179 node = get_node(f, ino);
3180 if (node->cache_valid) {
3181 struct timespec now;
3184 if (diff_timespec(&now, &node->stat_updated) >
3185 f->conf.ac_attr_timeout) {
3188 pthread_mutex_unlock(&f->lock);
3189 err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
3190 pthread_mutex_lock(&f->lock);
3192 update_stat(node, &stbuf);
3194 node->cache_valid = 0;
3197 if (node->cache_valid)
3200 node->cache_valid = 1;
3201 pthread_mutex_unlock(&f->lock);
3207 struct fuse *f = req_fuse_prepare(req);
3208 struct fuse_intr_data d;
3212 err = get_path(f, ino, &path);
3214 fuse_prepare_interrupt(f, req, &d);
3215 err = fuse_fs_open(f->fs, path, fi);
3217 if (f->conf.direct_io)
3219 if (f->conf.kernel_cache)
3222 if (f->conf.auto_cache)
3223 open_auto_cache(f, ino, path, fi);
3225 fuse_finish_interrupt(f, req, &d);
3228 pthread_mutex_lock(&f->lock);
3229 get_node(f, ino)->open_count++;
3230 pthread_mutex_unlock(&f->lock);
3234 fuse_do_release(f, ino, path, fi);
3237 reply_err(req, err);
3239 free_path(f, ino, path);
3245 struct fuse *f = req_fuse_prepare(req);
3250 res = get_path_nullok(f, ino, &path);
3252 struct fuse_intr_data d;
3254 fuse_prepare_interrupt(f, req, &d);
3255 res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3256 fuse_finish_interrupt(f, req, &d);
3257 free_path(f, ino, path);
3263 reply_err(req, res);
3272 struct fuse *f = req_fuse_prepare(req);
3276 res = get_path_nullok(f, ino, &path);
3278 struct fuse_intr_data d;
3280 fuse_prepare_interrupt(f, req, &d);
3281 res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3282 fuse_finish_interrupt(f, req, &d);
3283 free_path(f, ino, path);
3289 reply_err(req, res);
3295 struct fuse *f = req_fuse_prepare(req);
3299 err = get_path_nullok(f, ino, &path);
3301 struct fuse_intr_data d;
3303 fuse_prepare_interrupt(f, req, &d);
3304 err = fuse_fs_fsync(f->fs, path, datasync, fi);
3305 fuse_finish_interrupt(f, req, &d);
3306 free_path(f, ino, path);
3308 reply_err(req, err);
3311 static struct fuse_dh *get_dirhandle(
const struct fuse_file_info *llfi,
3314 struct fuse_dh *dh = (
struct fuse_dh *) (uintptr_t) llfi->
fh;
3317 fi->fh_old = dh->fh;
3324 struct fuse *f = req_fuse_prepare(req);
3325 struct fuse_intr_data d;
3331 dh = (
struct fuse_dh *) malloc(
sizeof(
struct fuse_dh));
3333 reply_err(req, -ENOMEM);
3336 memset(dh, 0,
sizeof(
struct fuse_dh));
3338 dh->contents = NULL;
3342 fuse_mutex_init(&dh->lock);
3344 llfi->
fh = (uintptr_t) dh;
3346 memset(&fi, 0,
sizeof(fi));
3349 err = get_path(f, ino, &path);
3351 fuse_prepare_interrupt(f, req, &d);
3352 err = fuse_fs_opendir(f->fs, path, &fi);
3353 fuse_finish_interrupt(f, req, &d);
3360 fuse_fs_releasedir(f->fs, path, &fi);
3361 pthread_mutex_destroy(&dh->lock);
3365 reply_err(req, err);
3366 pthread_mutex_destroy(&dh->lock);
3369 free_path(f, ino, path);
3372 static int extend_contents(
struct fuse_dh *dh,
unsigned minsize)
3374 if (minsize > dh->size) {
3376 unsigned newsize = dh->size;
3379 while (newsize < minsize) {
3380 if (newsize >= 0x80000000)
3381 newsize = 0xffffffff;
3386 newptr = (
char *) realloc(dh->contents, newsize);
3388 dh->error = -ENOMEM;
3391 dh->contents = newptr;
3397 static int fill_dir(
void *dh_,
const char *name,
const struct stat *statp,
3400 struct fuse_dh *dh = (
struct fuse_dh *) dh_;
3407 memset(&stbuf, 0,
sizeof(stbuf));
3408 stbuf.st_ino = FUSE_UNKNOWN_INO;
3411 if (!dh->fuse->conf.use_ino) {
3412 stbuf.st_ino = FUSE_UNKNOWN_INO;
3413 if (dh->fuse->conf.readdir_ino) {
3415 pthread_mutex_lock(&dh->fuse->lock);
3416 node = lookup_node(dh->fuse, dh->nodeid, name);
3418 stbuf.st_ino = (ino_t) node->nodeid;
3419 pthread_mutex_unlock(&dh->fuse->lock);
3424 if (extend_contents(dh, dh->needlen) == -1)
3430 dh->needlen - dh->len, name,
3432 if (newlen > dh->needlen)
3437 if (extend_contents(dh, newlen) == -1)
3441 dh->size - dh->len, name, &stbuf, newlen);
3448 size_t size, off_t off,
struct fuse_dh *dh,
3454 if (f->fs->op.readdir)
3455 err = get_path_nullok(f, ino, &path);
3457 err = get_path(f, ino, &path);
3459 struct fuse_intr_data d;
3466 fuse_prepare_interrupt(f, req, &d);
3467 err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
3468 fuse_finish_interrupt(f, req, &d);
3474 free_path(f, ino, path);
3482 struct fuse *f = req_fuse_prepare(req);
3484 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3486 pthread_mutex_lock(&dh->lock);
3493 int err = readdir_fill(f, req, ino, size, off, dh, &fi);
3495 reply_err(req, err);
3500 if (off < dh->len) {
3501 if (off + size > dh->len)
3502 size = dh->len - off;
3511 pthread_mutex_unlock(&dh->lock);
3517 struct fuse *f = req_fuse_prepare(req);
3518 struct fuse_intr_data d;
3520 struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3522 const char *compatpath;
3524 get_path_nullok(f, ino, &path);
3525 if (path != NULL || f->nullpath_ok || f->conf.nopath)
3530 fuse_prepare_interrupt(f, req, &d);
3531 fuse_fs_releasedir(f->fs, compatpath, &fi);
3532 fuse_finish_interrupt(f, req, &d);
3533 free_path(f, ino, path);
3535 pthread_mutex_lock(&dh->lock);
3536 pthread_mutex_unlock(&dh->lock);
3537 pthread_mutex_destroy(&dh->lock);
3546 struct fuse *f = req_fuse_prepare(req);
3551 get_dirhandle(llfi, &fi);
3553 err = get_path_nullok(f, ino, &path);
3555 struct fuse_intr_data d;
3556 fuse_prepare_interrupt(f, req, &d);
3557 err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3558 fuse_finish_interrupt(f, req, &d);
3559 free_path(f, ino, path);
3561 reply_err(req, err);
3566 struct fuse *f = req_fuse_prepare(req);
3571 memset(&buf, 0,
sizeof(buf));
3573 err = get_path(f, ino, &path);
3576 struct fuse_intr_data d;
3577 fuse_prepare_interrupt(f, req, &d);
3578 err = fuse_fs_statfs(f->fs, path ? path :
"/", &buf);
3579 fuse_finish_interrupt(f, req, &d);
3580 free_path(f, ino, path);
3586 reply_err(req, err);
3590 const char *value,
size_t size,
int flags)
3592 struct fuse *f = req_fuse_prepare(req);
3596 err = get_path(f, ino, &path);
3598 struct fuse_intr_data d;
3599 fuse_prepare_interrupt(f, req, &d);
3600 err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3601 fuse_finish_interrupt(f, req, &d);
3602 free_path(f, ino, path);
3604 reply_err(req, err);
3608 const char *name,
char *value,
size_t size)
3613 err = get_path(f, ino, &path);
3615 struct fuse_intr_data d;
3616 fuse_prepare_interrupt(f, req, &d);
3617 err = fuse_fs_getxattr(f->fs, path, name, value, size);
3618 fuse_finish_interrupt(f, req, &d);
3619 free_path(f, ino, path);
3627 struct fuse *f = req_fuse_prepare(req);
3631 char *value = (
char *) malloc(size);
3632 if (value == NULL) {
3633 reply_err(req, -ENOMEM);
3636 res = common_getxattr(f, req, ino, name, value, size);
3640 reply_err(req, res);
3643 res = common_getxattr(f, req, ino, name, NULL, 0);
3647 reply_err(req, res);
3652 char *list,
size_t size)
3657 err = get_path(f, ino, &path);
3659 struct fuse_intr_data d;
3660 fuse_prepare_interrupt(f, req, &d);
3661 err = fuse_fs_listxattr(f->fs, path, list, size);
3662 fuse_finish_interrupt(f, req, &d);
3663 free_path(f, ino, path);
3670 struct fuse *f = req_fuse_prepare(req);
3674 char *list = (
char *) malloc(size);
3676 reply_err(req, -ENOMEM);
3679 res = common_listxattr(f, req, ino, list, size);
3683 reply_err(req, res);
3686 res = common_listxattr(f, req, ino, NULL, 0);
3690 reply_err(req, res);
3697 struct fuse *f = req_fuse_prepare(req);
3701 err = get_path(f, ino, &path);
3703 struct fuse_intr_data d;
3704 fuse_prepare_interrupt(f, req, &d);
3705 err = fuse_fs_removexattr(f->fs, path, name);
3706 fuse_finish_interrupt(f, req, &d);
3707 free_path(f, ino, path);
3709 reply_err(req, err);
3712 static struct lock *locks_conflict(
struct node *node,
const struct lock *lock)
3716 for (l = node->locks; l; l = l->next)
3717 if (l->owner != lock->owner &&
3718 lock->start <= l->end && l->start <= lock->end &&
3719 (l->type == F_WRLCK || lock->type == F_WRLCK))
3725 static void delete_lock(
struct lock **lockp)
3727 struct lock *l = *lockp;
3732 static void insert_lock(
struct lock **pos,
struct lock *lock)
3738 static int locks_insert(
struct node *node,
struct lock *lock)
3741 struct lock *newl1 = NULL;
3742 struct lock *newl2 = NULL;
3744 if (lock->type != F_UNLCK || lock->start != 0 ||
3745 lock->end != OFFSET_MAX) {
3746 newl1 = malloc(
sizeof(
struct lock));
3747 newl2 = malloc(
sizeof(
struct lock));
3749 if (!newl1 || !newl2) {
3756 for (lp = &node->locks; *lp;) {
3757 struct lock *l = *lp;
3758 if (l->owner != lock->owner)
3761 if (lock->type == l->type) {
3762 if (l->end < lock->start - 1)
3764 if (lock->end < l->start - 1)
3766 if (l->start <= lock->start && lock->end <= l->end)
3768 if (l->start < lock->start)
3769 lock->start = l->start;
3770 if (lock->end < l->end)
3774 if (l->end < lock->start)
3776 if (lock->end < l->start)
3778 if (lock->start <= l->start && l->end <= lock->end)
3780 if (l->end <= lock->end) {
3781 l->end = lock->start - 1;
3784 if (lock->start <= l->start) {
3785 l->start = lock->end + 1;
3789 newl2->start = lock->end + 1;
3790 l->end = lock->start - 1;
3791 insert_lock(&l->next, newl2);
3801 if (lock->type != F_UNLCK) {
3803 insert_lock(lp, newl1);
3812 static void flock_to_lock(
struct flock *flock,
struct lock *lock)
3814 memset(lock, 0,
sizeof(
struct lock));
3815 lock->type = flock->l_type;
3816 lock->start = flock->l_start;
3818 flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
3819 lock->pid = flock->l_pid;
3822 static void lock_to_flock(
struct lock *lock,
struct flock *flock)
3824 flock->l_type = lock->type;
3825 flock->l_start = lock->start;
3827 (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
3828 flock->l_pid = lock->pid;
3834 struct fuse_intr_data d;
3840 fuse_prepare_interrupt(f, req, &d);
3841 memset(&lock, 0,
sizeof(lock));
3842 lock.l_type = F_UNLCK;
3843 lock.l_whence = SEEK_SET;
3844 err = fuse_fs_flush(f->fs, path, fi);
3845 errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
3846 fuse_finish_interrupt(f, req, &d);
3848 if (errlock != -ENOSYS) {
3849 flock_to_lock(&lock, &l);
3851 pthread_mutex_lock(&f->lock);
3852 locks_insert(get_node(f, ino), &l);
3853 pthread_mutex_unlock(&f->lock);
3866 struct fuse *f = req_fuse_prepare(req);
3867 struct fuse_intr_data d;
3871 get_path_nullok(f, ino, &path);
3873 err = fuse_flush_common(f, req, ino, path, fi);
3878 fuse_prepare_interrupt(f, req, &d);
3879 fuse_do_release(f, ino, path, fi);
3880 fuse_finish_interrupt(f, req, &d);
3881 free_path(f, ino, path);
3883 reply_err(req, err);
3889 struct fuse *f = req_fuse_prepare(req);
3893 get_path_nullok(f, ino, &path);
3894 err = fuse_flush_common(f, req, ino, path, fi);
3895 free_path(f, ino, path);
3897 reply_err(req, err);
3904 struct fuse *f = req_fuse_prepare(req);
3908 err = get_path_nullok(f, ino, &path);
3910 struct fuse_intr_data d;
3911 fuse_prepare_interrupt(f, req, &d);
3912 err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
3913 fuse_finish_interrupt(f, req, &d);
3914 free_path(f, ino, path);
3924 struct lock *conflict;
3925 struct fuse *f = req_fuse(req);
3927 flock_to_lock(lock, &l);
3929 pthread_mutex_lock(&f->lock);
3930 conflict = locks_conflict(get_node(f, ino), &l);
3932 lock_to_flock(conflict, lock);
3933 pthread_mutex_unlock(&f->lock);
3935 err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
3942 reply_err(req, err);
3949 int err = fuse_lock_common(req, ino, fi, lock,
3950 sleep ? F_SETLKW : F_SETLK);
3952 struct fuse *f = req_fuse(req);
3954 flock_to_lock(lock, &l);
3956 pthread_mutex_lock(&f->lock);
3957 locks_insert(get_node(f, ino), &l);
3958 pthread_mutex_unlock(&f->lock);
3960 reply_err(req, err);
3966 struct fuse *f = req_fuse_prepare(req);
3970 err = get_path_nullok(f, ino, &path);
3972 struct fuse_intr_data d;
3973 fuse_prepare_interrupt(f, req, &d);
3974 err = fuse_fs_flock(f->fs, path, fi, op);
3975 fuse_finish_interrupt(f, req, &d);
3976 free_path(f, ino, path);
3978 reply_err(req, err);
3984 struct fuse *f = req_fuse_prepare(req);
3985 struct fuse_intr_data d;
3989 err = get_path(f, ino, &path);
3991 fuse_prepare_interrupt(f, req, &d);
3992 err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
3993 fuse_finish_interrupt(f, req, &d);
3994 free_path(f, ino, path);
3999 reply_err(req, err);
4004 const void *in_buf,
size_t in_bufsz,
4007 struct fuse *f = req_fuse_prepare(req);
4008 struct fuse_intr_data d;
4010 char *path, *out_buf = NULL;
4014 if (flags & FUSE_IOCTL_UNRESTRICTED)
4017 if (flags & FUSE_IOCTL_DIR)
4018 get_dirhandle(llfi, &fi);
4024 out_buf = malloc(out_bufsz);
4029 assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4031 memcpy(out_buf, in_buf, in_bufsz);
4033 err = get_path_nullok(f, ino, &path);
4037 fuse_prepare_interrupt(f, req, &d);
4039 err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4040 out_buf ?: (
void *)in_buf);
4042 fuse_finish_interrupt(f, req, &d);
4043 free_path(f, ino, path);
4048 reply_err(req, err);
4056 struct fuse *f = req_fuse_prepare(req);
4057 struct fuse_intr_data d;
4060 unsigned revents = 0;
4062 err = get_path_nullok(f, ino, &path);
4064 fuse_prepare_interrupt(f, req, &d);
4065 err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4066 fuse_finish_interrupt(f, req, &d);
4067 free_path(f, ino, path);
4072 reply_err(req, err);
4078 struct fuse *f = req_fuse_prepare(req);
4079 struct fuse_intr_data d;
4083 err = get_path_nullok(f, ino, &path);
4085 fuse_prepare_interrupt(f, req, &d);
4086 err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4087 fuse_finish_interrupt(f, req, &d);
4088 free_path(f, ino, path);
4090 reply_err(req, err);
4093 static int clean_delay(
struct fuse *f)
4101 int max_sleep = 3600;
4102 int sleep_time = f->conf.remember / 10;
4104 if (sleep_time > max_sleep)
4106 if (sleep_time < min_sleep)
4113 struct node_lru *lnode;
4114 struct list_head *curr, *next;
4116 struct timespec now;
4118 pthread_mutex_lock(&f->lock);
4122 for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4126 lnode = list_entry(curr,
struct node_lru, lru);
4127 node = &lnode->node;
4129 age = diff_timespec(&now, &lnode->forget_time);
4130 if (age <= f->conf.remember)
4133 assert(node->nlookup == 1);
4136 if (node->refctr > 1)
4140 unhash_name(f, node);
4141 unref_node(f, node);
4143 pthread_mutex_unlock(&f->lock);
4145 return clean_delay(f);
4149 .
init = fuse_lib_init,
4150 .destroy = fuse_lib_destroy,
4151 .lookup = fuse_lib_lookup,
4152 .forget = fuse_lib_forget,
4153 .forget_multi = fuse_lib_forget_multi,
4154 .getattr = fuse_lib_getattr,
4155 .setattr = fuse_lib_setattr,
4156 .access = fuse_lib_access,
4157 .readlink = fuse_lib_readlink,
4158 .mknod = fuse_lib_mknod,
4159 .mkdir = fuse_lib_mkdir,
4160 .unlink = fuse_lib_unlink,
4161 .rmdir = fuse_lib_rmdir,
4162 .symlink = fuse_lib_symlink,
4163 .rename = fuse_lib_rename,
4164 .link = fuse_lib_link,
4165 .create = fuse_lib_create,
4166 .open = fuse_lib_open,
4167 .read = fuse_lib_read,
4168 .write_buf = fuse_lib_write_buf,
4169 .flush = fuse_lib_flush,
4170 .release = fuse_lib_release,
4171 .fsync = fuse_lib_fsync,
4172 .opendir = fuse_lib_opendir,
4173 .readdir = fuse_lib_readdir,
4174 .releasedir = fuse_lib_releasedir,
4175 .fsyncdir = fuse_lib_fsyncdir,
4176 .statfs = fuse_lib_statfs,
4177 .setxattr = fuse_lib_setxattr,
4178 .getxattr = fuse_lib_getxattr,
4179 .listxattr = fuse_lib_listxattr,
4180 .removexattr = fuse_lib_removexattr,
4181 .getlk = fuse_lib_getlk,
4182 .setlk = fuse_lib_setlk,
4183 .flock = fuse_lib_flock,
4184 .bmap = fuse_lib_bmap,
4185 .ioctl = fuse_lib_ioctl,
4186 .poll = fuse_lib_poll,
4187 .fallocate = fuse_lib_fallocate,
4190 int fuse_notify_poll(
struct fuse_pollhandle *ph)
4195 static void free_cmd(
struct fuse_cmd *cmd)
4201 void fuse_process_cmd(
struct fuse *f,
struct fuse_cmd *cmd)
4203 fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch);
4207 int fuse_exited(
struct fuse *f)
4217 static struct fuse_cmd *fuse_alloc_cmd(
size_t bufsize)
4219 struct fuse_cmd *cmd = (
struct fuse_cmd *) malloc(
sizeof(*cmd));
4221 fprintf(stderr,
"fuse: failed to allocate cmd\n");
4224 cmd->buf = (
char *) malloc(bufsize);
4225 if (cmd->buf == NULL) {
4226 fprintf(stderr,
"fuse: failed to allocate read buffer\n");
4233 struct fuse_cmd *fuse_read_cmd(
struct fuse *f)
4235 struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL);
4236 size_t bufsize = fuse_chan_bufsize(ch);
4237 struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
4239 int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
4242 if (res < 0 && res != -EINTR && res != -EAGAIN)
4252 static int fuse_session_loop_remember(
struct fuse *f)
4254 struct fuse_session *se = f->se;
4256 struct timespec now;
4258 struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
4259 size_t bufsize = fuse_chan_bufsize(ch);
4260 char *buf = (
char *) malloc(bufsize);
4261 struct pollfd fds = {
4262 .fd = fuse_chan_fd(ch),
4267 fprintf(stderr,
"fuse: failed to allocate read buffer\n");
4272 next_clean = now.tv_sec;
4274 struct fuse_chan *tmpch = ch;
4282 if (now.tv_sec < next_clean)
4283 timeout = next_clean - now.tv_sec;
4287 res = poll(&fds, 1, timeout * 1000);
4289 if (errno == -EINTR)
4293 }
else if (res > 0) {
4305 next_clean = now.tv_sec + timeout;
4311 return res < 0 ? -1 : 0;
4320 return fuse_session_loop_remember(f);
4325 int fuse_invalidate(
struct fuse *f,
const char *path)
4339 return &fuse_get_context_internal()->ctx;
4350 return &fuse_get_context_internal()->ctx;
4352 FUSE_SYMVER(
".symver fuse_get_context_compat22,fuse_get_context@FUSE_2.2");
4356 fuse_req_t req = fuse_get_context_internal()->req;
4365 void fuse_set_getcontext_func(
struct fuse_context *(*func)(
void))
4375 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v } 4377 static const struct fuse_opt fuse_lib_opts[] = {
4382 FUSE_LIB_OPT(
"debug", debug, 1),
4383 FUSE_LIB_OPT(
"-d", debug, 1),
4385 FUSE_LIB_OPT(
"use_ino",
use_ino, 1),
4387 FUSE_LIB_OPT(
"direct_io",
direct_io, 1),
4391 FUSE_LIB_OPT(
"umask=",
set_mode, 1),
4392 FUSE_LIB_OPT(
"umask=%o", umask, 0),
4393 FUSE_LIB_OPT(
"uid=",
set_uid, 1),
4394 FUSE_LIB_OPT(
"uid=%d", uid, 0),
4395 FUSE_LIB_OPT(
"gid=",
set_gid, 1),
4396 FUSE_LIB_OPT(
"gid=%d", gid, 0),
4399 FUSE_LIB_OPT(
"ac_attr_timeout=%lf", ac_attr_timeout, 0),
4402 FUSE_LIB_OPT(
"noforget",
remember, -1),
4403 FUSE_LIB_OPT(
"remember=%u",
remember, 0),
4404 FUSE_LIB_OPT(
"nopath", nopath, 1),
4405 FUSE_LIB_OPT(
"intr",
intr, 1),
4407 FUSE_LIB_OPT(
"modules=%s", modules, 0),
4414 " -o hard_remove immediate removal (don't hide files)\n" 4415 " -o use_ino let filesystem set inode numbers\n" 4416 " -o readdir_ino try to fill in d_ino in readdir\n" 4417 " -o direct_io use direct I/O\n" 4418 " -o kernel_cache cache files in kernel\n" 4419 " -o [no]auto_cache enable caching based on modification times (off)\n" 4420 " -o umask=M set file permissions (octal)\n" 4421 " -o uid=N set file owner\n" 4422 " -o gid=N set file group\n" 4423 " -o entry_timeout=T cache timeout for names (1.0s)\n" 4424 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n" 4425 " -o attr_timeout=T cache timeout for attributes (1.0s)\n" 4426 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n" 4427 " -o noforget never forget cached inodes\n" 4428 " -o remember=T remember cached inodes for T seconds (0s)\n" 4429 " -o nopath don't supply path if not necessary\n" 4430 " -o intr allow requests to be interrupted\n" 4431 " -o intr_signal=NUM signal to send on interrupt (%i)\n" 4432 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n" 4433 "\n", FUSE_DEFAULT_INTR_SIGNAL);
4436 static void fuse_lib_help_modules(
void)
4439 fprintf(stderr,
"\nModule options:\n");
4440 pthread_mutex_lock(&fuse_context_lock);
4441 for (m = fuse_modules; m; m = m->next) {
4442 struct fuse_fs *fs = NULL;
4443 struct fuse_fs *newfs;
4447 fprintf(stderr,
"\n[%s]\n", m->name);
4448 newfs = m->factory(&args, &fs);
4449 assert(newfs == NULL);
4453 pthread_mutex_unlock(&fuse_context_lock);
4456 static int fuse_lib_opt_proc(
void *data,
const char *arg,
int key,
4459 (void) arg; (void) outargs;
4461 if (key == KEY_HELP) {
4470 int fuse_is_lib_option(
const char *opt)
4472 return fuse_lowlevel_is_lib_option(opt) ||
4476 static int fuse_init_intr_signal(
int signum,
int *installed)
4478 struct sigaction old_sa;
4480 if (sigaction(signum, NULL, &old_sa) == -1) {
4481 perror(
"fuse: cannot get old signal handler");
4485 if (old_sa.sa_handler == SIG_DFL) {
4486 struct sigaction sa;
4488 memset(&sa, 0,
sizeof(
struct sigaction));
4489 sa.sa_handler = fuse_intr_sighandler;
4490 sigemptyset(&sa.sa_mask);
4492 if (sigaction(signum, &sa, NULL) == -1) {
4493 perror(
"fuse: cannot set interrupt signal handler");
4501 static void fuse_restore_intr_signal(
int signum)
4503 struct sigaction sa;
4505 memset(&sa, 0,
sizeof(
struct sigaction));
4506 sa.sa_handler = SIG_DFL;
4507 sigaction(signum, &sa, NULL);
4511 static int fuse_push_module(
struct fuse *f,
const char *module,
4514 struct fuse_fs *fs[2] = { f->fs, NULL };
4515 struct fuse_fs *newfs;
4521 newfs = m->factory(args, fs);
4528 f->nullpath_ok = newfs->op.flag_nullpath_ok && f->nullpath_ok;
4529 f->conf.nopath = newfs->op.flag_nopath && f->conf.nopath;
4530 f->utime_omit_ok = newfs->op.flag_utime_omit_ok && f->utime_omit_ok;
4540 fprintf(stderr,
"fuse: warning: library too old, some operations may not not work\n");
4544 fs = (
struct fuse_fs *) calloc(1,
sizeof(
struct fuse_fs));
4546 fprintf(stderr,
"fuse: failed to allocate fuse_fs object\n");
4550 fs->user_data = user_data;
4552 memcpy(&fs->op, op, op_size);
4556 static int node_table_init(
struct node_table *t)
4558 t->size = NODE_TABLE_MIN_SIZE;
4559 t->array = (
struct node **) calloc(1,
sizeof(
struct node *) * t->size);
4560 if (t->array == NULL) {
4561 fprintf(stderr,
"fuse: memory allocation failed\n");
4570 static void *fuse_prune_nodes(
void *fuse)
4572 struct fuse *f = fuse;
4585 return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4592 if (lru_enabled(f)) {
4593 pthread_mutex_lock(&f->lock);
4594 pthread_cancel(f->prune_thread);
4595 pthread_mutex_unlock(&f->lock);
4596 pthread_join(f->prune_thread, NULL);
4600 struct fuse *fuse_new_common(
struct fuse_chan *ch,
struct fuse_args *args,
4602 size_t op_size,
void *user_data,
int compat)
4609 if (fuse_create_context_key() == -1)
4612 f = (
struct fuse *) calloc(1,
sizeof(
struct fuse));
4614 fprintf(stderr,
"fuse: failed to allocate fuse object\n");
4615 goto out_delete_context_key;
4622 fs->compat = compat;
4624 f->nullpath_ok = fs->op.flag_nullpath_ok;
4625 f->conf.nopath = fs->op.flag_nopath;
4626 f->utime_omit_ok = fs->op.flag_utime_omit_ok;
4634 f->conf.entry_timeout = 1.0;
4635 f->conf.attr_timeout = 1.0;
4636 f->conf.negative_timeout = 0.0;
4637 f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4639 f->pagesize = getpagesize();
4640 init_list_head(&f->partial_slabs);
4641 init_list_head(&f->full_slabs);
4642 init_list_head(&f->lru_table);
4645 fuse_lib_opt_proc) == -1)
4648 if (f->conf.modules) {
4652 for (module = f->conf.modules; module; module = next) {
4654 for (p = module; *p && *p !=
':'; p++);
4655 next = *p ? p + 1 : NULL;
4658 fuse_push_module(f, module, args) == -1)
4663 if (!f->conf.ac_attr_timeout_set)
4664 f->conf.ac_attr_timeout = f->conf.attr_timeout;
4666 #if defined(__FreeBSD__) || defined(__NetBSD__) 4671 f->conf.readdir_ino = 1;
4674 if (compat && compat <= 25) {
4675 if (fuse_sync_compat_args(args) == -1)
4679 f->se = fuse_lowlevel_new_common(args, &llop,
sizeof(llop), f);
4680 if (f->se == NULL) {
4682 fuse_lib_help_modules();
4686 fuse_session_add_chan(f->se, ch);
4688 if (f->conf.debug) {
4689 fprintf(stderr,
"nullpath_ok: %i\n", f->nullpath_ok);
4690 fprintf(stderr,
"nopath: %i\n", f->conf.nopath);
4691 fprintf(stderr,
"utime_omit_ok: %i\n", f->utime_omit_ok);
4695 f->fs->debug = f->conf.debug;
4698 if (node_table_init(&f->name_table) == -1)
4699 goto out_free_session;
4701 if (node_table_init(&f->id_table) == -1)
4702 goto out_free_name_table;
4704 fuse_mutex_init(&f->lock);
4706 root = alloc_node(f);
4708 fprintf(stderr,
"fuse: memory allocation failed\n");
4709 goto out_free_id_table;
4711 if (lru_enabled(f)) {
4712 struct node_lru *lnode = node_lru(root);
4713 init_list_head(&lnode->lru);
4716 strcpy(root->inline_name,
"/");
4717 root->name = root->inline_name;
4720 fuse_init_intr_signal(f->conf.intr_signal,
4721 &f->intr_installed) == -1)
4724 root->parent = NULL;
4734 free(f->id_table.array);
4735 out_free_name_table:
4736 free(f->name_table.array);
4742 fs->op.destroy = NULL;
4743 fuse_fs_destroy(f->fs);
4744 free(f->conf.modules);
4747 out_delete_context_key:
4748 fuse_delete_context_key();
4757 return fuse_new_common(ch, args, op, op_size, user_data, 0);
4764 if (f->conf.intr && f->intr_installed)
4765 fuse_restore_intr_signal(f->conf.intr_signal);
4768 struct fuse_context_i *c = fuse_get_context_internal();
4770 memset(c, 0,
sizeof(*c));
4773 for (i = 0; i < f->id_table.size; i++) {
4776 for (node = f->id_table.array[i]; node != NULL;
4777 node = node->id_next) {
4778 if (node->is_hidden) {
4780 if (try_get_path(f, node->nodeid, NULL, &path, NULL,
false) == 0) {
4781 fuse_fs_unlink(f->fs, path);
4788 for (i = 0; i < f->id_table.size; i++) {
4792 for (node = f->id_table.array[i]; node != NULL; node = next) {
4793 next = node->id_next;
4798 assert(list_empty(&f->partial_slabs));
4799 assert(list_empty(&f->full_slabs));
4801 free(f->id_table.array);
4802 free(f->name_table.array);
4803 pthread_mutex_destroy(&f->lock);
4805 free(f->conf.modules);
4807 fuse_delete_context_key();
4810 static struct fuse *fuse_new_common_compat25(
int fd,
struct fuse_args *args,
4812 size_t op_size,
int compat)
4814 struct fuse *f = NULL;
4815 struct fuse_chan *ch = fuse_kern_chan_new(fd);
4818 f = fuse_new_common(ch, args, op, op_size, NULL, compat);
4825 void fuse_register_module(
struct fuse_module *mod)
4828 mod->so = fuse_current_so;
4831 mod->next = fuse_modules;
4835 #if !defined(__FreeBSD__) && !defined(__NetBSD__) 4837 static struct fuse *fuse_new_common_compat(
int fd,
const char *opts,
4839 size_t op_size,
int compat)
4852 f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
4858 struct fuse *fuse_new_compat22(
int fd,
const char *opts,
4859 const struct fuse_operations_compat22 *op,
4862 return fuse_new_common_compat(fd, opts, (
struct fuse_operations *) op,
4866 struct fuse *fuse_new_compat2(
int fd,
const char *opts,
4867 const struct fuse_operations_compat2 *op)
4869 return fuse_new_common_compat(fd, opts, (
struct fuse_operations *) op,
4870 sizeof(
struct fuse_operations_compat2),
4874 struct fuse *fuse_new_compat1(
int fd,
int flags,
4875 const struct fuse_operations_compat1 *op)
4877 const char *opts = NULL;
4878 if (flags & FUSE_DEBUG_COMPAT1)
4880 return fuse_new_common_compat(fd, opts, (
struct fuse_operations *) op,
4881 sizeof(
struct fuse_operations_compat1),
4885 FUSE_SYMVER(
".symver fuse_exited,__fuse_exited@");
4886 FUSE_SYMVER(
".symver fuse_process_cmd,__fuse_process_cmd@");
4887 FUSE_SYMVER(
".symver fuse_read_cmd,__fuse_read_cmd@");
4888 FUSE_SYMVER(
".symver fuse_set_getcontext_func,__fuse_set_getcontext_func@");
4889 FUSE_SYMVER(
".symver fuse_new_compat2,fuse_new@");
4890 FUSE_SYMVER(
".symver fuse_new_compat22,fuse_new@FUSE_2.2");
4894 struct fuse *fuse_new_compat25(
int fd,
struct fuse_args *args,
4895 const struct fuse_operations_compat25 *op,
4898 return fuse_new_common_compat25(fd, args, (
struct fuse_operations *) op,
4902 FUSE_SYMVER(
".symver fuse_new_compat25,fuse_new@FUSE_2.5");
#define FUSE_OPT_KEY_KEEP
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
void fuse_exit(struct fuse *f)
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
#define FUSE_ARGS_INIT(argc, argv)
void fuse_stop_cleanup_thread(struct fuse *fuse)
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
int fuse_reply_write(fuse_req_t req, size_t count)
int fuse_reply_poll(fuse_req_t req, unsigned revents)
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
int fuse_opt_match(const struct fuse_opt opts[], const char *opt)
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
#define FUSE_CAP_POSIX_LOCKS
struct fuse_context * fuse_get_context(void)
int fuse_session_loop(struct fuse_session *se)
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
void fuse_session_reset(struct fuse_session *se)
void fuse_lib_help(struct fuse_args *args)
int fuse_reply_readlink(fuse_req_t req, const char *link)
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
int fuse_reply_err(fuse_req_t req, int err)
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
void * fuse_req_userdata(fuse_req_t req)
enum fuse_buf_flags flags
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
struct fuse_req * fuse_req_t
#define FUSE_CAP_FLOCK_LOCKS
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
#define FUSE_CAP_SPLICE_READ
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
int fuse_loop(struct fuse *f)
void fuse_session_process_buf(struct fuse_session *se, const struct fuse_buf *buf)
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
struct fuse * fuse_new(struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *private_data)
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_bmap(fuse_req_t req, uint64_t idx)
int fuse_interrupted(void)
void fuse_session_destroy(struct fuse_session *se)
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_getgroups(int size, gid_t list[])
void fuse_session_exit(struct fuse_session *se)
int fuse_req_interrupted(fuse_req_t req)
#define FUSE_CAP_EXPORT_SUPPORT
void fuse_destroy(struct fuse *f)
struct fuse_session * fuse_get_session(struct fuse *f)
void fuse_reply_none(fuse_req_t req)
int fuse_clean_cache(struct fuse *fuse)
int fuse_start_cleanup_thread(struct fuse *fuse)
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
void(* init)(void *userdata, struct fuse_conn_info *conn)
int fuse_session_exited(struct fuse_session *se)
void fuse_opt_free_args(struct fuse_args *args)
#define FUSE_OPT_KEY(templ, key)
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
int fuse_reply_xattr(fuse_req_t req, size_t count)