libfuse
fuse.c
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of the high-level FUSE API on top of the low-level
6  API.
7 
8  This program can be distributed under the terms of the GNU LGPLv2.
9  See the file COPYING.LIB
10 */
11 
12 
13 /* For pthread_rwlock_t */
14 #define _GNU_SOURCE
15 
16 #include "config.h"
17 #include "fuse_i.h"
18 #include "fuse_lowlevel.h"
19 #include "fuse_opt.h"
20 #include "fuse_misc.h"
21 #include "fuse_kernel.h"
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stddef.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <time.h>
30 #include <fcntl.h>
31 #include <limits.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <dlfcn.h>
35 #include <assert.h>
36 #include <poll.h>
37 #include <sys/param.h>
38 #include <sys/uio.h>
39 #include <sys/time.h>
40 #include <sys/mman.h>
41 #include <sys/file.h>
42 
43 #define FUSE_NODE_SLAB 1
44 
45 #ifndef MAP_ANONYMOUS
46 #undef FUSE_NODE_SLAB
47 #endif
48 
49 #ifndef RENAME_EXCHANGE
50 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
51 #endif
52 
53 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
54 
55 #define FUSE_UNKNOWN_INO 0xffffffff
56 #define OFFSET_MAX 0x7fffffffffffffffLL
57 
58 #define NODE_TABLE_MIN_SIZE 8192
59 
60 struct fuse_fs {
61  struct fuse_operations op;
62  struct fuse_module *m;
63  void *user_data;
64  int debug;
65 };
66 
67 struct fusemod_so {
68  void *handle;
69  int ctr;
70 };
71 
72 struct lock_queue_element {
73  struct lock_queue_element *next;
74  pthread_cond_t cond;
75  fuse_ino_t nodeid1;
76  const char *name1;
77  char **path1;
78  struct node **wnode1;
79  fuse_ino_t nodeid2;
80  const char *name2;
81  char **path2;
82  struct node **wnode2;
83  int err;
84  bool first_locked : 1;
85  bool second_locked : 1;
86  bool done : 1;
87 };
88 
89 struct node_table {
90  struct node **array;
91  size_t use;
92  size_t size;
93  size_t split;
94 };
95 
96 #define container_of(ptr, type, member) ({ \
97  const typeof( ((type *)0)->member ) *__mptr = (ptr); \
98  (type *)( (char *)__mptr - offsetof(type,member) );})
99 
100 #define list_entry(ptr, type, member) \
101  container_of(ptr, type, member)
102 
103 struct list_head {
104  struct list_head *next;
105  struct list_head *prev;
106 };
107 
108 struct node_slab {
109  struct list_head list; /* must be the first member */
110  struct list_head freelist;
111  int used;
112 };
113 
114 struct fuse {
115  struct fuse_session *se;
116  struct node_table name_table;
117  struct node_table id_table;
118  struct list_head lru_table;
119  fuse_ino_t ctr;
120  unsigned int generation;
121  unsigned int hidectr;
122  pthread_mutex_t lock;
123  struct fuse_config conf;
124  int intr_installed;
125  struct fuse_fs *fs;
126  struct lock_queue_element *lockq;
127  int pagesize;
128  struct list_head partial_slabs;
129  struct list_head full_slabs;
130  pthread_t prune_thread;
131 };
132 
133 struct lock {
134  int type;
135  off_t start;
136  off_t end;
137  pid_t pid;
138  uint64_t owner;
139  struct lock *next;
140 };
141 
142 struct node {
143  struct node *name_next;
144  struct node *id_next;
145  fuse_ino_t nodeid;
146  unsigned int generation;
147  int refctr;
148  struct node *parent;
149  char *name;
150  uint64_t nlookup;
151  int open_count;
152  struct timespec stat_updated;
153  struct timespec mtime;
154  off_t size;
155  struct lock *locks;
156  unsigned int is_hidden : 1;
157  unsigned int cache_valid : 1;
158  int treelock;
159  char inline_name[32];
160 };
161 
162 #define TREELOCK_WRITE -1
163 #define TREELOCK_WAIT_OFFSET INT_MIN
164 
165 struct node_lru {
166  struct node node;
167  struct list_head lru;
168  struct timespec forget_time;
169 };
170 
171 struct fuse_direntry {
172  struct stat stat;
173  char *name;
174  struct fuse_direntry *next;
175 };
176 
177 struct fuse_dh {
178  pthread_mutex_t lock;
179  struct fuse *fuse;
180  fuse_req_t req;
181  char *contents;
182  struct fuse_direntry *first;
183  struct fuse_direntry **last;
184  unsigned len;
185  unsigned size;
186  unsigned needlen;
187  int filled;
188  uint64_t fh;
189  int error;
190  fuse_ino_t nodeid;
191 };
192 
193 struct fuse_context_i {
194  struct fuse_context ctx;
195  fuse_req_t req;
196 };
197 
198 /* Defined by FUSE_REGISTER_MODULE() in lib/modules/subdir.c and iconv.c. */
199 extern fuse_module_factory_t fuse_module_subdir_factory;
200 #ifdef HAVE_ICONV
201 extern fuse_module_factory_t fuse_module_iconv_factory;
202 #endif
203 
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;
207 static struct fuse_module *fuse_modules = NULL;
208 
209 static int fuse_register_module(const char *name,
210  fuse_module_factory_t factory,
211  struct fusemod_so *so)
212 {
213  struct fuse_module *mod;
214 
215  mod = calloc(1, sizeof(struct fuse_module));
216  if (!mod) {
217  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate module\n");
218  return -1;
219  }
220  mod->name = strdup(name);
221  if (!mod->name) {
222  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate module name\n");
223  free(mod);
224  return -1;
225  }
226  mod->factory = factory;
227  mod->ctr = 0;
228  mod->so = so;
229  if (mod->so)
230  mod->so->ctr++;
231  mod->next = fuse_modules;
232  fuse_modules = mod;
233 
234  return 0;
235 }
236 
237 static void fuse_unregister_module(struct fuse_module *m)
238 {
239  struct fuse_module **mp;
240  for (mp = &fuse_modules; *mp; mp = &(*mp)->next) {
241  if (*mp == m) {
242  *mp = (*mp)->next;
243  break;
244  }
245  }
246  free(m->name);
247  free(m);
248 }
249 
250 static int fuse_load_so_module(const char *module)
251 {
252  int ret = -1;
253  char *tmp;
254  struct fusemod_so *so;
255  fuse_module_factory_t factory;
256 
257  tmp = malloc(strlen(module) + 64);
258  if (!tmp) {
259  fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
260  return -1;
261  }
262  sprintf(tmp, "libfusemod_%s.so", module);
263  so = calloc(1, sizeof(struct fusemod_so));
264  if (!so) {
265  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate module so\n");
266  goto out;
267  }
268 
269  so->handle = dlopen(tmp, RTLD_NOW);
270  if (so->handle == NULL) {
271  fuse_log(FUSE_LOG_ERR, "fuse: dlopen(%s) failed: %s\n",
272  tmp, dlerror());
273  goto out_free_so;
274  }
275 
276  sprintf(tmp, "fuse_module_%s_factory", module);
277  *(void**)(&factory) = dlsym(so->handle, tmp);
278  if (factory == NULL) {
279  fuse_log(FUSE_LOG_ERR, "fuse: symbol <%s> not found in module: %s\n",
280  tmp, dlerror());
281  goto out_dlclose;
282  }
283  ret = fuse_register_module(module, factory, so);
284  if (ret)
285  goto out_dlclose;
286 
287 out:
288  free(tmp);
289  return ret;
290 
291 out_dlclose:
292  dlclose(so->handle);
293 out_free_so:
294  free(so);
295  goto out;
296 }
297 
298 static struct fuse_module *fuse_find_module(const char *module)
299 {
300  struct fuse_module *m;
301  for (m = fuse_modules; m; m = m->next) {
302  if (strcmp(module, m->name) == 0) {
303  m->ctr++;
304  break;
305  }
306  }
307  return m;
308 }
309 
310 static struct fuse_module *fuse_get_module(const char *module)
311 {
312  struct fuse_module *m;
313 
314  pthread_mutex_lock(&fuse_context_lock);
315  m = fuse_find_module(module);
316  if (!m) {
317  int err = fuse_load_so_module(module);
318  if (!err)
319  m = fuse_find_module(module);
320  }
321  pthread_mutex_unlock(&fuse_context_lock);
322  return m;
323 }
324 
325 static void fuse_put_module(struct fuse_module *m)
326 {
327  pthread_mutex_lock(&fuse_context_lock);
328  if (m->so)
329  assert(m->ctr > 0);
330  /* Builtin modules may already have m->ctr == 0 */
331  if (m->ctr > 0)
332  m->ctr--;
333  if (!m->ctr && m->so) {
334  struct fusemod_so *so = m->so;
335  assert(so->ctr > 0);
336  so->ctr--;
337  if (!so->ctr) {
338  struct fuse_module **mp;
339  for (mp = &fuse_modules; *mp;) {
340  if ((*mp)->so == so)
341  fuse_unregister_module(*mp);
342  else
343  mp = &(*mp)->next;
344  }
345  dlclose(so->handle);
346  free(so);
347  }
348  } else if (!m->ctr) {
349  fuse_unregister_module(m);
350  }
351  pthread_mutex_unlock(&fuse_context_lock);
352 }
353 
354 static void init_list_head(struct list_head *list)
355 {
356  list->next = list;
357  list->prev = list;
358 }
359 
360 static int list_empty(const struct list_head *head)
361 {
362  return head->next == head;
363 }
364 
365 static void list_add(struct list_head *new, struct list_head *prev,
366  struct list_head *next)
367 {
368  next->prev = new;
369  new->next = next;
370  new->prev = prev;
371  prev->next = new;
372 }
373 
374 static inline void list_add_head(struct list_head *new, struct list_head *head)
375 {
376  list_add(new, head, head->next);
377 }
378 
379 static inline void list_add_tail(struct list_head *new, struct list_head *head)
380 {
381  list_add(new, head->prev, head);
382 }
383 
384 static inline void list_del(struct list_head *entry)
385 {
386  struct list_head *prev = entry->prev;
387  struct list_head *next = entry->next;
388 
389  next->prev = prev;
390  prev->next = next;
391 }
392 
393 static inline int lru_enabled(struct fuse *f)
394 {
395  return f->conf.remember > 0;
396 }
397 
398 static struct node_lru *node_lru(struct node *node)
399 {
400  return (struct node_lru *) node;
401 }
402 
403 static size_t get_node_size(struct fuse *f)
404 {
405  if (lru_enabled(f))
406  return sizeof(struct node_lru);
407  else
408  return sizeof(struct node);
409 }
410 
411 #ifdef FUSE_NODE_SLAB
412 static struct node_slab *list_to_slab(struct list_head *head)
413 {
414  return (struct node_slab *) head;
415 }
416 
417 static struct node_slab *node_to_slab(struct fuse *f, struct node *node)
418 {
419  return (struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
420 }
421 
422 static int alloc_slab(struct fuse *f)
423 {
424  void *mem;
425  struct node_slab *slab;
426  char *start;
427  size_t num;
428  size_t i;
429  size_t node_size = get_node_size(f);
430 
431  mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
432  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
433 
434  if (mem == MAP_FAILED)
435  return -1;
436 
437  slab = mem;
438  init_list_head(&slab->freelist);
439  slab->used = 0;
440  num = (f->pagesize - sizeof(struct node_slab)) / node_size;
441 
442  start = (char *) mem + f->pagesize - num * node_size;
443  for (i = 0; i < num; i++) {
444  struct list_head *n;
445 
446  n = (struct list_head *) (start + i * node_size);
447  list_add_tail(n, &slab->freelist);
448  }
449  list_add_tail(&slab->list, &f->partial_slabs);
450 
451  return 0;
452 }
453 
454 static struct node *alloc_node(struct fuse *f)
455 {
456  struct node_slab *slab;
457  struct list_head *node;
458 
459  if (list_empty(&f->partial_slabs)) {
460  int res = alloc_slab(f);
461  if (res != 0)
462  return NULL;
463  }
464  slab = list_to_slab(f->partial_slabs.next);
465  slab->used++;
466  node = slab->freelist.next;
467  list_del(node);
468  if (list_empty(&slab->freelist)) {
469  list_del(&slab->list);
470  list_add_tail(&slab->list, &f->full_slabs);
471  }
472  memset(node, 0, sizeof(struct node));
473 
474  return (struct node *) node;
475 }
476 
477 static void free_slab(struct fuse *f, struct node_slab *slab)
478 {
479  int res;
480 
481  list_del(&slab->list);
482  res = munmap(slab, f->pagesize);
483  if (res == -1)
484  fuse_log(FUSE_LOG_WARNING, "fuse warning: munmap(%p) failed\n",
485  slab);
486 }
487 
488 static void free_node_mem(struct fuse *f, struct node *node)
489 {
490  struct node_slab *slab = node_to_slab(f, node);
491  struct list_head *n = (struct list_head *) node;
492 
493  slab->used--;
494  if (slab->used) {
495  if (list_empty(&slab->freelist)) {
496  list_del(&slab->list);
497  list_add_tail(&slab->list, &f->partial_slabs);
498  }
499  list_add_head(n, &slab->freelist);
500  } else {
501  free_slab(f, slab);
502  }
503 }
504 #else
505 static struct node *alloc_node(struct fuse *f)
506 {
507  return (struct node *) calloc(1, get_node_size(f));
508 }
509 
510 static void free_node_mem(struct fuse *f, struct node *node)
511 {
512  (void) f;
513  free(node);
514 }
515 #endif
516 
517 static size_t id_hash(struct fuse *f, fuse_ino_t ino)
518 {
519  uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
520  uint64_t oldhash = hash % (f->id_table.size / 2);
521 
522  if (oldhash >= f->id_table.split)
523  return oldhash;
524  else
525  return hash;
526 }
527 
528 static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
529 {
530  size_t hash = id_hash(f, nodeid);
531  struct node *node;
532 
533  for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
534  if (node->nodeid == nodeid)
535  return node;
536 
537  return NULL;
538 }
539 
540 static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
541 {
542  struct node *node = get_node_nocheck(f, nodeid);
543  if (!node) {
544  fuse_log(FUSE_LOG_ERR, "fuse internal error: node %llu not found\n",
545  (unsigned long long) nodeid);
546  abort();
547  }
548  return node;
549 }
550 
551 static void curr_time(struct timespec *now);
552 static double diff_timespec(const struct timespec *t1,
553  const struct timespec *t2);
554 
555 static void remove_node_lru(struct node *node)
556 {
557  struct node_lru *lnode = node_lru(node);
558  list_del(&lnode->lru);
559  init_list_head(&lnode->lru);
560 }
561 
562 static void set_forget_time(struct fuse *f, struct node *node)
563 {
564  struct node_lru *lnode = node_lru(node);
565 
566  list_del(&lnode->lru);
567  list_add_tail(&lnode->lru, &f->lru_table);
568  curr_time(&lnode->forget_time);
569 }
570 
571 static void free_node(struct fuse *f, struct node *node)
572 {
573  if (node->name != node->inline_name)
574  free(node->name);
575  free_node_mem(f, node);
576 }
577 
578 static void node_table_reduce(struct node_table *t)
579 {
580  size_t newsize = t->size / 2;
581  void *newarray;
582 
583  if (newsize < NODE_TABLE_MIN_SIZE)
584  return;
585 
586  newarray = realloc(t->array, sizeof(struct node *) * newsize);
587  if (newarray != NULL)
588  t->array = newarray;
589 
590  t->size = newsize;
591  t->split = t->size / 2;
592 }
593 
594 static void remerge_id(struct fuse *f)
595 {
596  struct node_table *t = &f->id_table;
597  int iter;
598 
599  if (t->split == 0)
600  node_table_reduce(t);
601 
602  for (iter = 8; t->split > 0 && iter; iter--) {
603  struct node **upper;
604 
605  t->split--;
606  upper = &t->array[t->split + t->size / 2];
607  if (*upper) {
608  struct node **nodep;
609 
610  for (nodep = &t->array[t->split]; *nodep;
611  nodep = &(*nodep)->id_next);
612 
613  *nodep = *upper;
614  *upper = NULL;
615  break;
616  }
617  }
618 }
619 
620 static void unhash_id(struct fuse *f, struct node *node)
621 {
622  struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
623 
624  for (; *nodep != NULL; nodep = &(*nodep)->id_next)
625  if (*nodep == node) {
626  *nodep = node->id_next;
627  f->id_table.use--;
628 
629  if(f->id_table.use < f->id_table.size / 4)
630  remerge_id(f);
631  return;
632  }
633 }
634 
635 static int node_table_resize(struct node_table *t)
636 {
637  size_t newsize = t->size * 2;
638  void *newarray;
639 
640  newarray = realloc(t->array, sizeof(struct node *) * newsize);
641  if (newarray == NULL)
642  return -1;
643 
644  t->array = newarray;
645  memset(t->array + t->size, 0, t->size * sizeof(struct node *));
646  t->size = newsize;
647  t->split = 0;
648 
649  return 0;
650 }
651 
652 static void rehash_id(struct fuse *f)
653 {
654  struct node_table *t = &f->id_table;
655  struct node **nodep;
656  struct node **next;
657  size_t hash;
658 
659  if (t->split == t->size / 2)
660  return;
661 
662  hash = t->split;
663  t->split++;
664  for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
665  struct node *node = *nodep;
666  size_t newhash = id_hash(f, node->nodeid);
667 
668  if (newhash != hash) {
669  next = nodep;
670  *nodep = node->id_next;
671  node->id_next = t->array[newhash];
672  t->array[newhash] = node;
673  } else {
674  next = &node->id_next;
675  }
676  }
677  if (t->split == t->size / 2)
678  node_table_resize(t);
679 }
680 
681 static void hash_id(struct fuse *f, struct node *node)
682 {
683  size_t hash = id_hash(f, node->nodeid);
684  node->id_next = f->id_table.array[hash];
685  f->id_table.array[hash] = node;
686  f->id_table.use++;
687 
688  if (f->id_table.use >= f->id_table.size / 2)
689  rehash_id(f);
690 }
691 
692 static size_t name_hash(struct fuse *f, fuse_ino_t parent,
693  const char *name)
694 {
695  uint64_t hash = parent;
696  uint64_t oldhash;
697 
698  for (; *name; name++)
699  hash = hash * 31 + (unsigned char) *name;
700 
701  hash %= f->name_table.size;
702  oldhash = hash % (f->name_table.size / 2);
703  if (oldhash >= f->name_table.split)
704  return oldhash;
705  else
706  return hash;
707 }
708 
709 static void unref_node(struct fuse *f, struct node *node);
710 
711 static void remerge_name(struct fuse *f)
712 {
713  struct node_table *t = &f->name_table;
714  int iter;
715 
716  if (t->split == 0)
717  node_table_reduce(t);
718 
719  for (iter = 8; t->split > 0 && iter; iter--) {
720  struct node **upper;
721 
722  t->split--;
723  upper = &t->array[t->split + t->size / 2];
724  if (*upper) {
725  struct node **nodep;
726 
727  for (nodep = &t->array[t->split]; *nodep;
728  nodep = &(*nodep)->name_next);
729 
730  *nodep = *upper;
731  *upper = NULL;
732  break;
733  }
734  }
735 }
736 
737 static void unhash_name(struct fuse *f, struct node *node)
738 {
739  if (node->name) {
740  size_t hash = name_hash(f, node->parent->nodeid, node->name);
741  struct node **nodep = &f->name_table.array[hash];
742 
743  for (; *nodep != NULL; nodep = &(*nodep)->name_next)
744  if (*nodep == node) {
745  *nodep = node->name_next;
746  node->name_next = NULL;
747  unref_node(f, node->parent);
748  if (node->name != node->inline_name)
749  free(node->name);
750  node->name = NULL;
751  node->parent = NULL;
752  f->name_table.use--;
753 
754  if (f->name_table.use < f->name_table.size / 4)
755  remerge_name(f);
756  return;
757  }
758  fuse_log(FUSE_LOG_ERR,
759  "fuse internal error: unable to unhash node: %llu\n",
760  (unsigned long long) node->nodeid);
761  abort();
762  }
763 }
764 
765 static void rehash_name(struct fuse *f)
766 {
767  struct node_table *t = &f->name_table;
768  struct node **nodep;
769  struct node **next;
770  size_t hash;
771 
772  if (t->split == t->size / 2)
773  return;
774 
775  hash = t->split;
776  t->split++;
777  for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
778  struct node *node = *nodep;
779  size_t newhash = name_hash(f, node->parent->nodeid, node->name);
780 
781  if (newhash != hash) {
782  next = nodep;
783  *nodep = node->name_next;
784  node->name_next = t->array[newhash];
785  t->array[newhash] = node;
786  } else {
787  next = &node->name_next;
788  }
789  }
790  if (t->split == t->size / 2)
791  node_table_resize(t);
792 }
793 
794 static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
795  const char *name)
796 {
797  size_t hash = name_hash(f, parentid, name);
798  struct node *parent = get_node(f, parentid);
799  if (strlen(name) < sizeof(node->inline_name)) {
800  strcpy(node->inline_name, name);
801  node->name = node->inline_name;
802  } else {
803  node->name = strdup(name);
804  if (node->name == NULL)
805  return -1;
806  }
807 
808  parent->refctr ++;
809  node->parent = parent;
810  node->name_next = f->name_table.array[hash];
811  f->name_table.array[hash] = node;
812  f->name_table.use++;
813 
814  if (f->name_table.use >= f->name_table.size / 2)
815  rehash_name(f);
816 
817  return 0;
818 }
819 
820 static void delete_node(struct fuse *f, struct node *node)
821 {
822  if (f->conf.debug)
823  fuse_log(FUSE_LOG_DEBUG, "DELETE: %llu\n",
824  (unsigned long long) node->nodeid);
825 
826  assert(node->treelock == 0);
827  unhash_name(f, node);
828  if (lru_enabled(f))
829  remove_node_lru(node);
830  unhash_id(f, node);
831  free_node(f, node);
832 }
833 
834 static void unref_node(struct fuse *f, struct node *node)
835 {
836  assert(node->refctr > 0);
837  node->refctr --;
838  if (!node->refctr)
839  delete_node(f, node);
840 }
841 
842 static fuse_ino_t next_id(struct fuse *f)
843 {
844  do {
845  f->ctr = (f->ctr + 1) & 0xffffffff;
846  if (!f->ctr)
847  f->generation ++;
848  } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
849  get_node_nocheck(f, f->ctr) != NULL);
850  return f->ctr;
851 }
852 
853 static struct node *lookup_node(struct fuse *f, fuse_ino_t parent,
854  const char *name)
855 {
856  size_t hash = name_hash(f, parent, name);
857  struct node *node;
858 
859  for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
860  if (node->parent->nodeid == parent &&
861  strcmp(node->name, name) == 0)
862  return node;
863 
864  return NULL;
865 }
866 
867 static void inc_nlookup(struct node *node)
868 {
869  if (!node->nlookup)
870  node->refctr++;
871  node->nlookup++;
872 }
873 
874 static struct node *find_node(struct fuse *f, fuse_ino_t parent,
875  const char *name)
876 {
877  struct node *node;
878 
879  pthread_mutex_lock(&f->lock);
880  if (!name)
881  node = get_node(f, parent);
882  else
883  node = lookup_node(f, parent, name);
884  if (node == NULL) {
885  node = alloc_node(f);
886  if (node == NULL)
887  goto out_err;
888 
889  node->nodeid = next_id(f);
890  node->generation = f->generation;
891  if (f->conf.remember)
892  inc_nlookup(node);
893 
894  if (hash_name(f, node, parent, name) == -1) {
895  free_node(f, node);
896  node = NULL;
897  goto out_err;
898  }
899  hash_id(f, node);
900  if (lru_enabled(f)) {
901  struct node_lru *lnode = node_lru(node);
902  init_list_head(&lnode->lru);
903  }
904  } else if (lru_enabled(f) && node->nlookup == 1) {
905  remove_node_lru(node);
906  }
907  inc_nlookup(node);
908 out_err:
909  pthread_mutex_unlock(&f->lock);
910  return node;
911 }
912 
913 static int lookup_path_in_cache(struct fuse *f,
914  const char *path, fuse_ino_t *inop)
915 {
916  char *tmp = strdup(path);
917  if (!tmp)
918  return -ENOMEM;
919 
920  pthread_mutex_lock(&f->lock);
921  fuse_ino_t ino = FUSE_ROOT_ID;
922 
923  int err = 0;
924  char *save_ptr;
925  char *path_element = strtok_r(tmp, "/", &save_ptr);
926  while (path_element != NULL) {
927  struct node *node = lookup_node(f, ino, path_element);
928  if (node == NULL) {
929  err = -ENOENT;
930  break;
931  }
932  ino = node->nodeid;
933  path_element = strtok_r(NULL, "/", &save_ptr);
934  }
935  pthread_mutex_unlock(&f->lock);
936  free(tmp);
937 
938  if (!err)
939  *inop = ino;
940  return err;
941 }
942 
943 static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
944 {
945  size_t len = strlen(name);
946 
947  if (s - len <= *buf) {
948  unsigned pathlen = *bufsize - (s - *buf);
949  unsigned newbufsize = *bufsize;
950  char *newbuf;
951 
952  while (newbufsize < pathlen + len + 1) {
953  if (newbufsize >= 0x80000000)
954  newbufsize = 0xffffffff;
955  else
956  newbufsize *= 2;
957  }
958 
959  newbuf = realloc(*buf, newbufsize);
960  if (newbuf == NULL)
961  return NULL;
962 
963  *buf = newbuf;
964  s = newbuf + newbufsize - pathlen;
965  memmove(s, newbuf + *bufsize - pathlen, pathlen);
966  *bufsize = newbufsize;
967  }
968  s -= len;
969  memcpy(s, name, len);
970  s--;
971  *s = '/';
972 
973  return s;
974 }
975 
976 static void unlock_path(struct fuse *f, fuse_ino_t nodeid, struct node *wnode,
977  struct node *end)
978 {
979  struct node *node;
980 
981  if (wnode) {
982  assert(wnode->treelock == TREELOCK_WRITE);
983  wnode->treelock = 0;
984  }
985 
986  for (node = get_node(f, nodeid);
987  node != end && node->nodeid != FUSE_ROOT_ID; node = node->parent) {
988  assert(node->treelock != 0);
989  assert(node->treelock != TREELOCK_WAIT_OFFSET);
990  assert(node->treelock != TREELOCK_WRITE);
991  node->treelock--;
992  if (node->treelock == TREELOCK_WAIT_OFFSET)
993  node->treelock = 0;
994  }
995 }
996 
997 static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
998  char **path, struct node **wnodep, bool need_lock)
999 {
1000  unsigned bufsize = 256;
1001  char *buf;
1002  char *s;
1003  struct node *node;
1004  struct node *wnode = NULL;
1005  int err;
1006 
1007  *path = NULL;
1008 
1009  err = -ENOMEM;
1010  buf = malloc(bufsize);
1011  if (buf == NULL)
1012  goto out_err;
1013 
1014  s = buf + bufsize - 1;
1015  *s = '\0';
1016 
1017  if (name != NULL) {
1018  s = add_name(&buf, &bufsize, s, name);
1019  err = -ENOMEM;
1020  if (s == NULL)
1021  goto out_free;
1022  }
1023 
1024  if (wnodep) {
1025  assert(need_lock);
1026  wnode = lookup_node(f, nodeid, name);
1027  if (wnode) {
1028  if (wnode->treelock != 0) {
1029  if (wnode->treelock > 0)
1030  wnode->treelock += TREELOCK_WAIT_OFFSET;
1031  err = -EAGAIN;
1032  goto out_free;
1033  }
1034  wnode->treelock = TREELOCK_WRITE;
1035  }
1036  }
1037 
1038  for (node = get_node(f, nodeid); node->nodeid != FUSE_ROOT_ID;
1039  node = node->parent) {
1040  err = -ENOENT;
1041  if (node->name == NULL || node->parent == NULL)
1042  goto out_unlock;
1043 
1044  err = -ENOMEM;
1045  s = add_name(&buf, &bufsize, s, node->name);
1046  if (s == NULL)
1047  goto out_unlock;
1048 
1049  if (need_lock) {
1050  err = -EAGAIN;
1051  if (node->treelock < 0)
1052  goto out_unlock;
1053 
1054  node->treelock++;
1055  }
1056  }
1057 
1058  if (s[0])
1059  memmove(buf, s, bufsize - (s - buf));
1060  else
1061  strcpy(buf, "/");
1062 
1063  *path = buf;
1064  if (wnodep)
1065  *wnodep = wnode;
1066 
1067  return 0;
1068 
1069  out_unlock:
1070  if (need_lock)
1071  unlock_path(f, nodeid, wnode, node);
1072  out_free:
1073  free(buf);
1074 
1075  out_err:
1076  return err;
1077 }
1078 
1079 static void queue_element_unlock(struct fuse *f, struct lock_queue_element *qe)
1080 {
1081  struct node *wnode;
1082 
1083  if (qe->first_locked) {
1084  wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1085  unlock_path(f, qe->nodeid1, wnode, NULL);
1086  qe->first_locked = false;
1087  }
1088  if (qe->second_locked) {
1089  wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1090  unlock_path(f, qe->nodeid2, wnode, NULL);
1091  qe->second_locked = false;
1092  }
1093 }
1094 
1095 static void queue_element_wakeup(struct fuse *f, struct lock_queue_element *qe)
1096 {
1097  int err;
1098  bool first = (qe == f->lockq);
1099 
1100  if (!qe->path1) {
1101  /* Just waiting for it to be unlocked */
1102  if (get_node(f, qe->nodeid1)->treelock == 0)
1103  pthread_cond_signal(&qe->cond);
1104 
1105  return;
1106  }
1107 
1108  if (!qe->first_locked) {
1109  err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1110  qe->wnode1, true);
1111  if (!err)
1112  qe->first_locked = true;
1113  else if (err != -EAGAIN)
1114  goto err_unlock;
1115  }
1116  if (!qe->second_locked && qe->path2) {
1117  err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1118  qe->wnode2, true);
1119  if (!err)
1120  qe->second_locked = true;
1121  else if (err != -EAGAIN)
1122  goto err_unlock;
1123  }
1124 
1125  if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1126  err = 0;
1127  goto done;
1128  }
1129 
1130  /*
1131  * Only let the first element be partially locked otherwise there could
1132  * be a deadlock.
1133  *
1134  * But do allow the first element to be partially locked to prevent
1135  * starvation.
1136  */
1137  if (!first)
1138  queue_element_unlock(f, qe);
1139 
1140  /* keep trying */
1141  return;
1142 
1143 err_unlock:
1144  queue_element_unlock(f, qe);
1145 done:
1146  qe->err = err;
1147  qe->done = true;
1148  pthread_cond_signal(&qe->cond);
1149 }
1150 
1151 static void wake_up_queued(struct fuse *f)
1152 {
1153  struct lock_queue_element *qe;
1154 
1155  for (qe = f->lockq; qe != NULL; qe = qe->next)
1156  queue_element_wakeup(f, qe);
1157 }
1158 
1159 static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid,
1160  const char *name, bool wr)
1161 {
1162  if (f->conf.debug) {
1163  struct node *wnode = NULL;
1164 
1165  if (wr)
1166  wnode = lookup_node(f, nodeid, name);
1167 
1168  if (wnode) {
1169  fuse_log(FUSE_LOG_DEBUG, "%s %llu (w)\n",
1170  msg, (unsigned long long) wnode->nodeid);
1171  } else {
1172  fuse_log(FUSE_LOG_DEBUG, "%s %llu\n",
1173  msg, (unsigned long long) nodeid);
1174  }
1175  }
1176 }
1177 
1178 static void queue_path(struct fuse *f, struct lock_queue_element *qe)
1179 {
1180  struct lock_queue_element **qp;
1181 
1182  qe->done = false;
1183  qe->first_locked = false;
1184  qe->second_locked = false;
1185  pthread_cond_init(&qe->cond, NULL);
1186  qe->next = NULL;
1187  for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1188  *qp = qe;
1189 }
1190 
1191 static void dequeue_path(struct fuse *f, struct lock_queue_element *qe)
1192 {
1193  struct lock_queue_element **qp;
1194 
1195  pthread_cond_destroy(&qe->cond);
1196  for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1197  *qp = qe->next;
1198 }
1199 
1200 static int wait_path(struct fuse *f, struct lock_queue_element *qe)
1201 {
1202  queue_path(f, qe);
1203 
1204  do {
1205  pthread_cond_wait(&qe->cond, &f->lock);
1206  } while (!qe->done);
1207 
1208  dequeue_path(f, qe);
1209 
1210  return qe->err;
1211 }
1212 
1213 static int get_path_common(struct fuse *f, fuse_ino_t nodeid, const char *name,
1214  char **path, struct node **wnode)
1215 {
1216  int err;
1217 
1218  pthread_mutex_lock(&f->lock);
1219  err = try_get_path(f, nodeid, name, path, wnode, true);
1220  if (err == -EAGAIN) {
1221  struct lock_queue_element qe = {
1222  .nodeid1 = nodeid,
1223  .name1 = name,
1224  .path1 = path,
1225  .wnode1 = wnode,
1226  };
1227  debug_path(f, "QUEUE PATH", nodeid, name, !!wnode);
1228  err = wait_path(f, &qe);
1229  debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode);
1230  }
1231  pthread_mutex_unlock(&f->lock);
1232 
1233  return err;
1234 }
1235 
1236 static int get_path(struct fuse *f, fuse_ino_t nodeid, char **path)
1237 {
1238  return get_path_common(f, nodeid, NULL, path, NULL);
1239 }
1240 
1241 static int get_path_nullok(struct fuse *f, fuse_ino_t nodeid, char **path)
1242 {
1243  int err = 0;
1244 
1245  if (f->conf.nullpath_ok) {
1246  *path = NULL;
1247  } else {
1248  err = get_path_common(f, nodeid, NULL, path, NULL);
1249  if (err == -ENOENT)
1250  err = 0;
1251  }
1252 
1253  return err;
1254 }
1255 
1256 static int get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name,
1257  char **path)
1258 {
1259  return get_path_common(f, nodeid, name, path, NULL);
1260 }
1261 
1262 static int get_path_wrlock(struct fuse *f, fuse_ino_t nodeid, const char *name,
1263  char **path, struct node **wnode)
1264 {
1265  return get_path_common(f, nodeid, name, path, wnode);
1266 }
1267 
1268 #if defined(__FreeBSD__)
1269 #define CHECK_DIR_LOOP
1270 #endif
1271 
1272 #if defined(CHECK_DIR_LOOP)
1273 static int check_dir_loop(struct fuse *f,
1274  fuse_ino_t nodeid1, const char *name1,
1275  fuse_ino_t nodeid2, const char *name2)
1276 {
1277  struct node *node, *node1, *node2;
1278  fuse_ino_t id1, id2;
1279 
1280  node1 = lookup_node(f, nodeid1, name1);
1281  id1 = node1 ? node1->nodeid : nodeid1;
1282 
1283  node2 = lookup_node(f, nodeid2, name2);
1284  id2 = node2 ? node2->nodeid : nodeid2;
1285 
1286  for (node = get_node(f, id2); node->nodeid != FUSE_ROOT_ID;
1287  node = node->parent) {
1288  if (node->name == NULL || node->parent == NULL)
1289  break;
1290 
1291  if (node->nodeid != id2 && node->nodeid == id1)
1292  return -EINVAL;
1293  }
1294 
1295  if (node2)
1296  {
1297  for (node = get_node(f, id1); node->nodeid != FUSE_ROOT_ID;
1298  node = node->parent) {
1299  if (node->name == NULL || node->parent == NULL)
1300  break;
1301 
1302  if (node->nodeid != id1 && node->nodeid == id2)
1303  return -ENOTEMPTY;
1304  }
1305  }
1306 
1307  return 0;
1308 }
1309 #endif
1310 
1311 static int try_get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1312  fuse_ino_t nodeid2, const char *name2,
1313  char **path1, char **path2,
1314  struct node **wnode1, struct node **wnode2)
1315 {
1316  int err;
1317 
1318  /* FIXME: locking two paths needs deadlock checking */
1319  err = try_get_path(f, nodeid1, name1, path1, wnode1, true);
1320  if (!err) {
1321  err = try_get_path(f, nodeid2, name2, path2, wnode2, true);
1322  if (err) {
1323  struct node *wn1 = wnode1 ? *wnode1 : NULL;
1324 
1325  unlock_path(f, nodeid1, wn1, NULL);
1326  free(*path1);
1327  }
1328  }
1329  return err;
1330 }
1331 
1332 static int get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1333  fuse_ino_t nodeid2, const char *name2,
1334  char **path1, char **path2,
1335  struct node **wnode1, struct node **wnode2)
1336 {
1337  int err;
1338 
1339  pthread_mutex_lock(&f->lock);
1340 
1341 #if defined(CHECK_DIR_LOOP)
1342  if (name1)
1343  {
1344  // called during rename; perform dir loop check
1345  err = check_dir_loop(f, nodeid1, name1, nodeid2, name2);
1346  if (err)
1347  goto out_unlock;
1348  }
1349 #endif
1350 
1351  err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1352  path1, path2, wnode1, wnode2);
1353  if (err == -EAGAIN) {
1354  struct lock_queue_element qe = {
1355  .nodeid1 = nodeid1,
1356  .name1 = name1,
1357  .path1 = path1,
1358  .wnode1 = wnode1,
1359  .nodeid2 = nodeid2,
1360  .name2 = name2,
1361  .path2 = path2,
1362  .wnode2 = wnode2,
1363  };
1364 
1365  debug_path(f, "QUEUE PATH1", nodeid1, name1, !!wnode1);
1366  debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1367  err = wait_path(f, &qe);
1368  debug_path(f, "DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1369  debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1370  }
1371 
1372 #if defined(CHECK_DIR_LOOP)
1373 out_unlock:
1374 #endif
1375  pthread_mutex_unlock(&f->lock);
1376 
1377  return err;
1378 }
1379 
1380 static void free_path_wrlock(struct fuse *f, fuse_ino_t nodeid,
1381  struct node *wnode, char *path)
1382 {
1383  pthread_mutex_lock(&f->lock);
1384  unlock_path(f, nodeid, wnode, NULL);
1385  if (f->lockq)
1386  wake_up_queued(f);
1387  pthread_mutex_unlock(&f->lock);
1388  free(path);
1389 }
1390 
1391 static void free_path(struct fuse *f, fuse_ino_t nodeid, char *path)
1392 {
1393  if (path)
1394  free_path_wrlock(f, nodeid, NULL, path);
1395 }
1396 
1397 static void free_path2(struct fuse *f, fuse_ino_t nodeid1, fuse_ino_t nodeid2,
1398  struct node *wnode1, struct node *wnode2,
1399  char *path1, char *path2)
1400 {
1401  pthread_mutex_lock(&f->lock);
1402  unlock_path(f, nodeid1, wnode1, NULL);
1403  unlock_path(f, nodeid2, wnode2, NULL);
1404  wake_up_queued(f);
1405  pthread_mutex_unlock(&f->lock);
1406  free(path1);
1407  free(path2);
1408 }
1409 
1410 static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
1411 {
1412  struct node *node;
1413  if (nodeid == FUSE_ROOT_ID)
1414  return;
1415  pthread_mutex_lock(&f->lock);
1416  node = get_node(f, nodeid);
1417 
1418  /*
1419  * Node may still be locked due to interrupt idiocy in open,
1420  * create and opendir
1421  */
1422  while (node->nlookup == nlookup && node->treelock) {
1423  struct lock_queue_element qe = {
1424  .nodeid1 = nodeid,
1425  };
1426 
1427  debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false);
1428  queue_path(f, &qe);
1429 
1430  do {
1431  pthread_cond_wait(&qe.cond, &f->lock);
1432  } while (node->nlookup == nlookup && node->treelock);
1433 
1434  dequeue_path(f, &qe);
1435  debug_path(f, "DEQUEUE_PATH (forget)", nodeid, NULL, false);
1436  }
1437 
1438  assert(node->nlookup >= nlookup);
1439  node->nlookup -= nlookup;
1440  if (!node->nlookup) {
1441  unref_node(f, node);
1442  } else if (lru_enabled(f) && node->nlookup == 1) {
1443  set_forget_time(f, node);
1444  }
1445  pthread_mutex_unlock(&f->lock);
1446 }
1447 
1448 static void unlink_node(struct fuse *f, struct node *node)
1449 {
1450  if (f->conf.remember) {
1451  assert(node->nlookup > 1);
1452  node->nlookup--;
1453  }
1454  unhash_name(f, node);
1455 }
1456 
1457 static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name)
1458 {
1459  struct node *node;
1460 
1461  pthread_mutex_lock(&f->lock);
1462  node = lookup_node(f, dir, name);
1463  if (node != NULL)
1464  unlink_node(f, node);
1465  pthread_mutex_unlock(&f->lock);
1466 }
1467 
1468 static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1469  fuse_ino_t newdir, const char *newname, int hide)
1470 {
1471  struct node *node;
1472  struct node *newnode;
1473  int err = 0;
1474 
1475  pthread_mutex_lock(&f->lock);
1476  node = lookup_node(f, olddir, oldname);
1477  newnode = lookup_node(f, newdir, newname);
1478  if (node == NULL)
1479  goto out;
1480 
1481  if (newnode != NULL) {
1482  if (hide) {
1483  fuse_log(FUSE_LOG_ERR, "fuse: hidden file got created during hiding\n");
1484  err = -EBUSY;
1485  goto out;
1486  }
1487  unlink_node(f, newnode);
1488  }
1489 
1490  unhash_name(f, node);
1491  if (hash_name(f, node, newdir, newname) == -1) {
1492  err = -ENOMEM;
1493  goto out;
1494  }
1495 
1496  if (hide)
1497  node->is_hidden = 1;
1498 
1499 out:
1500  pthread_mutex_unlock(&f->lock);
1501  return err;
1502 }
1503 
1504 static int exchange_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1505  fuse_ino_t newdir, const char *newname)
1506 {
1507  struct node *oldnode;
1508  struct node *newnode;
1509  int err;
1510 
1511  pthread_mutex_lock(&f->lock);
1512  oldnode = lookup_node(f, olddir, oldname);
1513  newnode = lookup_node(f, newdir, newname);
1514 
1515  if (oldnode)
1516  unhash_name(f, oldnode);
1517  if (newnode)
1518  unhash_name(f, newnode);
1519 
1520  err = -ENOMEM;
1521  if (oldnode) {
1522  if (hash_name(f, oldnode, newdir, newname) == -1)
1523  goto out;
1524  }
1525  if (newnode) {
1526  if (hash_name(f, newnode, olddir, oldname) == -1)
1527  goto out;
1528  }
1529  err = 0;
1530 out:
1531  pthread_mutex_unlock(&f->lock);
1532  return err;
1533 }
1534 
1535 static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
1536 {
1537  if (!f->conf.use_ino)
1538  stbuf->st_ino = nodeid;
1539  if (f->conf.set_mode)
1540  stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1541  (0777 & ~f->conf.umask);
1542  if (f->conf.set_uid)
1543  stbuf->st_uid = f->conf.uid;
1544  if (f->conf.set_gid)
1545  stbuf->st_gid = f->conf.gid;
1546 }
1547 
1548 static struct fuse *req_fuse(fuse_req_t req)
1549 {
1550  return (struct fuse *) fuse_req_userdata(req);
1551 }
1552 
1553 static void fuse_intr_sighandler(int sig)
1554 {
1555  (void) sig;
1556  /* Nothing to do */
1557 }
1558 
1559 struct fuse_intr_data {
1560  pthread_t id;
1561  pthread_cond_t cond;
1562  int finished;
1563 };
1564 
1565 static void fuse_interrupt(fuse_req_t req, void *d_)
1566 {
1567  struct fuse_intr_data *d = d_;
1568  struct fuse *f = req_fuse(req);
1569 
1570  if (d->id == pthread_self())
1571  return;
1572 
1573  pthread_mutex_lock(&f->lock);
1574  while (!d->finished) {
1575  struct timeval now;
1576  struct timespec timeout;
1577 
1578  pthread_kill(d->id, f->conf.intr_signal);
1579  gettimeofday(&now, NULL);
1580  timeout.tv_sec = now.tv_sec + 1;
1581  timeout.tv_nsec = now.tv_usec * 1000;
1582  pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1583  }
1584  pthread_mutex_unlock(&f->lock);
1585 }
1586 
1587 static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
1588  struct fuse_intr_data *d)
1589 {
1590  pthread_mutex_lock(&f->lock);
1591  d->finished = 1;
1592  pthread_cond_broadcast(&d->cond);
1593  pthread_mutex_unlock(&f->lock);
1594  fuse_req_interrupt_func(req, NULL, NULL);
1595  pthread_cond_destroy(&d->cond);
1596 }
1597 
1598 static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
1599 {
1600  d->id = pthread_self();
1601  pthread_cond_init(&d->cond, NULL);
1602  d->finished = 0;
1603  fuse_req_interrupt_func(req, fuse_interrupt, d);
1604 }
1605 
1606 static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
1607  struct fuse_intr_data *d)
1608 {
1609  if (f->conf.intr)
1610  fuse_do_finish_interrupt(f, req, d);
1611 }
1612 
1613 static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
1614  struct fuse_intr_data *d)
1615 {
1616  if (f->conf.intr)
1617  fuse_do_prepare_interrupt(req, d);
1618 }
1619 
1620 static const char* file_info_string(struct fuse_file_info *fi,
1621  char* buf, size_t len)
1622 {
1623  if(fi == NULL)
1624  return "NULL";
1625  snprintf(buf, len, "%llu", (unsigned long long) fi->fh);
1626  return buf;
1627 }
1628 
1629 int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
1630  struct fuse_file_info *fi)
1631 {
1632  fuse_get_context()->private_data = fs->user_data;
1633  if (fs->op.getattr) {
1634  if (fs->debug) {
1635  char buf[10];
1636  fuse_log(FUSE_LOG_DEBUG, "getattr[%s] %s\n",
1637  file_info_string(fi, buf, sizeof(buf)),
1638  path);
1639  }
1640  return fs->op.getattr(path, buf, fi);
1641  } else {
1642  return -ENOSYS;
1643  }
1644 }
1645 
1646 int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
1647  const char *newpath, unsigned int flags)
1648 {
1649  fuse_get_context()->private_data = fs->user_data;
1650  if (fs->op.rename) {
1651  if (fs->debug)
1652  fuse_log(FUSE_LOG_DEBUG, "rename %s %s 0x%x\n", oldpath, newpath,
1653  flags);
1654 
1655  return fs->op.rename(oldpath, newpath, flags);
1656  } else {
1657  return -ENOSYS;
1658  }
1659 }
1660 
1661 int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
1662 {
1663  fuse_get_context()->private_data = fs->user_data;
1664  if (fs->op.unlink) {
1665  if (fs->debug)
1666  fuse_log(FUSE_LOG_DEBUG, "unlink %s\n", path);
1667 
1668  return fs->op.unlink(path);
1669  } else {
1670  return -ENOSYS;
1671  }
1672 }
1673 
1674 int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
1675 {
1676  fuse_get_context()->private_data = fs->user_data;
1677  if (fs->op.rmdir) {
1678  if (fs->debug)
1679  fuse_log(FUSE_LOG_DEBUG, "rmdir %s\n", path);
1680 
1681  return fs->op.rmdir(path);
1682  } else {
1683  return -ENOSYS;
1684  }
1685 }
1686 
1687 int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
1688 {
1689  fuse_get_context()->private_data = fs->user_data;
1690  if (fs->op.symlink) {
1691  if (fs->debug)
1692  fuse_log(FUSE_LOG_DEBUG, "symlink %s %s\n", linkname, path);
1693 
1694  return fs->op.symlink(linkname, path);
1695  } else {
1696  return -ENOSYS;
1697  }
1698 }
1699 
1700 int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
1701 {
1702  fuse_get_context()->private_data = fs->user_data;
1703  if (fs->op.link) {
1704  if (fs->debug)
1705  fuse_log(FUSE_LOG_DEBUG, "link %s %s\n", oldpath, newpath);
1706 
1707  return fs->op.link(oldpath, newpath);
1708  } else {
1709  return -ENOSYS;
1710  }
1711 }
1712 
1713 int fuse_fs_release(struct fuse_fs *fs, const char *path,
1714  struct fuse_file_info *fi)
1715 {
1716  fuse_get_context()->private_data = fs->user_data;
1717  if (fs->op.release) {
1718  if (fs->debug)
1719  fuse_log(FUSE_LOG_DEBUG, "release%s[%llu] flags: 0x%x\n",
1720  fi->flush ? "+flush" : "",
1721  (unsigned long long) fi->fh, fi->flags);
1722 
1723  return fs->op.release(path, fi);
1724  } else {
1725  return 0;
1726  }
1727 }
1728 
1729 int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
1730  struct fuse_file_info *fi)
1731 {
1732  fuse_get_context()->private_data = fs->user_data;
1733  if (fs->op.opendir) {
1734  int err;
1735 
1736  if (fs->debug)
1737  fuse_log(FUSE_LOG_DEBUG, "opendir flags: 0x%x %s\n", fi->flags,
1738  path);
1739 
1740  err = fs->op.opendir(path, fi);
1741 
1742  if (fs->debug && !err)
1743  fuse_log(FUSE_LOG_DEBUG, " opendir[%llu] flags: 0x%x %s\n",
1744  (unsigned long long) fi->fh, fi->flags, path);
1745 
1746  return err;
1747  } else {
1748  return 0;
1749  }
1750 }
1751 
1752 int fuse_fs_open(struct fuse_fs *fs, const char *path,
1753  struct fuse_file_info *fi)
1754 {
1755  fuse_get_context()->private_data = fs->user_data;
1756  if (fs->op.open) {
1757  int err;
1758 
1759  if (fs->debug)
1760  fuse_log(FUSE_LOG_DEBUG, "open flags: 0x%x %s\n", fi->flags,
1761  path);
1762 
1763  err = fs->op.open(path, fi);
1764 
1765  if (fs->debug && !err)
1766  fuse_log(FUSE_LOG_DEBUG, " open[%llu] flags: 0x%x %s\n",
1767  (unsigned long long) fi->fh, fi->flags, path);
1768 
1769  return err;
1770  } else {
1771  return 0;
1772  }
1773 }
1774 
1775 static void fuse_free_buf(struct fuse_bufvec *buf)
1776 {
1777  if (buf != NULL) {
1778  size_t i;
1779 
1780  for (i = 0; i < buf->count; i++)
1781  if (!(buf->buf[i].flags & FUSE_BUF_IS_FD))
1782  free(buf->buf[i].mem);
1783  free(buf);
1784  }
1785 }
1786 
1787 int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
1788  struct fuse_bufvec **bufp, size_t size, off_t off,
1789  struct fuse_file_info *fi)
1790 {
1791  fuse_get_context()->private_data = fs->user_data;
1792  if (fs->op.read || fs->op.read_buf) {
1793  int res;
1794 
1795  if (fs->debug)
1796  fuse_log(FUSE_LOG_DEBUG,
1797  "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1798  (unsigned long long) fi->fh,
1799  size, (unsigned long long) off, fi->flags);
1800 
1801  if (fs->op.read_buf) {
1802  res = fs->op.read_buf(path, bufp, size, off, fi);
1803  } else {
1804  struct fuse_bufvec *buf;
1805  void *mem;
1806 
1807  buf = malloc(sizeof(struct fuse_bufvec));
1808  if (buf == NULL)
1809  return -ENOMEM;
1810 
1811  mem = malloc(size);
1812  if (mem == NULL) {
1813  free(buf);
1814  return -ENOMEM;
1815  }
1816  *buf = FUSE_BUFVEC_INIT(size);
1817  buf->buf[0].mem = mem;
1818  *bufp = buf;
1819 
1820  res = fs->op.read(path, mem, size, off, fi);
1821  if (res >= 0)
1822  buf->buf[0].size = res;
1823  }
1824 
1825  if (fs->debug && res >= 0)
1826  fuse_log(FUSE_LOG_DEBUG, " read[%llu] %zu bytes from %llu\n",
1827  (unsigned long long) fi->fh,
1828  fuse_buf_size(*bufp),
1829  (unsigned long long) off);
1830  if (res >= 0 && fuse_buf_size(*bufp) > size)
1831  fuse_log(FUSE_LOG_ERR, "fuse: read too many bytes\n");
1832 
1833  if (res < 0)
1834  return res;
1835 
1836  return 0;
1837  } else {
1838  return -ENOSYS;
1839  }
1840 }
1841 
1842 int fuse_fs_read(struct fuse_fs *fs, const char *path, char *mem, size_t size,
1843  off_t off, struct fuse_file_info *fi)
1844 {
1845  fuse_get_context()->private_data = fs->user_data;
1846  if (fs->op.read || fs->op.read_buf) {
1847  int res;
1848 
1849  if (fs->debug)
1850  fuse_log(FUSE_LOG_DEBUG,
1851  "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1852  (unsigned long long) fi->fh,
1853  size, (unsigned long long) off, fi->flags);
1854 
1855  if (fs->op.read_buf) {
1856  struct fuse_bufvec *buf = NULL;
1857 
1858  res = fs->op.read_buf(path, &buf, size, off, fi);
1859  if (res == 0) {
1860  struct fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
1861 
1862  dst.buf[0].mem = mem;
1863  res = fuse_buf_copy(&dst, buf, 0);
1864  }
1865  fuse_free_buf(buf);
1866  } else {
1867  res = fs->op.read(path, mem, size, off, fi);
1868  }
1869 
1870  if (fs->debug && res >= 0)
1871  fuse_log(FUSE_LOG_DEBUG, " read[%llu] %u bytes from %llu\n",
1872  (unsigned long long) fi->fh,
1873  res,
1874  (unsigned long long) off);
1875  if (res >= 0 && res > (int) size)
1876  fuse_log(FUSE_LOG_ERR, "fuse: read too many bytes\n");
1877 
1878  return res;
1879  } else {
1880  return -ENOSYS;
1881  }
1882 }
1883 
1884 int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
1885  struct fuse_bufvec *buf, off_t off,
1886  struct fuse_file_info *fi)
1887 {
1888  fuse_get_context()->private_data = fs->user_data;
1889  if (fs->op.write_buf || fs->op.write) {
1890  int res;
1891  size_t size = fuse_buf_size(buf);
1892 
1893  assert(buf->idx == 0 && buf->off == 0);
1894  if (fs->debug)
1895  fuse_log(FUSE_LOG_DEBUG,
1896  "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1897  fi->writepage ? "page" : "",
1898  (unsigned long long) fi->fh,
1899  size,
1900  (unsigned long long) off,
1901  fi->flags);
1902 
1903  if (fs->op.write_buf) {
1904  res = fs->op.write_buf(path, buf, off, fi);
1905  } else {
1906  void *mem = NULL;
1907  struct fuse_buf *flatbuf;
1908  struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
1909 
1910  if (buf->count == 1 &&
1911  !(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
1912  flatbuf = &buf->buf[0];
1913  } else {
1914  res = -ENOMEM;
1915  mem = malloc(size);
1916  if (mem == NULL)
1917  goto out;
1918 
1919  tmp.buf[0].mem = mem;
1920  res = fuse_buf_copy(&tmp, buf, 0);
1921  if (res <= 0)
1922  goto out_free;
1923 
1924  tmp.buf[0].size = res;
1925  flatbuf = &tmp.buf[0];
1926  }
1927 
1928  res = fs->op.write(path, flatbuf->mem, flatbuf->size,
1929  off, fi);
1930 out_free:
1931  free(mem);
1932  }
1933 out:
1934  if (fs->debug && res >= 0)
1935  fuse_log(FUSE_LOG_DEBUG, " write%s[%llu] %u bytes to %llu\n",
1936  fi->writepage ? "page" : "",
1937  (unsigned long long) fi->fh, res,
1938  (unsigned long long) off);
1939  if (res > (int) size)
1940  fuse_log(FUSE_LOG_ERR, "fuse: wrote too many bytes\n");
1941 
1942  return res;
1943  } else {
1944  return -ENOSYS;
1945  }
1946 }
1947 
1948 int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *mem,
1949  size_t size, off_t off, struct fuse_file_info *fi)
1950 {
1951  struct fuse_bufvec bufv = FUSE_BUFVEC_INIT(size);
1952 
1953  bufv.buf[0].mem = (void *) mem;
1954 
1955  return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1956 }
1957 
1958 int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
1959  struct fuse_file_info *fi)
1960 {
1961  fuse_get_context()->private_data = fs->user_data;
1962  if (fs->op.fsync) {
1963  if (fs->debug)
1964  fuse_log(FUSE_LOG_DEBUG, "fsync[%llu] datasync: %i\n",
1965  (unsigned long long) fi->fh, datasync);
1966 
1967  return fs->op.fsync(path, datasync, fi);
1968  } else {
1969  return -ENOSYS;
1970  }
1971 }
1972 
1973 int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
1974  struct fuse_file_info *fi)
1975 {
1976  fuse_get_context()->private_data = fs->user_data;
1977  if (fs->op.fsyncdir) {
1978  if (fs->debug)
1979  fuse_log(FUSE_LOG_DEBUG, "fsyncdir[%llu] datasync: %i\n",
1980  (unsigned long long) fi->fh, datasync);
1981 
1982  return fs->op.fsyncdir(path, datasync, fi);
1983  } else {
1984  return -ENOSYS;
1985  }
1986 }
1987 
1988 int fuse_fs_flush(struct fuse_fs *fs, const char *path,
1989  struct fuse_file_info *fi)
1990 {
1991  fuse_get_context()->private_data = fs->user_data;
1992  if (fs->op.flush) {
1993  if (fs->debug)
1994  fuse_log(FUSE_LOG_DEBUG, "flush[%llu]\n",
1995  (unsigned long long) fi->fh);
1996 
1997  return fs->op.flush(path, fi);
1998  } else {
1999  return -ENOSYS;
2000  }
2001 }
2002 
2003 int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
2004 {
2005  fuse_get_context()->private_data = fs->user_data;
2006  if (fs->op.statfs) {
2007  if (fs->debug)
2008  fuse_log(FUSE_LOG_DEBUG, "statfs %s\n", path);
2009 
2010  return fs->op.statfs(path, buf);
2011  } else {
2012  buf->f_namemax = 255;
2013  buf->f_bsize = 512;
2014  return 0;
2015  }
2016 }
2017 
2018 int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
2019  struct fuse_file_info *fi)
2020 {
2021  fuse_get_context()->private_data = fs->user_data;
2022  if (fs->op.releasedir) {
2023  if (fs->debug)
2024  fuse_log(FUSE_LOG_DEBUG, "releasedir[%llu] flags: 0x%x\n",
2025  (unsigned long long) fi->fh, fi->flags);
2026 
2027  return fs->op.releasedir(path, fi);
2028  } else {
2029  return 0;
2030  }
2031 }
2032 
2033 int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
2034  fuse_fill_dir_t filler, off_t off,
2035  struct fuse_file_info *fi,
2036  enum fuse_readdir_flags flags)
2037 {
2038  fuse_get_context()->private_data = fs->user_data;
2039  if (fs->op.readdir) {
2040  if (fs->debug) {
2041  fuse_log(FUSE_LOG_DEBUG, "readdir%s[%llu] from %llu\n",
2042  (flags & FUSE_READDIR_PLUS) ? "plus" : "",
2043  (unsigned long long) fi->fh,
2044  (unsigned long long) off);
2045  }
2046 
2047  return fs->op.readdir(path, buf, filler, off, fi, flags);
2048  } else {
2049  return -ENOSYS;
2050  }
2051 }
2052 
2053 int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
2054  struct fuse_file_info *fi)
2055 {
2056  fuse_get_context()->private_data = fs->user_data;
2057  if (fs->op.create) {
2058  int err;
2059 
2060  if (fs->debug)
2061  fuse_log(FUSE_LOG_DEBUG,
2062  "create flags: 0x%x %s 0%o umask=0%03o\n",
2063  fi->flags, path, mode,
2064  fuse_get_context()->umask);
2065 
2066  err = fs->op.create(path, mode, fi);
2067 
2068  if (fs->debug && !err)
2069  fuse_log(FUSE_LOG_DEBUG, " create[%llu] flags: 0x%x %s\n",
2070  (unsigned long long) fi->fh, fi->flags, path);
2071 
2072  return err;
2073  } else {
2074  return -ENOSYS;
2075  }
2076 }
2077 
2078 int fuse_fs_lock(struct fuse_fs *fs, const char *path,
2079  struct fuse_file_info *fi, int cmd, struct flock *lock)
2080 {
2081  fuse_get_context()->private_data = fs->user_data;
2082  if (fs->op.lock) {
2083  if (fs->debug)
2084  fuse_log(FUSE_LOG_DEBUG, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2085  (unsigned long long) fi->fh,
2086  (cmd == F_GETLK ? "F_GETLK" :
2087  (cmd == F_SETLK ? "F_SETLK" :
2088  (cmd == F_SETLKW ? "F_SETLKW" : "???"))),
2089  (lock->l_type == F_RDLCK ? "F_RDLCK" :
2090  (lock->l_type == F_WRLCK ? "F_WRLCK" :
2091  (lock->l_type == F_UNLCK ? "F_UNLCK" :
2092  "???"))),
2093  (unsigned long long) lock->l_start,
2094  (unsigned long long) lock->l_len,
2095  (unsigned long long) lock->l_pid);
2096 
2097  return fs->op.lock(path, fi, cmd, lock);
2098  } else {
2099  return -ENOSYS;
2100  }
2101 }
2102 
2103 int fuse_fs_flock(struct fuse_fs *fs, const char *path,
2104  struct fuse_file_info *fi, int op)
2105 {
2106  fuse_get_context()->private_data = fs->user_data;
2107  if (fs->op.flock) {
2108  if (fs->debug) {
2109  int xop = op & ~LOCK_NB;
2110 
2111  fuse_log(FUSE_LOG_DEBUG, "lock[%llu] %s%s\n",
2112  (unsigned long long) fi->fh,
2113  xop == LOCK_SH ? "LOCK_SH" :
2114  (xop == LOCK_EX ? "LOCK_EX" :
2115  (xop == LOCK_UN ? "LOCK_UN" : "???")),
2116  (op & LOCK_NB) ? "|LOCK_NB" : "");
2117  }
2118  return fs->op.flock(path, fi, op);
2119  } else {
2120  return -ENOSYS;
2121  }
2122 }
2123 
2124 int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid,
2125  gid_t gid, struct fuse_file_info *fi)
2126 {
2127  fuse_get_context()->private_data = fs->user_data;
2128  if (fs->op.chown) {
2129  if (fs->debug) {
2130  char buf[10];
2131  fuse_log(FUSE_LOG_DEBUG, "chown[%s] %s %lu %lu\n",
2132  file_info_string(fi, buf, sizeof(buf)),
2133  path, (unsigned long) uid, (unsigned long) gid);
2134  }
2135  return fs->op.chown(path, uid, gid, fi);
2136  } else {
2137  return -ENOSYS;
2138  }
2139 }
2140 
2141 int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
2142  struct fuse_file_info *fi)
2143 {
2144  fuse_get_context()->private_data = fs->user_data;
2145  if (fs->op.truncate) {
2146  if (fs->debug) {
2147  char buf[10];
2148  fuse_log(FUSE_LOG_DEBUG, "truncate[%s] %llu\n",
2149  file_info_string(fi, buf, sizeof(buf)),
2150  (unsigned long long) size);
2151  }
2152  return fs->op.truncate(path, size, fi);
2153  } else {
2154  return -ENOSYS;
2155  }
2156 }
2157 
2158 int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
2159  const struct timespec tv[2], struct fuse_file_info *fi)
2160 {
2161  fuse_get_context()->private_data = fs->user_data;
2162  if (fs->op.utimens) {
2163  if (fs->debug) {
2164  char buf[10];
2165  fuse_log(FUSE_LOG_DEBUG, "utimens[%s] %s %li.%09lu %li.%09lu\n",
2166  file_info_string(fi, buf, sizeof(buf)),
2167  path, tv[0].tv_sec, tv[0].tv_nsec,
2168  tv[1].tv_sec, tv[1].tv_nsec);
2169  }
2170  return fs->op.utimens(path, tv, fi);
2171  } else {
2172  return -ENOSYS;
2173  }
2174 }
2175 
2176 int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
2177 {
2178  fuse_get_context()->private_data = fs->user_data;
2179  if (fs->op.access) {
2180  if (fs->debug)
2181  fuse_log(FUSE_LOG_DEBUG, "access %s 0%o\n", path, mask);
2182 
2183  return fs->op.access(path, mask);
2184  } else {
2185  return -ENOSYS;
2186  }
2187 }
2188 
2189 int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
2190  size_t len)
2191 {
2192  fuse_get_context()->private_data = fs->user_data;
2193  if (fs->op.readlink) {
2194  if (fs->debug)
2195  fuse_log(FUSE_LOG_DEBUG, "readlink %s %lu\n", path,
2196  (unsigned long) len);
2197 
2198  return fs->op.readlink(path, buf, len);
2199  } else {
2200  return -ENOSYS;
2201  }
2202 }
2203 
2204 int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
2205  dev_t rdev)
2206 {
2207  fuse_get_context()->private_data = fs->user_data;
2208  if (fs->op.mknod) {
2209  if (fs->debug)
2210  fuse_log(FUSE_LOG_DEBUG, "mknod %s 0%o 0x%llx umask=0%03o\n",
2211  path, mode, (unsigned long long) rdev,
2212  fuse_get_context()->umask);
2213 
2214  return fs->op.mknod(path, mode, rdev);
2215  } else {
2216  return -ENOSYS;
2217  }
2218 }
2219 
2220 int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
2221 {
2222  fuse_get_context()->private_data = fs->user_data;
2223  if (fs->op.mkdir) {
2224  if (fs->debug)
2225  fuse_log(FUSE_LOG_DEBUG, "mkdir %s 0%o umask=0%03o\n",
2226  path, mode, fuse_get_context()->umask);
2227 
2228  return fs->op.mkdir(path, mode);
2229  } else {
2230  return -ENOSYS;
2231  }
2232 }
2233 
2234 int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
2235  const char *value, size_t size, int flags)
2236 {
2237  fuse_get_context()->private_data = fs->user_data;
2238  if (fs->op.setxattr) {
2239  if (fs->debug)
2240  fuse_log(FUSE_LOG_DEBUG, "setxattr %s %s %lu 0x%x\n",
2241  path, name, (unsigned long) size, flags);
2242 
2243  return fs->op.setxattr(path, name, value, size, flags);
2244  } else {
2245  return -ENOSYS;
2246  }
2247 }
2248 
2249 int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
2250  char *value, size_t size)
2251 {
2252  fuse_get_context()->private_data = fs->user_data;
2253  if (fs->op.getxattr) {
2254  if (fs->debug)
2255  fuse_log(FUSE_LOG_DEBUG, "getxattr %s %s %lu\n",
2256  path, name, (unsigned long) size);
2257 
2258  return fs->op.getxattr(path, name, value, size);
2259  } else {
2260  return -ENOSYS;
2261  }
2262 }
2263 
2264 int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
2265  size_t size)
2266 {
2267  fuse_get_context()->private_data = fs->user_data;
2268  if (fs->op.listxattr) {
2269  if (fs->debug)
2270  fuse_log(FUSE_LOG_DEBUG, "listxattr %s %lu\n",
2271  path, (unsigned long) size);
2272 
2273  return fs->op.listxattr(path, list, size);
2274  } else {
2275  return -ENOSYS;
2276  }
2277 }
2278 
2279 int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
2280  uint64_t *idx)
2281 {
2282  fuse_get_context()->private_data = fs->user_data;
2283  if (fs->op.bmap) {
2284  if (fs->debug)
2285  fuse_log(FUSE_LOG_DEBUG, "bmap %s blocksize: %lu index: %llu\n",
2286  path, (unsigned long) blocksize,
2287  (unsigned long long) *idx);
2288 
2289  return fs->op.bmap(path, blocksize, idx);
2290  } else {
2291  return -ENOSYS;
2292  }
2293 }
2294 
2295 int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
2296 {
2297  fuse_get_context()->private_data = fs->user_data;
2298  if (fs->op.removexattr) {
2299  if (fs->debug)
2300  fuse_log(FUSE_LOG_DEBUG, "removexattr %s %s\n", path, name);
2301 
2302  return fs->op.removexattr(path, name);
2303  } else {
2304  return -ENOSYS;
2305  }
2306 }
2307 
2308 int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, unsigned int cmd,
2309  void *arg, struct fuse_file_info *fi, unsigned int flags,
2310  void *data)
2311 {
2312  fuse_get_context()->private_data = fs->user_data;
2313  if (fs->op.ioctl) {
2314  if (fs->debug)
2315  fuse_log(FUSE_LOG_DEBUG, "ioctl[%llu] 0x%x flags: 0x%x\n",
2316  (unsigned long long) fi->fh, cmd, flags);
2317 
2318  return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2319  } else
2320  return -ENOSYS;
2321 }
2322 
2323 int fuse_fs_poll(struct fuse_fs *fs, const char *path,
2324  struct fuse_file_info *fi, struct fuse_pollhandle *ph,
2325  unsigned *reventsp)
2326 {
2327  fuse_get_context()->private_data = fs->user_data;
2328  if (fs->op.poll) {
2329  int res;
2330 
2331  if (fs->debug)
2332  fuse_log(FUSE_LOG_DEBUG, "poll[%llu] ph: %p, events 0x%x\n",
2333  (unsigned long long) fi->fh, ph,
2334  fi->poll_events);
2335 
2336  res = fs->op.poll(path, fi, ph, reventsp);
2337 
2338  if (fs->debug && !res)
2339  fuse_log(FUSE_LOG_DEBUG, " poll[%llu] revents: 0x%x\n",
2340  (unsigned long long) fi->fh, *reventsp);
2341 
2342  return res;
2343  } else
2344  return -ENOSYS;
2345 }
2346 
2347 int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
2348  off_t offset, off_t length, struct fuse_file_info *fi)
2349 {
2350  fuse_get_context()->private_data = fs->user_data;
2351  if (fs->op.fallocate) {
2352  if (fs->debug)
2353  fuse_log(FUSE_LOG_DEBUG, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2354  path,
2355  mode,
2356  (unsigned long long) offset,
2357  (unsigned long long) length);
2358 
2359  return fs->op.fallocate(path, mode, offset, length, fi);
2360  } else
2361  return -ENOSYS;
2362 }
2363 
2364 ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, const char *path_in,
2365  struct fuse_file_info *fi_in, off_t off_in,
2366  const char *path_out,
2367  struct fuse_file_info *fi_out, off_t off_out,
2368  size_t len, int flags)
2369 {
2370  fuse_get_context()->private_data = fs->user_data;
2371  if (fs->op.copy_file_range) {
2372  if (fs->debug)
2373  fuse_log(FUSE_LOG_DEBUG, "copy_file_range from %s:%llu to "
2374  "%s:%llu, length: %llu\n",
2375  path_in,
2376  (unsigned long long) off_in,
2377  path_out,
2378  (unsigned long long) off_out,
2379  (unsigned long long) len);
2380 
2381  return fs->op.copy_file_range(path_in, fi_in, off_in, path_out,
2382  fi_out, off_out, len, flags);
2383  } else
2384  return -ENOSYS;
2385 }
2386 
2387 off_t fuse_fs_lseek(struct fuse_fs *fs, const char *path, off_t off, int whence,
2388  struct fuse_file_info *fi)
2389 {
2390  fuse_get_context()->private_data = fs->user_data;
2391  if (fs->op.lseek) {
2392  if (fs->debug) {
2393  char buf[10];
2394  fuse_log(FUSE_LOG_DEBUG, "lseek[%s] %llu %d\n",
2395  file_info_string(fi, buf, sizeof(buf)),
2396  (unsigned long long) off, whence);
2397  }
2398  return fs->op.lseek(path, off, whence, fi);
2399  } else {
2400  return -ENOSYS;
2401  }
2402 }
2403 
2404 static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
2405 {
2406  struct node *node;
2407  int isopen = 0;
2408  pthread_mutex_lock(&f->lock);
2409  node = lookup_node(f, dir, name);
2410  if (node && node->open_count > 0)
2411  isopen = 1;
2412  pthread_mutex_unlock(&f->lock);
2413  return isopen;
2414 }
2415 
2416 static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
2417  char *newname, size_t bufsize)
2418 {
2419  struct stat buf;
2420  struct node *node;
2421  struct node *newnode;
2422  char *newpath;
2423  int res;
2424  int failctr = 10;
2425 
2426  do {
2427  pthread_mutex_lock(&f->lock);
2428  node = lookup_node(f, dir, oldname);
2429  if (node == NULL) {
2430  pthread_mutex_unlock(&f->lock);
2431  return NULL;
2432  }
2433  do {
2434  f->hidectr ++;
2435  snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
2436  (unsigned int) node->nodeid, f->hidectr);
2437  newnode = lookup_node(f, dir, newname);
2438  } while(newnode);
2439 
2440  res = try_get_path(f, dir, newname, &newpath, NULL, false);
2441  pthread_mutex_unlock(&f->lock);
2442  if (res)
2443  break;
2444 
2445  memset(&buf, 0, sizeof(buf));
2446  res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
2447  if (res == -ENOENT)
2448  break;
2449  free(newpath);
2450  newpath = NULL;
2451  } while(res == 0 && --failctr);
2452 
2453  return newpath;
2454 }
2455 
2456 static int hide_node(struct fuse *f, const char *oldpath,
2457  fuse_ino_t dir, const char *oldname)
2458 {
2459  char newname[64];
2460  char *newpath;
2461  int err = -EBUSY;
2462 
2463  newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
2464  if (newpath) {
2465  err = fuse_fs_rename(f->fs, oldpath, newpath, 0);
2466  if (!err)
2467  err = rename_node(f, dir, oldname, dir, newname, 1);
2468  free(newpath);
2469  }
2470  return err;
2471 }
2472 
2473 static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
2474 {
2475  return stbuf->st_mtime == ts->tv_sec &&
2476  ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2477 }
2478 
2479 #ifndef CLOCK_MONOTONIC
2480 #define CLOCK_MONOTONIC CLOCK_REALTIME
2481 #endif
2482 
2483 static void curr_time(struct timespec *now)
2484 {
2485  static clockid_t clockid = CLOCK_MONOTONIC;
2486  int res = clock_gettime(clockid, now);
2487  if (res == -1 && errno == EINVAL) {
2488  clockid = CLOCK_REALTIME;
2489  res = clock_gettime(clockid, now);
2490  }
2491  if (res == -1) {
2492  perror("fuse: clock_gettime");
2493  abort();
2494  }
2495 }
2496 
2497 static void update_stat(struct node *node, const struct stat *stbuf)
2498 {
2499  if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2500  stbuf->st_size != node->size))
2501  node->cache_valid = 0;
2502  node->mtime.tv_sec = stbuf->st_mtime;
2503  node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2504  node->size = stbuf->st_size;
2505  curr_time(&node->stat_updated);
2506 }
2507 
2508 static int do_lookup(struct fuse *f, fuse_ino_t nodeid, const char *name,
2509  struct fuse_entry_param *e)
2510 {
2511  struct node *node;
2512 
2513  node = find_node(f, nodeid, name);
2514  if (node == NULL)
2515  return -ENOMEM;
2516 
2517  e->ino = node->nodeid;
2518  e->generation = node->generation;
2519  e->entry_timeout = f->conf.entry_timeout;
2520  e->attr_timeout = f->conf.attr_timeout;
2521  if (f->conf.auto_cache) {
2522  pthread_mutex_lock(&f->lock);
2523  update_stat(node, &e->attr);
2524  pthread_mutex_unlock(&f->lock);
2525  }
2526  set_stat(f, e->ino, &e->attr);
2527  return 0;
2528 }
2529 
2530 static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
2531  const char *name, const char *path,
2532  struct fuse_entry_param *e, struct fuse_file_info *fi)
2533 {
2534  int res;
2535 
2536  memset(e, 0, sizeof(struct fuse_entry_param));
2537  res = fuse_fs_getattr(f->fs, path, &e->attr, fi);
2538  if (res == 0) {
2539  res = do_lookup(f, nodeid, name, e);
2540  if (res == 0 && f->conf.debug) {
2541  fuse_log(FUSE_LOG_DEBUG, " NODEID: %llu\n",
2542  (unsigned long long) e->ino);
2543  }
2544  }
2545  return res;
2546 }
2547 
2548 static struct fuse_context_i *fuse_get_context_internal(void)
2549 {
2550  return (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2551 }
2552 
2553 static struct fuse_context_i *fuse_create_context(struct fuse *f)
2554 {
2555  struct fuse_context_i *c = fuse_get_context_internal();
2556  if (c == NULL) {
2557  c = (struct fuse_context_i *)
2558  calloc(1, sizeof(struct fuse_context_i));
2559  if (c == NULL) {
2560  /* This is hard to deal with properly, so just
2561  abort. If memory is so low that the
2562  context cannot be allocated, there's not
2563  much hope for the filesystem anyway */
2564  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate thread specific data\n");
2565  abort();
2566  }
2567  pthread_setspecific(fuse_context_key, c);
2568  } else {
2569  memset(c, 0, sizeof(*c));
2570  }
2571  c->ctx.fuse = f;
2572 
2573  return c;
2574 }
2575 
2576 static void fuse_freecontext(void *data)
2577 {
2578  free(data);
2579 }
2580 
2581 static int fuse_create_context_key(void)
2582 {
2583  int err = 0;
2584  pthread_mutex_lock(&fuse_context_lock);
2585  if (!fuse_context_ref) {
2586  err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2587  if (err) {
2588  fuse_log(FUSE_LOG_ERR, "fuse: failed to create thread specific key: %s\n",
2589  strerror(err));
2590  pthread_mutex_unlock(&fuse_context_lock);
2591  return -1;
2592  }
2593  }
2594  fuse_context_ref++;
2595  pthread_mutex_unlock(&fuse_context_lock);
2596  return 0;
2597 }
2598 
2599 static void fuse_delete_context_key(void)
2600 {
2601  pthread_mutex_lock(&fuse_context_lock);
2602  fuse_context_ref--;
2603  if (!fuse_context_ref) {
2604  free(pthread_getspecific(fuse_context_key));
2605  pthread_key_delete(fuse_context_key);
2606  }
2607  pthread_mutex_unlock(&fuse_context_lock);
2608 }
2609 
2610 static struct fuse *req_fuse_prepare(fuse_req_t req)
2611 {
2612  struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2613  const struct fuse_ctx *ctx = fuse_req_ctx(req);
2614  c->req = req;
2615  c->ctx.uid = ctx->uid;
2616  c->ctx.gid = ctx->gid;
2617  c->ctx.pid = ctx->pid;
2618  c->ctx.umask = ctx->umask;
2619  return c->ctx.fuse;
2620 }
2621 
2622 static inline void reply_err(fuse_req_t req, int err)
2623 {
2624  /* fuse_reply_err() uses non-negated errno values */
2625  fuse_reply_err(req, -err);
2626 }
2627 
2628 static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
2629  int err)
2630 {
2631  if (!err) {
2632  struct fuse *f = req_fuse(req);
2633  if (fuse_reply_entry(req, e) == -ENOENT) {
2634  /* Skip forget for negative result */
2635  if (e->ino != 0)
2636  forget_node(f, e->ino, 1);
2637  }
2638  } else
2639  reply_err(req, err);
2640 }
2641 
2642 void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn,
2643  struct fuse_config *cfg)
2644 {
2645  fuse_get_context()->private_data = fs->user_data;
2646  if (!fs->op.write_buf)
2647  conn->want &= ~FUSE_CAP_SPLICE_READ;
2648  if (!fs->op.lock)
2649  conn->want &= ~FUSE_CAP_POSIX_LOCKS;
2650  if (!fs->op.flock)
2651  conn->want &= ~FUSE_CAP_FLOCK_LOCKS;
2652  if (fs->op.init)
2653  fs->user_data = fs->op.init(conn, cfg);
2654 }
2655 
2656 static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
2657 {
2658  struct fuse *f = (struct fuse *) data;
2659 
2660  fuse_create_context(f);
2661  if(conn->capable & FUSE_CAP_EXPORT_SUPPORT)
2662  conn->want |= FUSE_CAP_EXPORT_SUPPORT;
2663  fuse_fs_init(f->fs, conn, &f->conf);
2664 }
2665 
2666 void fuse_fs_destroy(struct fuse_fs *fs)
2667 {
2668  fuse_get_context()->private_data = fs->user_data;
2669  if (fs->op.destroy)
2670  fs->op.destroy(fs->user_data);
2671  if (fs->m)
2672  fuse_put_module(fs->m);
2673  free(fs);
2674 }
2675 
2676 static void fuse_lib_destroy(void *data)
2677 {
2678  struct fuse *f = (struct fuse *) data;
2679 
2680  fuse_create_context(f);
2681  fuse_fs_destroy(f->fs);
2682  f->fs = NULL;
2683 }
2684 
2685 static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
2686  const char *name)
2687 {
2688  struct fuse *f = req_fuse_prepare(req);
2689  struct fuse_entry_param e;
2690  char *path;
2691  int err;
2692  struct node *dot = NULL;
2693 
2694  if (name[0] == '.') {
2695  int len = strlen(name);
2696 
2697  if (len == 1 || (name[1] == '.' && len == 2)) {
2698  pthread_mutex_lock(&f->lock);
2699  if (len == 1) {
2700  if (f->conf.debug)
2701  fuse_log(FUSE_LOG_DEBUG, "LOOKUP-DOT\n");
2702  dot = get_node_nocheck(f, parent);
2703  if (dot == NULL) {
2704  pthread_mutex_unlock(&f->lock);
2705  reply_entry(req, &e, -ESTALE);
2706  return;
2707  }
2708  dot->refctr++;
2709  } else {
2710  if (f->conf.debug)
2711  fuse_log(FUSE_LOG_DEBUG, "LOOKUP-DOTDOT\n");
2712  parent = get_node(f, parent)->parent->nodeid;
2713  }
2714  pthread_mutex_unlock(&f->lock);
2715  name = NULL;
2716  }
2717  }
2718 
2719  err = get_path_name(f, parent, name, &path);
2720  if (!err) {
2721  struct fuse_intr_data d;
2722  if (f->conf.debug)
2723  fuse_log(FUSE_LOG_DEBUG, "LOOKUP %s\n", path);
2724  fuse_prepare_interrupt(f, req, &d);
2725  err = lookup_path(f, parent, name, path, &e, NULL);
2726  if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2727  e.ino = 0;
2728  e.entry_timeout = f->conf.negative_timeout;
2729  err = 0;
2730  }
2731  fuse_finish_interrupt(f, req, &d);
2732  free_path(f, parent, path);
2733  }
2734  if (dot) {
2735  pthread_mutex_lock(&f->lock);
2736  unref_node(f, dot);
2737  pthread_mutex_unlock(&f->lock);
2738  }
2739  reply_entry(req, &e, err);
2740 }
2741 
2742 static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup)
2743 {
2744  if (f->conf.debug)
2745  fuse_log(FUSE_LOG_DEBUG, "FORGET %llu/%llu\n", (unsigned long long)ino,
2746  (unsigned long long) nlookup);
2747  forget_node(f, ino, nlookup);
2748 }
2749 
2750 static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino, uint64_t nlookup)
2751 {
2752  do_forget(req_fuse(req), ino, nlookup);
2753  fuse_reply_none(req);
2754 }
2755 
2756 static void fuse_lib_forget_multi(fuse_req_t req, size_t count,
2757  struct fuse_forget_data *forgets)
2758 {
2759  struct fuse *f = req_fuse(req);
2760  size_t i;
2761 
2762  for (i = 0; i < count; i++)
2763  do_forget(f, forgets[i].ino, forgets[i].nlookup);
2764 
2765  fuse_reply_none(req);
2766 }
2767 
2768 
2769 static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
2770  struct fuse_file_info *fi)
2771 {
2772  struct fuse *f = req_fuse_prepare(req);
2773  struct stat buf;
2774  char *path;
2775  int err;
2776 
2777  memset(&buf, 0, sizeof(buf));
2778 
2779  if (fi != NULL)
2780  err = get_path_nullok(f, ino, &path);
2781  else
2782  err = get_path(f, ino, &path);
2783  if (!err) {
2784  struct fuse_intr_data d;
2785  fuse_prepare_interrupt(f, req, &d);
2786  err = fuse_fs_getattr(f->fs, path, &buf, fi);
2787  fuse_finish_interrupt(f, req, &d);
2788  free_path(f, ino, path);
2789  }
2790  if (!err) {
2791  struct node *node;
2792 
2793  pthread_mutex_lock(&f->lock);
2794  node = get_node(f, ino);
2795  if (node->is_hidden && buf.st_nlink > 0)
2796  buf.st_nlink--;
2797  if (f->conf.auto_cache)
2798  update_stat(node, &buf);
2799  pthread_mutex_unlock(&f->lock);
2800  set_stat(f, ino, &buf);
2801  fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2802  } else
2803  reply_err(req, err);
2804 }
2805 
2806 int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
2807  struct fuse_file_info *fi)
2808 {
2809  fuse_get_context()->private_data = fs->user_data;
2810  if (fs->op.chmod) {
2811  if (fs->debug) {
2812  char buf[10];
2813  fuse_log(FUSE_LOG_DEBUG, "chmod[%s] %s %llo\n",
2814  file_info_string(fi, buf, sizeof(buf)),
2815  path, (unsigned long long) mode);
2816  }
2817  return fs->op.chmod(path, mode, fi);
2818  }
2819  else
2820  return -ENOSYS;
2821 }
2822 
2823 static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
2824  int valid, struct fuse_file_info *fi)
2825 {
2826  struct fuse *f = req_fuse_prepare(req);
2827  struct stat buf;
2828  char *path;
2829  int err;
2830 
2831  memset(&buf, 0, sizeof(buf));
2832  if (fi != NULL)
2833  err = get_path_nullok(f, ino, &path);
2834  else
2835  err = get_path(f, ino, &path);
2836  if (!err) {
2837  struct fuse_intr_data d;
2838  fuse_prepare_interrupt(f, req, &d);
2839  err = 0;
2840  if (!err && (valid & FUSE_SET_ATTR_MODE))
2841  err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
2842  if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2843  uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2844  attr->st_uid : (uid_t) -1;
2845  gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2846  attr->st_gid : (gid_t) -1;
2847  err = fuse_fs_chown(f->fs, path, uid, gid, fi);
2848  }
2849  if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2850  err = fuse_fs_truncate(f->fs, path,
2851  attr->st_size, fi);
2852  }
2853 #ifdef HAVE_UTIMENSAT
2854  if (!err &&
2855  (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2856  struct timespec tv[2];
2857 
2858  tv[0].tv_sec = 0;
2859  tv[1].tv_sec = 0;
2860  tv[0].tv_nsec = UTIME_OMIT;
2861  tv[1].tv_nsec = UTIME_OMIT;
2862 
2863  if (valid & FUSE_SET_ATTR_ATIME_NOW)
2864  tv[0].tv_nsec = UTIME_NOW;
2865  else if (valid & FUSE_SET_ATTR_ATIME)
2866  tv[0] = attr->st_atim;
2867 
2868  if (valid & FUSE_SET_ATTR_MTIME_NOW)
2869  tv[1].tv_nsec = UTIME_NOW;
2870  else if (valid & FUSE_SET_ATTR_MTIME)
2871  tv[1] = attr->st_mtim;
2872 
2873  err = fuse_fs_utimens(f->fs, path, tv, fi);
2874  } else
2875 #endif
2876  if (!err &&
2877  (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2878  (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2879  struct timespec tv[2];
2880  tv[0].tv_sec = attr->st_atime;
2881  tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2882  tv[1].tv_sec = attr->st_mtime;
2883  tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2884  err = fuse_fs_utimens(f->fs, path, tv, fi);
2885  }
2886  if (!err) {
2887  err = fuse_fs_getattr(f->fs, path, &buf, fi);
2888  }
2889  fuse_finish_interrupt(f, req, &d);
2890  free_path(f, ino, path);
2891  }
2892  if (!err) {
2893  if (f->conf.auto_cache) {
2894  pthread_mutex_lock(&f->lock);
2895  update_stat(get_node(f, ino), &buf);
2896  pthread_mutex_unlock(&f->lock);
2897  }
2898  set_stat(f, ino, &buf);
2899  fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2900  } else
2901  reply_err(req, err);
2902 }
2903 
2904 static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
2905 {
2906  struct fuse *f = req_fuse_prepare(req);
2907  char *path;
2908  int err;
2909 
2910  err = get_path(f, ino, &path);
2911  if (!err) {
2912  struct fuse_intr_data d;
2913 
2914  fuse_prepare_interrupt(f, req, &d);
2915  err = fuse_fs_access(f->fs, path, mask);
2916  fuse_finish_interrupt(f, req, &d);
2917  free_path(f, ino, path);
2918  }
2919  reply_err(req, err);
2920 }
2921 
2922 static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
2923 {
2924  struct fuse *f = req_fuse_prepare(req);
2925  char linkname[PATH_MAX + 1];
2926  char *path;
2927  int err;
2928 
2929  err = get_path(f, ino, &path);
2930  if (!err) {
2931  struct fuse_intr_data d;
2932  fuse_prepare_interrupt(f, req, &d);
2933  err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
2934  fuse_finish_interrupt(f, req, &d);
2935  free_path(f, ino, path);
2936  }
2937  if (!err) {
2938  linkname[PATH_MAX] = '\0';
2939  fuse_reply_readlink(req, linkname);
2940  } else
2941  reply_err(req, err);
2942 }
2943 
2944 static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
2945  mode_t mode, dev_t rdev)
2946 {
2947  struct fuse *f = req_fuse_prepare(req);
2948  struct fuse_entry_param e;
2949  char *path;
2950  int err;
2951 
2952  err = get_path_name(f, parent, name, &path);
2953  if (!err) {
2954  struct fuse_intr_data d;
2955 
2956  fuse_prepare_interrupt(f, req, &d);
2957  err = -ENOSYS;
2958  if (S_ISREG(mode)) {
2959  struct fuse_file_info fi;
2960 
2961  memset(&fi, 0, sizeof(fi));
2962  fi.flags = O_CREAT | O_EXCL | O_WRONLY;
2963  err = fuse_fs_create(f->fs, path, mode, &fi);
2964  if (!err) {
2965  err = lookup_path(f, parent, name, path, &e,
2966  &fi);
2967  fuse_fs_release(f->fs, path, &fi);
2968  }
2969  }
2970  if (err == -ENOSYS) {
2971  err = fuse_fs_mknod(f->fs, path, mode, rdev);
2972  if (!err)
2973  err = lookup_path(f, parent, name, path, &e,
2974  NULL);
2975  }
2976  fuse_finish_interrupt(f, req, &d);
2977  free_path(f, parent, path);
2978  }
2979  reply_entry(req, &e, err);
2980 }
2981 
2982 static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
2983  mode_t mode)
2984 {
2985  struct fuse *f = req_fuse_prepare(req);
2986  struct fuse_entry_param e;
2987  char *path;
2988  int err;
2989 
2990  err = get_path_name(f, parent, name, &path);
2991  if (!err) {
2992  struct fuse_intr_data d;
2993 
2994  fuse_prepare_interrupt(f, req, &d);
2995  err = fuse_fs_mkdir(f->fs, path, mode);
2996  if (!err)
2997  err = lookup_path(f, parent, name, path, &e, NULL);
2998  fuse_finish_interrupt(f, req, &d);
2999  free_path(f, parent, path);
3000  }
3001  reply_entry(req, &e, err);
3002 }
3003 
3004 static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
3005  const char *name)
3006 {
3007  struct fuse *f = req_fuse_prepare(req);
3008  struct node *wnode;
3009  char *path;
3010  int err;
3011 
3012  err = get_path_wrlock(f, parent, name, &path, &wnode);
3013  if (!err) {
3014  struct fuse_intr_data d;
3015 
3016  fuse_prepare_interrupt(f, req, &d);
3017  if (!f->conf.hard_remove && is_open(f, parent, name)) {
3018  err = hide_node(f, path, parent, name);
3019  } else {
3020  err = fuse_fs_unlink(f->fs, path);
3021  if (!err)
3022  remove_node(f, parent, name);
3023  }
3024  fuse_finish_interrupt(f, req, &d);
3025  free_path_wrlock(f, parent, wnode, path);
3026  }
3027  reply_err(req, err);
3028 }
3029 
3030 static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
3031 {
3032  struct fuse *f = req_fuse_prepare(req);
3033  struct node *wnode;
3034  char *path;
3035  int err;
3036 
3037  err = get_path_wrlock(f, parent, name, &path, &wnode);
3038  if (!err) {
3039  struct fuse_intr_data d;
3040 
3041  fuse_prepare_interrupt(f, req, &d);
3042  err = fuse_fs_rmdir(f->fs, path);
3043  fuse_finish_interrupt(f, req, &d);
3044  if (!err)
3045  remove_node(f, parent, name);
3046  free_path_wrlock(f, parent, wnode, path);
3047  }
3048  reply_err(req, err);
3049 }
3050 
3051 static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
3052  fuse_ino_t parent, const char *name)
3053 {
3054  struct fuse *f = req_fuse_prepare(req);
3055  struct fuse_entry_param e;
3056  char *path;
3057  int err;
3058 
3059  err = get_path_name(f, parent, name, &path);
3060  if (!err) {
3061  struct fuse_intr_data d;
3062 
3063  fuse_prepare_interrupt(f, req, &d);
3064  err = fuse_fs_symlink(f->fs, linkname, path);
3065  if (!err)
3066  err = lookup_path(f, parent, name, path, &e, NULL);
3067  fuse_finish_interrupt(f, req, &d);
3068  free_path(f, parent, path);
3069  }
3070  reply_entry(req, &e, err);
3071 }
3072 
3073 static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
3074  const char *oldname, fuse_ino_t newdir,
3075  const char *newname, unsigned int flags)
3076 {
3077  struct fuse *f = req_fuse_prepare(req);
3078  char *oldpath;
3079  char *newpath;
3080  struct node *wnode1;
3081  struct node *wnode2;
3082  int err;
3083 
3084  err = get_path2(f, olddir, oldname, newdir, newname,
3085  &oldpath, &newpath, &wnode1, &wnode2);
3086  if (!err) {
3087  struct fuse_intr_data d;
3088  err = 0;
3089  fuse_prepare_interrupt(f, req, &d);
3090  if (!f->conf.hard_remove && !(flags & RENAME_EXCHANGE) &&
3091  is_open(f, newdir, newname))
3092  err = hide_node(f, newpath, newdir, newname);
3093  if (!err) {
3094  err = fuse_fs_rename(f->fs, oldpath, newpath, flags);
3095  if (!err) {
3096  if (flags & RENAME_EXCHANGE) {
3097  err = exchange_node(f, olddir, oldname,
3098  newdir, newname);
3099  } else {
3100  err = rename_node(f, olddir, oldname,
3101  newdir, newname, 0);
3102  }
3103  }
3104  }
3105  fuse_finish_interrupt(f, req, &d);
3106  free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3107  }
3108  reply_err(req, err);
3109 }
3110 
3111 static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
3112  const char *newname)
3113 {
3114  struct fuse *f = req_fuse_prepare(req);
3115  struct fuse_entry_param e;
3116  char *oldpath;
3117  char *newpath;
3118  int err;
3119 
3120  err = get_path2(f, ino, NULL, newparent, newname,
3121  &oldpath, &newpath, NULL, NULL);
3122  if (!err) {
3123  struct fuse_intr_data d;
3124 
3125  fuse_prepare_interrupt(f, req, &d);
3126  err = fuse_fs_link(f->fs, oldpath, newpath);
3127  if (!err)
3128  err = lookup_path(f, newparent, newname, newpath,
3129  &e, NULL);
3130  fuse_finish_interrupt(f, req, &d);
3131  free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3132  }
3133  reply_entry(req, &e, err);
3134 }
3135 
3136 static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
3137  struct fuse_file_info *fi)
3138 {
3139  struct node *node;
3140  int unlink_hidden = 0;
3141 
3142  fuse_fs_release(f->fs, path, fi);
3143 
3144  pthread_mutex_lock(&f->lock);
3145  node = get_node(f, ino);
3146  assert(node->open_count > 0);
3147  --node->open_count;
3148  if (node->is_hidden && !node->open_count) {
3149  unlink_hidden = 1;
3150  node->is_hidden = 0;
3151  }
3152  pthread_mutex_unlock(&f->lock);
3153 
3154  if(unlink_hidden) {
3155  if (path) {
3156  fuse_fs_unlink(f->fs, path);
3157  } else if (f->conf.nullpath_ok) {
3158  char *unlinkpath;
3159 
3160  if (get_path(f, ino, &unlinkpath) == 0)
3161  fuse_fs_unlink(f->fs, unlinkpath);
3162 
3163  free_path(f, ino, unlinkpath);
3164  }
3165  }
3166 }
3167 
3168 static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
3169  const char *name, mode_t mode,
3170  struct fuse_file_info *fi)
3171 {
3172  struct fuse *f = req_fuse_prepare(req);
3173  struct fuse_intr_data d;
3174  struct fuse_entry_param e;
3175  char *path;
3176  int err;
3177 
3178  err = get_path_name(f, parent, name, &path);
3179  if (!err) {
3180  fuse_prepare_interrupt(f, req, &d);
3181  err = fuse_fs_create(f->fs, path, mode, fi);
3182  if (!err) {
3183  err = lookup_path(f, parent, name, path, &e, fi);
3184  if (err)
3185  fuse_fs_release(f->fs, path, fi);
3186  else if (!S_ISREG(e.attr.st_mode)) {
3187  err = -EIO;
3188  fuse_fs_release(f->fs, path, fi);
3189  forget_node(f, e.ino, 1);
3190  } else {
3191  if (f->conf.direct_io)
3192  fi->direct_io = 1;
3193  if (f->conf.kernel_cache)
3194  fi->keep_cache = 1;
3195 
3196  }
3197  }
3198  fuse_finish_interrupt(f, req, &d);
3199  }
3200  if (!err) {
3201  pthread_mutex_lock(&f->lock);
3202  get_node(f, e.ino)->open_count++;
3203  pthread_mutex_unlock(&f->lock);
3204  if (fuse_reply_create(req, &e, fi) == -ENOENT) {
3205  /* The open syscall was interrupted, so it
3206  must be cancelled */
3207  fuse_do_release(f, e.ino, path, fi);
3208  forget_node(f, e.ino, 1);
3209  }
3210  } else {
3211  reply_err(req, err);
3212  }
3213 
3214  free_path(f, parent, path);
3215 }
3216 
3217 static double diff_timespec(const struct timespec *t1,
3218  const struct timespec *t2)
3219 {
3220  return (t1->tv_sec - t2->tv_sec) +
3221  ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
3222 }
3223 
3224 static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
3225  struct fuse_file_info *fi)
3226 {
3227  struct node *node;
3228 
3229  pthread_mutex_lock(&f->lock);
3230  node = get_node(f, ino);
3231  if (node->cache_valid) {
3232  struct timespec now;
3233 
3234  curr_time(&now);
3235  if (diff_timespec(&now, &node->stat_updated) >
3236  f->conf.ac_attr_timeout) {
3237  struct stat stbuf;
3238  int err;
3239  pthread_mutex_unlock(&f->lock);
3240  err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
3241  pthread_mutex_lock(&f->lock);
3242  if (!err)
3243  update_stat(node, &stbuf);
3244  else
3245  node->cache_valid = 0;
3246  }
3247  }
3248  if (node->cache_valid)
3249  fi->keep_cache = 1;
3250 
3251  node->cache_valid = 1;
3252  pthread_mutex_unlock(&f->lock);
3253 }
3254 
3255 static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
3256  struct fuse_file_info *fi)
3257 {
3258  struct fuse *f = req_fuse_prepare(req);
3259  struct fuse_intr_data d;
3260  char *path;
3261  int err;
3262 
3263  err = get_path(f, ino, &path);
3264  if (!err) {
3265  fuse_prepare_interrupt(f, req, &d);
3266  err = fuse_fs_open(f->fs, path, fi);
3267  if (!err) {
3268  if (f->conf.direct_io)
3269  fi->direct_io = 1;
3270  if (f->conf.kernel_cache)
3271  fi->keep_cache = 1;
3272 
3273  if (f->conf.auto_cache)
3274  open_auto_cache(f, ino, path, fi);
3275  }
3276  fuse_finish_interrupt(f, req, &d);
3277  }
3278  if (!err) {
3279  pthread_mutex_lock(&f->lock);
3280  get_node(f, ino)->open_count++;
3281  pthread_mutex_unlock(&f->lock);
3282  if (fuse_reply_open(req, fi) == -ENOENT) {
3283  /* The open syscall was interrupted, so it
3284  must be cancelled */
3285  fuse_do_release(f, ino, path, fi);
3286  }
3287  } else
3288  reply_err(req, err);
3289 
3290  free_path(f, ino, path);
3291 }
3292 
3293 static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
3294  off_t off, struct fuse_file_info *fi)
3295 {
3296  struct fuse *f = req_fuse_prepare(req);
3297  struct fuse_bufvec *buf = NULL;
3298  char *path;
3299  int res;
3300 
3301  res = get_path_nullok(f, ino, &path);
3302  if (res == 0) {
3303  struct fuse_intr_data d;
3304 
3305  fuse_prepare_interrupt(f, req, &d);
3306  res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3307  fuse_finish_interrupt(f, req, &d);
3308  free_path(f, ino, path);
3309  }
3310 
3311  if (res == 0)
3313  else
3314  reply_err(req, res);
3315 
3316  fuse_free_buf(buf);
3317 }
3318 
3319 static void fuse_lib_write_buf(fuse_req_t req, fuse_ino_t ino,
3320  struct fuse_bufvec *buf, off_t off,
3321  struct fuse_file_info *fi)
3322 {
3323  struct fuse *f = req_fuse_prepare(req);
3324  char *path;
3325  int res;
3326 
3327  res = get_path_nullok(f, ino, &path);
3328  if (res == 0) {
3329  struct fuse_intr_data d;
3330 
3331  fuse_prepare_interrupt(f, req, &d);
3332  res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3333  fuse_finish_interrupt(f, req, &d);
3334  free_path(f, ino, path);
3335  }
3336 
3337  if (res >= 0)
3338  fuse_reply_write(req, res);
3339  else
3340  reply_err(req, res);
3341 }
3342 
3343 static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
3344  struct fuse_file_info *fi)
3345 {
3346  struct fuse *f = req_fuse_prepare(req);
3347  char *path;
3348  int err;
3349 
3350  err = get_path_nullok(f, ino, &path);
3351  if (!err) {
3352  struct fuse_intr_data d;
3353 
3354  fuse_prepare_interrupt(f, req, &d);
3355  err = fuse_fs_fsync(f->fs, path, datasync, fi);
3356  fuse_finish_interrupt(f, req, &d);
3357  free_path(f, ino, path);
3358  }
3359  reply_err(req, err);
3360 }
3361 
3362 static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
3363  struct fuse_file_info *fi)
3364 {
3365  struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
3366  memset(fi, 0, sizeof(struct fuse_file_info));
3367  fi->fh = dh->fh;
3368  return dh;
3369 }
3370 
3371 static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
3372  struct fuse_file_info *llfi)
3373 {
3374  struct fuse *f = req_fuse_prepare(req);
3375  struct fuse_intr_data d;
3376  struct fuse_dh *dh;
3377  struct fuse_file_info fi;
3378  char *path;
3379  int err;
3380 
3381  dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
3382  if (dh == NULL) {
3383  reply_err(req, -ENOMEM);
3384  return;
3385  }
3386  memset(dh, 0, sizeof(struct fuse_dh));
3387  dh->fuse = f;
3388  dh->contents = NULL;
3389  dh->first = NULL;
3390  dh->len = 0;
3391  dh->filled = 0;
3392  dh->nodeid = ino;
3393  pthread_mutex_init(&dh->lock, NULL);
3394 
3395  llfi->fh = (uintptr_t) dh;
3396 
3397  memset(&fi, 0, sizeof(fi));
3398  fi.flags = llfi->flags;
3399 
3400  err = get_path(f, ino, &path);
3401  if (!err) {
3402  fuse_prepare_interrupt(f, req, &d);
3403  err = fuse_fs_opendir(f->fs, path, &fi);
3404  fuse_finish_interrupt(f, req, &d);
3405  dh->fh = fi.fh;
3406  }
3407  if (!err) {
3408  if (fuse_reply_open(req, llfi) == -ENOENT) {
3409  /* The opendir syscall was interrupted, so it
3410  must be cancelled */
3411  fuse_fs_releasedir(f->fs, path, &fi);
3412  pthread_mutex_destroy(&dh->lock);
3413  free(dh);
3414  }
3415  } else {
3416  reply_err(req, err);
3417  pthread_mutex_destroy(&dh->lock);
3418  free(dh);
3419  }
3420  free_path(f, ino, path);
3421 }
3422 
3423 static int extend_contents(struct fuse_dh *dh, unsigned minsize)
3424 {
3425  if (minsize > dh->size) {
3426  char *newptr;
3427  unsigned newsize = dh->size;
3428  if (!newsize)
3429  newsize = 1024;
3430  while (newsize < minsize) {
3431  if (newsize >= 0x80000000)
3432  newsize = 0xffffffff;
3433  else
3434  newsize *= 2;
3435  }
3436 
3437  newptr = (char *) realloc(dh->contents, newsize);
3438  if (!newptr) {
3439  dh->error = -ENOMEM;
3440  return -1;
3441  }
3442  dh->contents = newptr;
3443  dh->size = newsize;
3444  }
3445  return 0;
3446 }
3447 
3448 static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name,
3449  struct stat *st)
3450 {
3451  struct fuse_direntry *de;
3452 
3453  de = malloc(sizeof(struct fuse_direntry));
3454  if (!de) {
3455  dh->error = -ENOMEM;
3456  return -1;
3457  }
3458  de->name = strdup(name);
3459  if (!de->name) {
3460  dh->error = -ENOMEM;
3461  free(de);
3462  return -1;
3463  }
3464  de->stat = *st;
3465  de->next = NULL;
3466 
3467  *dh->last = de;
3468  dh->last = &de->next;
3469 
3470  return 0;
3471 }
3472 
3473 static fuse_ino_t lookup_nodeid(struct fuse *f, fuse_ino_t parent,
3474  const char *name)
3475 {
3476  struct node *node;
3477  fuse_ino_t res = FUSE_UNKNOWN_INO;
3478 
3479  pthread_mutex_lock(&f->lock);
3480  node = lookup_node(f, parent, name);
3481  if (node)
3482  res = node->nodeid;
3483  pthread_mutex_unlock(&f->lock);
3484 
3485  return res;
3486 }
3487 
3488 static int fill_dir(void *dh_, const char *name, const struct stat *statp,
3489  off_t off, enum fuse_fill_dir_flags flags)
3490 {
3491  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3492  struct stat stbuf;
3493 
3494  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3495  dh->error = -EIO;
3496  return 1;
3497  }
3498 
3499  if (statp)
3500  stbuf = *statp;
3501  else {
3502  memset(&stbuf, 0, sizeof(stbuf));
3503  stbuf.st_ino = FUSE_UNKNOWN_INO;
3504  }
3505 
3506  if (!dh->fuse->conf.use_ino) {
3507  stbuf.st_ino = FUSE_UNKNOWN_INO;
3508  if (dh->fuse->conf.readdir_ino) {
3509  stbuf.st_ino = (ino_t)
3510  lookup_nodeid(dh->fuse, dh->nodeid, name);
3511  }
3512  }
3513 
3514  if (off) {
3515  size_t newlen;
3516 
3517  if (dh->filled) {
3518  dh->error = -EIO;
3519  return 1;
3520  }
3521 
3522  if (dh->first) {
3523  dh->error = -EIO;
3524  return 1;
3525  }
3526 
3527  if (extend_contents(dh, dh->needlen) == -1)
3528  return 1;
3529 
3530  newlen = dh->len +
3531  fuse_add_direntry(dh->req, dh->contents + dh->len,
3532  dh->needlen - dh->len, name,
3533  &stbuf, off);
3534  if (newlen > dh->needlen)
3535  return 1;
3536 
3537  dh->len = newlen;
3538  } else {
3539  dh->filled = 1;
3540 
3541  if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3542  return 1;
3543  }
3544  return 0;
3545 }
3546 
3547 static int is_dot_or_dotdot(const char *name)
3548 {
3549  return name[0] == '.' && (name[1] == '\0' ||
3550  (name[1] == '.' && name[2] == '\0'));
3551 }
3552 
3553 static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
3554  off_t off, enum fuse_fill_dir_flags flags)
3555 {
3556  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3557  struct fuse_entry_param e = {
3558  /* ino=0 tells the kernel to ignore readdirplus stat info */
3559  .ino = 0,
3560  };
3561  struct fuse *f = dh->fuse;
3562  int res;
3563 
3564  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3565  dh->error = -EIO;
3566  return 1;
3567  }
3568 
3569  if (off && statp && (flags & FUSE_FILL_DIR_PLUS)) {
3570  e.attr = *statp;
3571 
3572  if (!is_dot_or_dotdot(name)) {
3573  res = do_lookup(f, dh->nodeid, name, &e);
3574  if (res) {
3575  dh->error = res;
3576  return 1;
3577  }
3578  }
3579  } else {
3580  e.attr.st_ino = FUSE_UNKNOWN_INO;
3581  if (!f->conf.use_ino && f->conf.readdir_ino) {
3582  e.attr.st_ino = (ino_t)
3583  lookup_nodeid(f, dh->nodeid, name);
3584  }
3585  }
3586 
3587  if (off) {
3588  size_t newlen;
3589 
3590  if (dh->filled) {
3591  dh->error = -EIO;
3592  return 1;
3593  }
3594 
3595  if (dh->first) {
3596  dh->error = -EIO;
3597  return 1;
3598  }
3599  if (extend_contents(dh, dh->needlen) == -1)
3600  return 1;
3601 
3602  newlen = dh->len +
3603  fuse_add_direntry_plus(dh->req, dh->contents + dh->len,
3604  dh->needlen - dh->len, name,
3605  &e, off);
3606  if (newlen > dh->needlen)
3607  return 1;
3608  dh->len = newlen;
3609  } else {
3610  dh->filled = 1;
3611 
3612  if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1)
3613  return 1;
3614  }
3615 
3616  return 0;
3617 }
3618 
3619 static void free_direntries(struct fuse_direntry *de)
3620 {
3621  while (de) {
3622  struct fuse_direntry *next = de->next;
3623  free(de->name);
3624  free(de);
3625  de = next;
3626  }
3627 }
3628 
3629 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3630  size_t size, off_t off, struct fuse_dh *dh,
3631  struct fuse_file_info *fi,
3632  enum fuse_readdir_flags flags)
3633 {
3634  char *path;
3635  int err;
3636 
3637  if (f->fs->op.readdir)
3638  err = get_path_nullok(f, ino, &path);
3639  else
3640  err = get_path(f, ino, &path);
3641  if (!err) {
3642  struct fuse_intr_data d;
3643  fuse_fill_dir_t filler = fill_dir;
3644 
3645  if (flags & FUSE_READDIR_PLUS)
3646  filler = fill_dir_plus;
3647 
3648  free_direntries(dh->first);
3649  dh->first = NULL;
3650  dh->last = &dh->first;
3651  dh->len = 0;
3652  dh->error = 0;
3653  dh->needlen = size;
3654  dh->filled = 0;
3655  dh->req = req;
3656  fuse_prepare_interrupt(f, req, &d);
3657  err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3658  fuse_finish_interrupt(f, req, &d);
3659  dh->req = NULL;
3660  if (!err)
3661  err = dh->error;
3662  if (err)
3663  dh->filled = 0;
3664  free_path(f, ino, path);
3665  }
3666  return err;
3667 }
3668 
3669 static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh,
3670  off_t off, enum fuse_readdir_flags flags)
3671 {
3672  off_t pos;
3673  struct fuse_direntry *de = dh->first;
3674 
3675  dh->len = 0;
3676 
3677  if (extend_contents(dh, dh->needlen) == -1)
3678  return dh->error;
3679 
3680  for (pos = 0; pos < off; pos++) {
3681  if (!de)
3682  break;
3683 
3684  de = de->next;
3685  }
3686  while (de) {
3687  char *p = dh->contents + dh->len;
3688  unsigned rem = dh->needlen - dh->len;
3689  unsigned thislen;
3690  unsigned newlen;
3691  pos++;
3692 
3693  if (flags & FUSE_READDIR_PLUS) {
3694  struct fuse_entry_param e = {
3695  .ino = 0,
3696  .attr = de->stat,
3697  };
3698  thislen = fuse_add_direntry_plus(req, p, rem,
3699  de->name, &e, pos);
3700  } else {
3701  thislen = fuse_add_direntry(req, p, rem,
3702  de->name, &de->stat, pos);
3703  }
3704  newlen = dh->len + thislen;
3705  if (newlen > dh->needlen)
3706  break;
3707  dh->len = newlen;
3708  de = de->next;
3709  }
3710  return 0;
3711 }
3712 
3713 static void fuse_readdir_common(fuse_req_t req, fuse_ino_t ino, size_t size,
3714  off_t off, struct fuse_file_info *llfi,
3715  enum fuse_readdir_flags flags)
3716 {
3717  struct fuse *f = req_fuse_prepare(req);
3718  struct fuse_file_info fi;
3719  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3720  int err;
3721 
3722  pthread_mutex_lock(&dh->lock);
3723  /* According to SUS, directory contents need to be refreshed on
3724  rewinddir() */
3725  if (!off)
3726  dh->filled = 0;
3727 
3728  if (!dh->filled) {
3729  err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3730  if (err) {
3731  reply_err(req, err);
3732  goto out;
3733  }
3734  }
3735  if (dh->filled) {
3736  dh->needlen = size;
3737  err = readdir_fill_from_list(req, dh, off, flags);
3738  if (err) {
3739  reply_err(req, err);
3740  goto out;
3741  }
3742  }
3743  fuse_reply_buf(req, dh->contents, dh->len);
3744 out:
3745  pthread_mutex_unlock(&dh->lock);
3746 }
3747 
3748 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3749  off_t off, struct fuse_file_info *llfi)
3750 {
3751  fuse_readdir_common(req, ino, size, off, llfi, 0);
3752 }
3753 
3754 static void fuse_lib_readdirplus(fuse_req_t req, fuse_ino_t ino, size_t size,
3755  off_t off, struct fuse_file_info *llfi)
3756 {
3757  fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3758 }
3759 
3760 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3761  struct fuse_file_info *llfi)
3762 {
3763  struct fuse *f = req_fuse_prepare(req);
3764  struct fuse_intr_data d;
3765  struct fuse_file_info fi;
3766  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3767  char *path;
3768 
3769  get_path_nullok(f, ino, &path);
3770 
3771  fuse_prepare_interrupt(f, req, &d);
3772  fuse_fs_releasedir(f->fs, path, &fi);
3773  fuse_finish_interrupt(f, req, &d);
3774  free_path(f, ino, path);
3775 
3776  pthread_mutex_lock(&dh->lock);
3777  pthread_mutex_unlock(&dh->lock);
3778  pthread_mutex_destroy(&dh->lock);
3779  free_direntries(dh->first);
3780  free(dh->contents);
3781  free(dh);
3782  reply_err(req, 0);
3783 }
3784 
3785 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3786  struct fuse_file_info *llfi)
3787 {
3788  struct fuse *f = req_fuse_prepare(req);
3789  struct fuse_file_info fi;
3790  char *path;
3791  int err;
3792 
3793  get_dirhandle(llfi, &fi);
3794 
3795  err = get_path_nullok(f, ino, &path);
3796  if (!err) {
3797  struct fuse_intr_data d;
3798  fuse_prepare_interrupt(f, req, &d);
3799  err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3800  fuse_finish_interrupt(f, req, &d);
3801  free_path(f, ino, path);
3802  }
3803  reply_err(req, err);
3804 }
3805 
3806 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3807 {
3808  struct fuse *f = req_fuse_prepare(req);
3809  struct statvfs buf;
3810  char *path = NULL;
3811  int err = 0;
3812 
3813  memset(&buf, 0, sizeof(buf));
3814  if (ino)
3815  err = get_path(f, ino, &path);
3816 
3817  if (!err) {
3818  struct fuse_intr_data d;
3819  fuse_prepare_interrupt(f, req, &d);
3820  err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3821  fuse_finish_interrupt(f, req, &d);
3822  free_path(f, ino, path);
3823  }
3824 
3825  if (!err)
3826  fuse_reply_statfs(req, &buf);
3827  else
3828  reply_err(req, err);
3829 }
3830 
3831 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3832  const char *value, size_t size, int flags)
3833 {
3834  struct fuse *f = req_fuse_prepare(req);
3835  char *path;
3836  int err;
3837 
3838  err = get_path(f, ino, &path);
3839  if (!err) {
3840  struct fuse_intr_data d;
3841  fuse_prepare_interrupt(f, req, &d);
3842  err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3843  fuse_finish_interrupt(f, req, &d);
3844  free_path(f, ino, path);
3845  }
3846  reply_err(req, err);
3847 }
3848 
3849 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3850  const char *name, char *value, size_t size)
3851 {
3852  int err;
3853  char *path;
3854 
3855  err = get_path(f, ino, &path);
3856  if (!err) {
3857  struct fuse_intr_data d;
3858  fuse_prepare_interrupt(f, req, &d);
3859  err = fuse_fs_getxattr(f->fs, path, name, value, size);
3860  fuse_finish_interrupt(f, req, &d);
3861  free_path(f, ino, path);
3862  }
3863  return err;
3864 }
3865 
3866 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3867  size_t size)
3868 {
3869  struct fuse *f = req_fuse_prepare(req);
3870  int res;
3871 
3872  if (size) {
3873  char *value = (char *) malloc(size);
3874  if (value == NULL) {
3875  reply_err(req, -ENOMEM);
3876  return;
3877  }
3878  res = common_getxattr(f, req, ino, name, value, size);
3879  if (res > 0)
3880  fuse_reply_buf(req, value, res);
3881  else
3882  reply_err(req, res);
3883  free(value);
3884  } else {
3885  res = common_getxattr(f, req, ino, name, NULL, 0);
3886  if (res >= 0)
3887  fuse_reply_xattr(req, res);
3888  else
3889  reply_err(req, res);
3890  }
3891 }
3892 
3893 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3894  char *list, size_t size)
3895 {
3896  char *path;
3897  int err;
3898 
3899  err = get_path(f, ino, &path);
3900  if (!err) {
3901  struct fuse_intr_data d;
3902  fuse_prepare_interrupt(f, req, &d);
3903  err = fuse_fs_listxattr(f->fs, path, list, size);
3904  fuse_finish_interrupt(f, req, &d);
3905  free_path(f, ino, path);
3906  }
3907  return err;
3908 }
3909 
3910 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3911 {
3912  struct fuse *f = req_fuse_prepare(req);
3913  int res;
3914 
3915  if (size) {
3916  char *list = (char *) malloc(size);
3917  if (list == NULL) {
3918  reply_err(req, -ENOMEM);
3919  return;
3920  }
3921  res = common_listxattr(f, req, ino, list, size);
3922  if (res > 0)
3923  fuse_reply_buf(req, list, res);
3924  else
3925  reply_err(req, res);
3926  free(list);
3927  } else {
3928  res = common_listxattr(f, req, ino, NULL, 0);
3929  if (res >= 0)
3930  fuse_reply_xattr(req, res);
3931  else
3932  reply_err(req, res);
3933  }
3934 }
3935 
3936 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3937  const char *name)
3938 {
3939  struct fuse *f = req_fuse_prepare(req);
3940  char *path;
3941  int err;
3942 
3943  err = get_path(f, ino, &path);
3944  if (!err) {
3945  struct fuse_intr_data d;
3946  fuse_prepare_interrupt(f, req, &d);
3947  err = fuse_fs_removexattr(f->fs, path, name);
3948  fuse_finish_interrupt(f, req, &d);
3949  free_path(f, ino, path);
3950  }
3951  reply_err(req, err);
3952 }
3953 
3954 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3955 {
3956  struct lock *l;
3957 
3958  for (l = node->locks; l; l = l->next)
3959  if (l->owner != lock->owner &&
3960  lock->start <= l->end && l->start <= lock->end &&
3961  (l->type == F_WRLCK || lock->type == F_WRLCK))
3962  break;
3963 
3964  return l;
3965 }
3966 
3967 static void delete_lock(struct lock **lockp)
3968 {
3969  struct lock *l = *lockp;
3970  *lockp = l->next;
3971  free(l);
3972 }
3973 
3974 static void insert_lock(struct lock **pos, struct lock *lock)
3975 {
3976  lock->next = *pos;
3977  *pos = lock;
3978 }
3979 
3980 static int locks_insert(struct node *node, struct lock *lock)
3981 {
3982  struct lock **lp;
3983  struct lock *newl1 = NULL;
3984  struct lock *newl2 = NULL;
3985 
3986  if (lock->type != F_UNLCK || lock->start != 0 ||
3987  lock->end != OFFSET_MAX) {
3988  newl1 = malloc(sizeof(struct lock));
3989  newl2 = malloc(sizeof(struct lock));
3990 
3991  if (!newl1 || !newl2) {
3992  free(newl1);
3993  free(newl2);
3994  return -ENOLCK;
3995  }
3996  }
3997 
3998  for (lp = &node->locks; *lp;) {
3999  struct lock *l = *lp;
4000  if (l->owner != lock->owner)
4001  goto skip;
4002 
4003  if (lock->type == l->type) {
4004  if (l->end < lock->start - 1)
4005  goto skip;
4006  if (lock->end < l->start - 1)
4007  break;
4008  if (l->start <= lock->start && lock->end <= l->end)
4009  goto out;
4010  if (l->start < lock->start)
4011  lock->start = l->start;
4012  if (lock->end < l->end)
4013  lock->end = l->end;
4014  goto delete;
4015  } else {
4016  if (l->end < lock->start)
4017  goto skip;
4018  if (lock->end < l->start)
4019  break;
4020  if (lock->start <= l->start && l->end <= lock->end)
4021  goto delete;
4022  if (l->end <= lock->end) {
4023  l->end = lock->start - 1;
4024  goto skip;
4025  }
4026  if (lock->start <= l->start) {
4027  l->start = lock->end + 1;
4028  break;
4029  }
4030  *newl2 = *l;
4031  newl2->start = lock->end + 1;
4032  l->end = lock->start - 1;
4033  insert_lock(&l->next, newl2);
4034  newl2 = NULL;
4035  }
4036  skip:
4037  lp = &l->next;
4038  continue;
4039 
4040  delete:
4041  delete_lock(lp);
4042  }
4043  if (lock->type != F_UNLCK) {
4044  *newl1 = *lock;
4045  insert_lock(lp, newl1);
4046  newl1 = NULL;
4047  }
4048 out:
4049  free(newl1);
4050  free(newl2);
4051  return 0;
4052 }
4053 
4054 static void flock_to_lock(struct flock *flock, struct lock *lock)
4055 {
4056  memset(lock, 0, sizeof(struct lock));
4057  lock->type = flock->l_type;
4058  lock->start = flock->l_start;
4059  lock->end =
4060  flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4061  lock->pid = flock->l_pid;
4062 }
4063 
4064 static void lock_to_flock(struct lock *lock, struct flock *flock)
4065 {
4066  flock->l_type = lock->type;
4067  flock->l_start = lock->start;
4068  flock->l_len =
4069  (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4070  flock->l_pid = lock->pid;
4071 }
4072 
4073 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
4074  const char *path, struct fuse_file_info *fi)
4075 {
4076  struct fuse_intr_data d;
4077  struct flock lock;
4078  struct lock l;
4079  int err;
4080  int errlock;
4081 
4082  fuse_prepare_interrupt(f, req, &d);
4083  memset(&lock, 0, sizeof(lock));
4084  lock.l_type = F_UNLCK;
4085  lock.l_whence = SEEK_SET;
4086  err = fuse_fs_flush(f->fs, path, fi);
4087  errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4088  fuse_finish_interrupt(f, req, &d);
4089 
4090  if (errlock != -ENOSYS) {
4091  flock_to_lock(&lock, &l);
4092  l.owner = fi->lock_owner;
4093  pthread_mutex_lock(&f->lock);
4094  locks_insert(get_node(f, ino), &l);
4095  pthread_mutex_unlock(&f->lock);
4096 
4097  /* if op.lock() is defined FLUSH is needed regardless
4098  of op.flush() */
4099  if (err == -ENOSYS)
4100  err = 0;
4101  }
4102  return err;
4103 }
4104 
4105 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
4106  struct fuse_file_info *fi)
4107 {
4108  struct fuse *f = req_fuse_prepare(req);
4109  struct fuse_intr_data d;
4110  char *path;
4111  int err = 0;
4112 
4113  get_path_nullok(f, ino, &path);
4114  if (fi->flush) {
4115  err = fuse_flush_common(f, req, ino, path, fi);
4116  if (err == -ENOSYS)
4117  err = 0;
4118  }
4119 
4120  fuse_prepare_interrupt(f, req, &d);
4121  fuse_do_release(f, ino, path, fi);
4122  fuse_finish_interrupt(f, req, &d);
4123  free_path(f, ino, path);
4124 
4125  reply_err(req, err);
4126 }
4127 
4128 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
4129  struct fuse_file_info *fi)
4130 {
4131  struct fuse *f = req_fuse_prepare(req);
4132  char *path;
4133  int err;
4134 
4135  get_path_nullok(f, ino, &path);
4136  err = fuse_flush_common(f, req, ino, path, fi);
4137  free_path(f, ino, path);
4138 
4139  reply_err(req, err);
4140 }
4141 
4142 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
4143  struct fuse_file_info *fi, struct flock *lock,
4144  int cmd)
4145 {
4146  struct fuse *f = req_fuse_prepare(req);
4147  char *path;
4148  int err;
4149 
4150  err = get_path_nullok(f, ino, &path);
4151  if (!err) {
4152  struct fuse_intr_data d;
4153  fuse_prepare_interrupt(f, req, &d);
4154  err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4155  fuse_finish_interrupt(f, req, &d);
4156  free_path(f, ino, path);
4157  }
4158  return err;
4159 }
4160 
4161 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
4162  struct fuse_file_info *fi, struct flock *lock)
4163 {
4164  int err;
4165  struct lock l;
4166  struct lock *conflict;
4167  struct fuse *f = req_fuse(req);
4168 
4169  flock_to_lock(lock, &l);
4170  l.owner = fi->lock_owner;
4171  pthread_mutex_lock(&f->lock);
4172  conflict = locks_conflict(get_node(f, ino), &l);
4173  if (conflict)
4174  lock_to_flock(conflict, lock);
4175  pthread_mutex_unlock(&f->lock);
4176  if (!conflict)
4177  err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4178  else
4179  err = 0;
4180 
4181  if (!err)
4182  fuse_reply_lock(req, lock);
4183  else
4184  reply_err(req, err);
4185 }
4186 
4187 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
4188  struct fuse_file_info *fi, struct flock *lock,
4189  int sleep)
4190 {
4191  int err = fuse_lock_common(req, ino, fi, lock,
4192  sleep ? F_SETLKW : F_SETLK);
4193  if (!err) {
4194  struct fuse *f = req_fuse(req);
4195  struct lock l;
4196  flock_to_lock(lock, &l);
4197  l.owner = fi->lock_owner;
4198  pthread_mutex_lock(&f->lock);
4199  locks_insert(get_node(f, ino), &l);
4200  pthread_mutex_unlock(&f->lock);
4201  }
4202  reply_err(req, err);
4203 }
4204 
4205 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
4206  struct fuse_file_info *fi, int op)
4207 {
4208  struct fuse *f = req_fuse_prepare(req);
4209  char *path;
4210  int err;
4211 
4212  err = get_path_nullok(f, ino, &path);
4213  if (err == 0) {
4214  struct fuse_intr_data d;
4215  fuse_prepare_interrupt(f, req, &d);
4216  err = fuse_fs_flock(f->fs, path, fi, op);
4217  fuse_finish_interrupt(f, req, &d);
4218  free_path(f, ino, path);
4219  }
4220  reply_err(req, err);
4221 }
4222 
4223 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
4224  uint64_t idx)
4225 {
4226  struct fuse *f = req_fuse_prepare(req);
4227  struct fuse_intr_data d;
4228  char *path;
4229  int err;
4230 
4231  err = get_path(f, ino, &path);
4232  if (!err) {
4233  fuse_prepare_interrupt(f, req, &d);
4234  err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4235  fuse_finish_interrupt(f, req, &d);
4236  free_path(f, ino, path);
4237  }
4238  if (!err)
4239  fuse_reply_bmap(req, idx);
4240  else
4241  reply_err(req, err);
4242 }
4243 
4244 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, unsigned int cmd,
4245  void *arg, struct fuse_file_info *llfi,
4246  unsigned int flags, const void *in_buf,
4247  size_t in_bufsz, size_t out_bufsz)
4248 {
4249  struct fuse *f = req_fuse_prepare(req);
4250  struct fuse_intr_data d;
4251  struct fuse_file_info fi;
4252  char *path, *out_buf = NULL;
4253  int err;
4254 
4255  err = -EPERM;
4256  if (flags & FUSE_IOCTL_UNRESTRICTED)
4257  goto err;
4258 
4259  if (flags & FUSE_IOCTL_DIR)
4260  get_dirhandle(llfi, &fi);
4261  else
4262  fi = *llfi;
4263 
4264  if (out_bufsz) {
4265  err = -ENOMEM;
4266  out_buf = malloc(out_bufsz);
4267  if (!out_buf)
4268  goto err;
4269  }
4270 
4271  assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4272  if (out_buf && in_bufsz)
4273  memcpy(out_buf, in_buf, in_bufsz);
4274 
4275  err = get_path_nullok(f, ino, &path);
4276  if (err)
4277  goto err;
4278 
4279  fuse_prepare_interrupt(f, req, &d);
4280 
4281  err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4282  out_buf ? out_buf : (void *)in_buf);
4283 
4284  fuse_finish_interrupt(f, req, &d);
4285  free_path(f, ino, path);
4286 
4287  fuse_reply_ioctl(req, err, out_buf, out_bufsz);
4288  goto out;
4289 err:
4290  reply_err(req, err);
4291 out:
4292  free(out_buf);
4293 }
4294 
4295 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
4296  struct fuse_file_info *fi, struct fuse_pollhandle *ph)
4297 {
4298  struct fuse *f = req_fuse_prepare(req);
4299  struct fuse_intr_data d;
4300  char *path;
4301  int err;
4302  unsigned revents = 0;
4303 
4304  err = get_path_nullok(f, ino, &path);
4305  if (!err) {
4306  fuse_prepare_interrupt(f, req, &d);
4307  err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4308  fuse_finish_interrupt(f, req, &d);
4309  free_path(f, ino, path);
4310  }
4311  if (!err)
4312  fuse_reply_poll(req, revents);
4313  else
4314  reply_err(req, err);
4315 }
4316 
4317 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
4318  off_t offset, off_t length, struct fuse_file_info *fi)
4319 {
4320  struct fuse *f = req_fuse_prepare(req);
4321  struct fuse_intr_data d;
4322  char *path;
4323  int err;
4324 
4325  err = get_path_nullok(f, ino, &path);
4326  if (!err) {
4327  fuse_prepare_interrupt(f, req, &d);
4328  err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4329  fuse_finish_interrupt(f, req, &d);
4330  free_path(f, ino, path);
4331  }
4332  reply_err(req, err);
4333 }
4334 
4335 static void fuse_lib_copy_file_range(fuse_req_t req, fuse_ino_t nodeid_in,
4336  off_t off_in, struct fuse_file_info *fi_in,
4337  fuse_ino_t nodeid_out, off_t off_out,
4338  struct fuse_file_info *fi_out, size_t len,
4339  int flags)
4340 {
4341  struct fuse *f = req_fuse_prepare(req);
4342  struct fuse_intr_data d;
4343  char *path_in, *path_out;
4344  int err;
4345  ssize_t res;
4346 
4347  err = get_path_nullok(f, nodeid_in, &path_in);
4348  if (err) {
4349  reply_err(req, err);
4350  return;
4351  }
4352 
4353  err = get_path_nullok(f, nodeid_out, &path_out);
4354  if (err) {
4355  free_path(f, nodeid_in, path_in);
4356  reply_err(req, err);
4357  return;
4358  }
4359 
4360  fuse_prepare_interrupt(f, req, &d);
4361  res = fuse_fs_copy_file_range(f->fs, path_in, fi_in, off_in, path_out,
4362  fi_out, off_out, len, flags);
4363  fuse_finish_interrupt(f, req, &d);
4364 
4365  if (res >= 0)
4366  fuse_reply_write(req, res);
4367  else
4368  reply_err(req, res);
4369 
4370  free_path(f, nodeid_in, path_in);
4371  free_path(f, nodeid_out, path_out);
4372 }
4373 
4374 static void fuse_lib_lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
4375  struct fuse_file_info *fi)
4376 {
4377  struct fuse *f = req_fuse_prepare(req);
4378  struct fuse_intr_data d;
4379  char *path;
4380  int err;
4381  off_t res;
4382 
4383  err = get_path(f, ino, &path);
4384  if (err) {
4385  reply_err(req, err);
4386  return;
4387  }
4388 
4389  fuse_prepare_interrupt(f, req, &d);
4390  res = fuse_fs_lseek(f->fs, path, off, whence, fi);
4391  fuse_finish_interrupt(f, req, &d);
4392  free_path(f, ino, path);
4393  if (res >= 0)
4394  fuse_reply_lseek(req, res);
4395  else
4396  reply_err(req, res);
4397 }
4398 
4399 static int clean_delay(struct fuse *f)
4400 {
4401  /*
4402  * This is calculating the delay between clean runs. To
4403  * reduce the number of cleans we are doing them 10 times
4404  * within the remember window.
4405  */
4406  int min_sleep = 60;
4407  int max_sleep = 3600;
4408  int sleep_time = f->conf.remember / 10;
4409 
4410  if (sleep_time > max_sleep)
4411  return max_sleep;
4412  if (sleep_time < min_sleep)
4413  return min_sleep;
4414  return sleep_time;
4415 }
4416 
4417 int fuse_clean_cache(struct fuse *f)
4418 {
4419  struct node_lru *lnode;
4420  struct list_head *curr, *next;
4421  struct node *node;
4422  struct timespec now;
4423 
4424  pthread_mutex_lock(&f->lock);
4425 
4426  curr_time(&now);
4427 
4428  for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4429  double age;
4430 
4431  next = curr->next;
4432  lnode = list_entry(curr, struct node_lru, lru);
4433  node = &lnode->node;
4434 
4435  age = diff_timespec(&now, &lnode->forget_time);
4436  if (age <= f->conf.remember)
4437  break;
4438 
4439  assert(node->nlookup == 1);
4440 
4441  /* Don't forget active directories */
4442  if (node->refctr > 1)
4443  continue;
4444 
4445  node->nlookup = 0;
4446  unhash_name(f, node);
4447  unref_node(f, node);
4448  }
4449  pthread_mutex_unlock(&f->lock);
4450 
4451  return clean_delay(f);
4452 }
4453 
4454 static struct fuse_lowlevel_ops fuse_path_ops = {
4455  .init = fuse_lib_init,
4456  .destroy = fuse_lib_destroy,
4457  .lookup = fuse_lib_lookup,
4458  .forget = fuse_lib_forget,
4459  .forget_multi = fuse_lib_forget_multi,
4460  .getattr = fuse_lib_getattr,
4461  .setattr = fuse_lib_setattr,
4462  .access = fuse_lib_access,
4463  .readlink = fuse_lib_readlink,
4464  .mknod = fuse_lib_mknod,
4465  .mkdir = fuse_lib_mkdir,
4466  .unlink = fuse_lib_unlink,
4467  .rmdir = fuse_lib_rmdir,
4468  .symlink = fuse_lib_symlink,
4469  .rename = fuse_lib_rename,
4470  .link = fuse_lib_link,
4471  .create = fuse_lib_create,
4472  .open = fuse_lib_open,
4473  .read = fuse_lib_read,
4474  .write_buf = fuse_lib_write_buf,
4475  .flush = fuse_lib_flush,
4476  .release = fuse_lib_release,
4477  .fsync = fuse_lib_fsync,
4478  .opendir = fuse_lib_opendir,
4479  .readdir = fuse_lib_readdir,
4480  .readdirplus = fuse_lib_readdirplus,
4481  .releasedir = fuse_lib_releasedir,
4482  .fsyncdir = fuse_lib_fsyncdir,
4483  .statfs = fuse_lib_statfs,
4484  .setxattr = fuse_lib_setxattr,
4485  .getxattr = fuse_lib_getxattr,
4486  .listxattr = fuse_lib_listxattr,
4487  .removexattr = fuse_lib_removexattr,
4488  .getlk = fuse_lib_getlk,
4489  .setlk = fuse_lib_setlk,
4490  .flock = fuse_lib_flock,
4491  .bmap = fuse_lib_bmap,
4492  .ioctl = fuse_lib_ioctl,
4493  .poll = fuse_lib_poll,
4494  .fallocate = fuse_lib_fallocate,
4495  .copy_file_range = fuse_lib_copy_file_range,
4496  .lseek = fuse_lib_lseek,
4497 };
4498 
4499 int fuse_notify_poll(struct fuse_pollhandle *ph)
4500 {
4501  return fuse_lowlevel_notify_poll(ph);
4502 }
4503 
4504 struct fuse_session *fuse_get_session(struct fuse *f)
4505 {
4506  return f->se;
4507 }
4508 
4509 static int fuse_session_loop_remember(struct fuse *f)
4510 {
4511  struct fuse_session *se = f->se;
4512  int res = 0;
4513  struct timespec now;
4514  time_t next_clean;
4515  struct pollfd fds = {
4516  .fd = se->fd,
4517  .events = POLLIN
4518  };
4519  struct fuse_buf fbuf = {
4520  .mem = NULL,
4521  };
4522 
4523  curr_time(&now);
4524  next_clean = now.tv_sec;
4525  while (!fuse_session_exited(se)) {
4526  unsigned timeout;
4527 
4528  curr_time(&now);
4529  if (now.tv_sec < next_clean)
4530  timeout = next_clean - now.tv_sec;
4531  else
4532  timeout = 0;
4533 
4534  res = poll(&fds, 1, timeout * 1000);
4535  if (res == -1) {
4536  if (errno == EINTR)
4537  continue;
4538  else
4539  break;
4540  } else if (res > 0) {
4541  res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4542 
4543  if (res == -EINTR)
4544  continue;
4545  if (res <= 0)
4546  break;
4547 
4548  fuse_session_process_buf_int(se, &fbuf, NULL);
4549  } else {
4550  timeout = fuse_clean_cache(f);
4551  curr_time(&now);
4552  next_clean = now.tv_sec + timeout;
4553  }
4554  }
4555 
4556  free(fbuf.mem);
4557  fuse_session_reset(se);
4558  return res < 0 ? -1 : 0;
4559 }
4560 
4561 int fuse_loop(struct fuse *f)
4562 {
4563  if (!f)
4564  return -1;
4565 
4566  if (lru_enabled(f))
4567  return fuse_session_loop_remember(f);
4568 
4569  return fuse_session_loop(f->se);
4570 }
4571 
4572 FUSE_SYMVER("fuse_loop_mt_32", "fuse_loop_mt@@FUSE_3.2")
4573 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
4574 {
4575  if (f == NULL)
4576  return -1;
4577 
4578  int res = fuse_start_cleanup_thread(f);
4579  if (res)
4580  return -1;
4581 
4582  res = fuse_session_loop_mt_32(fuse_get_session(f), config);
4584  return res;
4585 }
4586 
4587 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
4588 FUSE_SYMVER("fuse_loop_mt_31", "fuse_loop_mt@FUSE_3.0")
4589 int fuse_loop_mt_31(struct fuse *f, int clone_fd)
4590 {
4591  struct fuse_loop_config config;
4592  config.clone_fd = clone_fd;
4593  config.max_idle_threads = 10;
4594  return fuse_loop_mt_32(f, &config);
4595 }
4596 
4597 void fuse_exit(struct fuse *f)
4598 {
4599  fuse_session_exit(f->se);
4600 }
4601 
4603 {
4604  struct fuse_context_i *c = fuse_get_context_internal();
4605 
4606  if (c)
4607  return &c->ctx;
4608  else
4609  return NULL;
4610 }
4611 
4612 int fuse_getgroups(int size, gid_t list[])
4613 {
4614  struct fuse_context_i *c = fuse_get_context_internal();
4615  if (!c)
4616  return -EINVAL;
4617 
4618  return fuse_req_getgroups(c->req, size, list);
4619 }
4620 
4622 {
4623  struct fuse_context_i *c = fuse_get_context_internal();
4624 
4625  if (c)
4626  return fuse_req_interrupted(c->req);
4627  else
4628  return 0;
4629 }
4630 
4631 int fuse_invalidate_path(struct fuse *f, const char *path) {
4632  fuse_ino_t ino;
4633  int err = lookup_path_in_cache(f, path, &ino);
4634  if (err) {
4635  return err;
4636  }
4637 
4638  return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
4639 }
4640 
4641 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4642 
4643 static const struct fuse_opt fuse_lib_opts[] = {
4644  FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
4646  FUSE_LIB_OPT("debug", debug, 1),
4647  FUSE_LIB_OPT("-d", debug, 1),
4648  FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
4649  FUSE_LIB_OPT("auto_cache", auto_cache, 1),
4650  FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
4651  FUSE_LIB_OPT("umask=", set_mode, 1),
4652  FUSE_LIB_OPT("umask=%o", umask, 0),
4653  FUSE_LIB_OPT("uid=", set_uid, 1),
4654  FUSE_LIB_OPT("uid=%d", uid, 0),
4655  FUSE_LIB_OPT("gid=", set_gid, 1),
4656  FUSE_LIB_OPT("gid=%d", gid, 0),
4657  FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
4658  FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
4659  FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
4660  FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
4661  FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
4662  FUSE_LIB_OPT("noforget", remember, -1),
4663  FUSE_LIB_OPT("remember=%u", remember, 0),
4664  FUSE_LIB_OPT("modules=%s", modules, 0),
4665  FUSE_OPT_END
4666 };
4667 
4668 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4669  struct fuse_args *outargs)
4670 {
4671  (void) arg; (void) outargs; (void) data; (void) key;
4672 
4673  /* Pass through unknown options */
4674  return 1;
4675 }
4676 
4677 
4678 static const struct fuse_opt fuse_help_opts[] = {
4679  FUSE_LIB_OPT("modules=%s", modules, 1),
4680  FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP),
4681  FUSE_OPT_END
4682 };
4683 
4684 static void print_module_help(const char *name,
4685  fuse_module_factory_t *fac)
4686 {
4687  struct fuse_args a = FUSE_ARGS_INIT(0, NULL);
4688  if (fuse_opt_add_arg(&a, "") == -1 ||
4689  fuse_opt_add_arg(&a, "-h") == -1)
4690  return;
4691  printf("\nOptions for %s module:\n", name);
4692  (*fac)(&a, NULL);
4693  fuse_opt_free_args(&a);
4694 }
4695 
4696 void fuse_lib_help(struct fuse_args *args)
4697 {
4698  /* These are not all options, but only the ones that
4699  may be of interest to an end-user */
4700  printf(
4701 " -o kernel_cache cache files in kernel\n"
4702 " -o [no]auto_cache enable caching based on modification times (off)\n"
4703 " -o umask=M set file permissions (octal)\n"
4704 " -o uid=N set file owner\n"
4705 " -o gid=N set file group\n"
4706 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4707 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4708 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4709 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4710 " -o noforget never forget cached inodes\n"
4711 " -o remember=T remember cached inodes for T seconds (0s)\n"
4712 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4713 
4714 
4715  /* Print low-level help */
4717 
4718  /* Print help for builtin modules */
4719  print_module_help("subdir", &fuse_module_subdir_factory);
4720 #ifdef HAVE_ICONV
4721  print_module_help("iconv", &fuse_module_iconv_factory);
4722 #endif
4723 
4724  /* Parse command line options in case we need to
4725  activate more modules */
4726  struct fuse_config conf = { .modules = NULL };
4727  if (fuse_opt_parse(args, &conf, fuse_help_opts,
4728  fuse_lib_opt_proc) == -1
4729  || !conf.modules)
4730  return;
4731 
4732  char *module;
4733  char *next;
4734  struct fuse_module *m;
4735 
4736  // Iterate over all modules
4737  for (module = conf.modules; module; module = next) {
4738  char *p;
4739  for (p = module; *p && *p != ':'; p++);
4740  next = *p ? p + 1 : NULL;
4741  *p = '\0';
4742 
4743  m = fuse_get_module(module);
4744  if (m)
4745  print_module_help(module, &m->factory);
4746  }
4747 }
4748 
4749 
4750 
4751 static int fuse_init_intr_signal(int signum, int *installed)
4752 {
4753  struct sigaction old_sa;
4754 
4755  if (sigaction(signum, NULL, &old_sa) == -1) {
4756  perror("fuse: cannot get old signal handler");
4757  return -1;
4758  }
4759 
4760  if (old_sa.sa_handler == SIG_DFL) {
4761  struct sigaction sa;
4762 
4763  memset(&sa, 0, sizeof(struct sigaction));
4764  sa.sa_handler = fuse_intr_sighandler;
4765  sigemptyset(&sa.sa_mask);
4766 
4767  if (sigaction(signum, &sa, NULL) == -1) {
4768  perror("fuse: cannot set interrupt signal handler");
4769  return -1;
4770  }
4771  *installed = 1;
4772  }
4773  return 0;
4774 }
4775 
4776 static void fuse_restore_intr_signal(int signum)
4777 {
4778  struct sigaction sa;
4779 
4780  memset(&sa, 0, sizeof(struct sigaction));
4781  sa.sa_handler = SIG_DFL;
4782  sigaction(signum, &sa, NULL);
4783 }
4784 
4785 
4786 static int fuse_push_module(struct fuse *f, const char *module,
4787  struct fuse_args *args)
4788 {
4789  struct fuse_fs *fs[2] = { f->fs, NULL };
4790  struct fuse_fs *newfs;
4791  struct fuse_module *m = fuse_get_module(module);
4792 
4793  if (!m)
4794  return -1;
4795 
4796  newfs = m->factory(args, fs);
4797  if (!newfs) {
4798  fuse_put_module(m);
4799  return -1;
4800  }
4801  newfs->m = m;
4802  f->fs = newfs;
4803  return 0;
4804 }
4805 
4806 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4807  void *user_data)
4808 {
4809  struct fuse_fs *fs;
4810 
4811  if (sizeof(struct fuse_operations) < op_size) {
4812  fuse_log(FUSE_LOG_ERR, "fuse: warning: library too old, some operations may not not work\n");
4813  op_size = sizeof(struct fuse_operations);
4814  }
4815 
4816  fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4817  if (!fs) {
4818  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse_fs object\n");
4819  return NULL;
4820  }
4821 
4822  fs->user_data = user_data;
4823  if (op)
4824  memcpy(&fs->op, op, op_size);
4825  return fs;
4826 }
4827 
4828 static int node_table_init(struct node_table *t)
4829 {
4830  t->size = NODE_TABLE_MIN_SIZE;
4831  t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4832  if (t->array == NULL) {
4833  fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
4834  return -1;
4835  }
4836  t->use = 0;
4837  t->split = 0;
4838 
4839  return 0;
4840 }
4841 
4842 static void *fuse_prune_nodes(void *fuse)
4843 {
4844  struct fuse *f = fuse;
4845  int sleep_time;
4846 
4847  while(1) {
4848  sleep_time = fuse_clean_cache(f);
4849  sleep(sleep_time);
4850  }
4851  return NULL;
4852 }
4853 
4854 int fuse_start_cleanup_thread(struct fuse *f)
4855 {
4856  if (lru_enabled(f))
4857  return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4858 
4859  return 0;
4860 }
4861 
4862 void fuse_stop_cleanup_thread(struct fuse *f)
4863 {
4864  if (lru_enabled(f)) {
4865  pthread_mutex_lock(&f->lock);
4866  pthread_cancel(f->prune_thread);
4867  pthread_mutex_unlock(&f->lock);
4868  pthread_join(f->prune_thread, NULL);
4869  }
4870 }
4871 
4872 
4873 FUSE_SYMVER("fuse_new_31", "fuse_new@@FUSE_3.1")
4874 struct fuse *fuse_new_31(struct fuse_args *args,
4875  const struct fuse_operations *op,
4876  size_t op_size, void *user_data)
4877 {
4878  struct fuse *f;
4879  struct node *root;
4880  struct fuse_fs *fs;
4881  struct fuse_lowlevel_ops llop = fuse_path_ops;
4882 
4883  f = (struct fuse *) calloc(1, sizeof(struct fuse));
4884  if (f == NULL) {
4885  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse object\n");
4886  goto out;
4887  }
4888 
4889  f->conf.entry_timeout = 1.0;
4890  f->conf.attr_timeout = 1.0;
4891  f->conf.negative_timeout = 0.0;
4892  f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4893 
4894  /* Parse options */
4895  if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4896  fuse_lib_opt_proc) == -1)
4897  goto out_free;
4898 
4899  pthread_mutex_lock(&fuse_context_lock);
4900  static int builtin_modules_registered = 0;
4901  /* Have the builtin modules already been registered? */
4902  if (builtin_modules_registered == 0) {
4903  /* If not, register them. */
4904  fuse_register_module("subdir", fuse_module_subdir_factory, NULL);
4905 #ifdef HAVE_ICONV
4906  fuse_register_module("iconv", fuse_module_iconv_factory, NULL);
4907 #endif
4908  builtin_modules_registered= 1;
4909  }
4910  pthread_mutex_unlock(&fuse_context_lock);
4911 
4912  if (fuse_create_context_key() == -1)
4913  goto out_free;
4914 
4915  fs = fuse_fs_new(op, op_size, user_data);
4916  if (!fs)
4917  goto out_delete_context_key;
4918 
4919  f->fs = fs;
4920 
4921  /* Oh f**k, this is ugly! */
4922  if (!fs->op.lock) {
4923  llop.getlk = NULL;
4924  llop.setlk = NULL;
4925  }
4926 
4927  f->pagesize = getpagesize();
4928  init_list_head(&f->partial_slabs);
4929  init_list_head(&f->full_slabs);
4930  init_list_head(&f->lru_table);
4931 
4932  if (f->conf.modules) {
4933  char *module;
4934  char *next;
4935 
4936  for (module = f->conf.modules; module; module = next) {
4937  char *p;
4938  for (p = module; *p && *p != ':'; p++);
4939  next = *p ? p + 1 : NULL;
4940  *p = '\0';
4941  if (module[0] &&
4942  fuse_push_module(f, module, args) == -1)
4943  goto out_free_fs;
4944  }
4945  }
4946 
4947  if (!f->conf.ac_attr_timeout_set)
4948  f->conf.ac_attr_timeout = f->conf.attr_timeout;
4949 
4950 #if defined(__FreeBSD__) || defined(__NetBSD__)
4951  /*
4952  * In FreeBSD, we always use these settings as inode numbers
4953  * are needed to make getcwd(3) work.
4954  */
4955  f->conf.readdir_ino = 1;
4956 #endif
4957 
4958  f->se = fuse_session_new(args, &llop, sizeof(llop), f);
4959  if (f->se == NULL)
4960  goto out_free_fs;
4961 
4962  if (f->conf.debug) {
4963  fuse_log(FUSE_LOG_DEBUG, "nullpath_ok: %i\n", f->conf.nullpath_ok);
4964  }
4965 
4966  /* Trace topmost layer by default */
4967  f->fs->debug = f->conf.debug;
4968  f->ctr = 0;
4969  f->generation = 0;
4970  if (node_table_init(&f->name_table) == -1)
4971  goto out_free_session;
4972 
4973  if (node_table_init(&f->id_table) == -1)
4974  goto out_free_name_table;
4975 
4976  pthread_mutex_init(&f->lock, NULL);
4977 
4978  root = alloc_node(f);
4979  if (root == NULL) {
4980  fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
4981  goto out_free_id_table;
4982  }
4983  if (lru_enabled(f)) {
4984  struct node_lru *lnode = node_lru(root);
4985  init_list_head(&lnode->lru);
4986  }
4987 
4988  strcpy(root->inline_name, "/");
4989  root->name = root->inline_name;
4990 
4991  if (f->conf.intr &&
4992  fuse_init_intr_signal(f->conf.intr_signal,
4993  &f->intr_installed) == -1)
4994  goto out_free_root;
4995 
4996  root->parent = NULL;
4997  root->nodeid = FUSE_ROOT_ID;
4998  inc_nlookup(root);
4999  hash_id(f, root);
5000 
5001  return f;
5002 
5003 out_free_root:
5004  free(root);
5005 out_free_id_table:
5006  free(f->id_table.array);
5007 out_free_name_table:
5008  free(f->name_table.array);
5009 out_free_session:
5010  fuse_session_destroy(f->se);
5011 out_free_fs:
5012  if (f->fs->m)
5013  fuse_put_module(f->fs->m);
5014  free(f->fs);
5015  free(f->conf.modules);
5016 out_delete_context_key:
5017  fuse_delete_context_key();
5018 out_free:
5019  free(f);
5020 out:
5021  return NULL;
5022 }
5023 
5024 /* Emulates 3.0-style fuse_new(), which processes --help */
5025 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
5026  size_t op_size, void *private_data);
5027 FUSE_SYMVER("fuse_new_30", "fuse_new@FUSE_3.0")
5028 struct fuse *fuse_new_30(struct fuse_args *args,
5029  const struct fuse_operations *op,
5030  size_t op_size, void *user_data)
5031 {
5032  struct fuse_config conf;
5033 
5034  memset(&conf, 0, sizeof(conf));
5035 
5036  const struct fuse_opt opts[] = {
5037  FUSE_LIB_OPT("-h", show_help, 1),
5038  FUSE_LIB_OPT("--help", show_help, 1),
5039  FUSE_OPT_END
5040  };
5041 
5042  if (fuse_opt_parse(args, &conf, opts,
5043  fuse_lib_opt_proc) == -1)
5044  return NULL;
5045 
5046  if (conf.show_help) {
5047  fuse_lib_help(args);
5048  return NULL;
5049  } else
5050  return fuse_new_31(args, op, op_size, user_data);
5051 }
5052 
5053 void fuse_destroy(struct fuse *f)
5054 {
5055  size_t i;
5056 
5057  if (f->conf.intr && f->intr_installed)
5058  fuse_restore_intr_signal(f->conf.intr_signal);
5059 
5060  if (f->fs) {
5061  fuse_create_context(f);
5062 
5063  for (i = 0; i < f->id_table.size; i++) {
5064  struct node *node;
5065 
5066  for (node = f->id_table.array[i]; node != NULL;
5067  node = node->id_next) {
5068  if (node->is_hidden) {
5069  char *path;
5070  if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
5071  fuse_fs_unlink(f->fs, path);
5072  free(path);
5073  }
5074  }
5075  }
5076  }
5077  }
5078  for (i = 0; i < f->id_table.size; i++) {
5079  struct node *node;
5080  struct node *next;
5081 
5082  for (node = f->id_table.array[i]; node != NULL; node = next) {
5083  next = node->id_next;
5084  free_node(f, node);
5085  f->id_table.use--;
5086  }
5087  }
5088  assert(list_empty(&f->partial_slabs));
5089  assert(list_empty(&f->full_slabs));
5090 
5091  while (fuse_modules) {
5092  fuse_put_module(fuse_modules);
5093  }
5094  free(f->id_table.array);
5095  free(f->name_table.array);
5096  pthread_mutex_destroy(&f->lock);
5097  fuse_session_destroy(f->se);
5098  free(f->conf.modules);
5099  free(f);
5100  fuse_delete_context_key();
5101 }
5102 
5103 int fuse_mount(struct fuse *f, const char *mountpoint) {
5104  return fuse_session_mount(fuse_get_session(f), mountpoint);
5105 }
5106 
5107 
5108 void fuse_unmount(struct fuse *f) {
5110 }
5111 
5112 int fuse_version(void)
5113 {
5114  return FUSE_VERSION;
5115 }
5116 
5117 const char *fuse_pkgversion(void)
5118 {
5119  return PACKAGE_VERSION;
5120 }
size_t off
Definition: fuse_common.h:757
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
void fuse_stop_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4862
unsigned capable
Definition: fuse_common.h:459
uint64_t fh
Definition: fuse_common.h:93
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
void fuse_lowlevel_help(void)
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
unsigned int writepage
Definition: fuse_common.h:54
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
unsigned int direct_io
Definition: fuse_common.h:57
int fuse_getgroups(int size, gid_t list[])
Definition: fuse.c:4612
uint32_t poll_events
Definition: fuse_common.h:100
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5103
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
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
Definition: fuse_common.h:124
mode_t umask
void fuse_session_destroy(struct fuse_session *se)
int fuse_version(void)
Definition: fuse.c:5112
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
void fuse_exit(struct fuse *f)
Definition: fuse.c:4597
struct stat attr
Definition: fuse_lowlevel.h:88
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
unsigned int keep_cache
Definition: fuse_common.h:64
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
Definition: fuse_lowlevel.h:59
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4696
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
uint64_t lock_owner
Definition: fuse_common.h:96
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5053
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_loop(struct fuse *f)
Definition: fuse.c:4561
void fuse_session_exit(struct fuse_session *se)
int fuse_reply_lseek(fuse_req_t req, off_t off)
int fuse_session_exited(struct fuse_session *se)
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4631
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4806
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
void * fuse_req_userdata(fuse_req_t req)
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
int fuse_reply_xattr(fuse_req_t req, size_t count)
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:34
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
void fuse_session_reset(struct fuse_session *se)
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
int fuse_reply_poll(fuse_req_t req, unsigned revents)
size_t idx
Definition: fuse_common.h:752
size_t count
Definition: fuse_common.h:747
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
#define FUSE_OPT_END
Definition: fuse_opt.h:104
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4602
enum fuse_buf_flags flags
Definition: fuse_common.h:711
unsigned int flush
Definition: fuse_common.h:69
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:284
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:55
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:211
int fuse_reply_readlink(fuse_req_t req, const char *link)
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
int fuse_reply_err(fuse_req_t req, int err)
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
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)
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
int show_help
Definition: fuse.h:271
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
uint64_t generation
Definition: fuse_lowlevel.h:79
int fuse_start_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4854
void fuse_reply_none(fuse_req_t req)
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
#define FUSE_ROOT_ID
Definition: fuse_lowlevel.h:43
void fuse_log(enum fuse_log_level level, const char *fmt,...)
Definition: fuse_log.c:33
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4504
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:398
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5108
const char * fuse_pkgversion(void)
Definition: fuse.c:5117
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
void fuse_session_unmount(struct fuse_session *se)
unsigned want
Definition: fuse_common.h:467
void * mem
Definition: fuse_common.h:718
struct fuse_buf buf[1]
Definition: fuse_common.h:762
int fuse_reply_write(fuse_req_t req, size_t count)
fuse_fill_dir_flags
Definition: fuse.h:54
int fuse_interrupted(void)
Definition: fuse.c:4621
int fuse_req_interrupted(fuse_req_t req)
size_t size
Definition: fuse_common.h:706
double entry_timeout
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
Definition: fuse.h:1255
int fuse_clean_cache(struct fuse *fuse)
Definition: fuse.c:4417
double attr_timeout
Definition: fuse_lowlevel.h:94
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
void * private_data
Definition: fuse.h:811
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:198
void(* init)(void *userdata, struct fuse_conn_info *conn)
#define FUSE_CAP_EXPORT_SUPPORT
Definition: fuse_common.h:165
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:149
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
fuse_readdir_flags
Definition: fuse.h:42