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 = -ESTALE;
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 == -ESTALE)
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  if (f->conf.no_rofd_flush &&
3277  (fi->flags & O_ACCMODE) == O_RDONLY)
3278  fi->noflush = 1;
3279  }
3280  fuse_finish_interrupt(f, req, &d);
3281  }
3282  if (!err) {
3283  pthread_mutex_lock(&f->lock);
3284  get_node(f, ino)->open_count++;
3285  pthread_mutex_unlock(&f->lock);
3286  if (fuse_reply_open(req, fi) == -ENOENT) {
3287  /* The open syscall was interrupted, so it
3288  must be cancelled */
3289  fuse_do_release(f, ino, path, fi);
3290  }
3291  } else
3292  reply_err(req, err);
3293 
3294  free_path(f, ino, path);
3295 }
3296 
3297 static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
3298  off_t off, struct fuse_file_info *fi)
3299 {
3300  struct fuse *f = req_fuse_prepare(req);
3301  struct fuse_bufvec *buf = NULL;
3302  char *path;
3303  int res;
3304 
3305  res = get_path_nullok(f, ino, &path);
3306  if (res == 0) {
3307  struct fuse_intr_data d;
3308 
3309  fuse_prepare_interrupt(f, req, &d);
3310  res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3311  fuse_finish_interrupt(f, req, &d);
3312  free_path(f, ino, path);
3313  }
3314 
3315  if (res == 0)
3317  else
3318  reply_err(req, res);
3319 
3320  fuse_free_buf(buf);
3321 }
3322 
3323 static void fuse_lib_write_buf(fuse_req_t req, fuse_ino_t ino,
3324  struct fuse_bufvec *buf, off_t off,
3325  struct fuse_file_info *fi)
3326 {
3327  struct fuse *f = req_fuse_prepare(req);
3328  char *path;
3329  int res;
3330 
3331  res = get_path_nullok(f, ino, &path);
3332  if (res == 0) {
3333  struct fuse_intr_data d;
3334 
3335  fuse_prepare_interrupt(f, req, &d);
3336  res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3337  fuse_finish_interrupt(f, req, &d);
3338  free_path(f, ino, path);
3339  }
3340 
3341  if (res >= 0)
3342  fuse_reply_write(req, res);
3343  else
3344  reply_err(req, res);
3345 }
3346 
3347 static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
3348  struct fuse_file_info *fi)
3349 {
3350  struct fuse *f = req_fuse_prepare(req);
3351  char *path;
3352  int err;
3353 
3354  err = get_path_nullok(f, ino, &path);
3355  if (!err) {
3356  struct fuse_intr_data d;
3357 
3358  fuse_prepare_interrupt(f, req, &d);
3359  err = fuse_fs_fsync(f->fs, path, datasync, fi);
3360  fuse_finish_interrupt(f, req, &d);
3361  free_path(f, ino, path);
3362  }
3363  reply_err(req, err);
3364 }
3365 
3366 static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
3367  struct fuse_file_info *fi)
3368 {
3369  struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
3370  memset(fi, 0, sizeof(struct fuse_file_info));
3371  fi->fh = dh->fh;
3372  return dh;
3373 }
3374 
3375 static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
3376  struct fuse_file_info *llfi)
3377 {
3378  struct fuse *f = req_fuse_prepare(req);
3379  struct fuse_intr_data d;
3380  struct fuse_dh *dh;
3381  struct fuse_file_info fi;
3382  char *path;
3383  int err;
3384 
3385  dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
3386  if (dh == NULL) {
3387  reply_err(req, -ENOMEM);
3388  return;
3389  }
3390  memset(dh, 0, sizeof(struct fuse_dh));
3391  dh->fuse = f;
3392  dh->contents = NULL;
3393  dh->first = NULL;
3394  dh->len = 0;
3395  dh->filled = 0;
3396  dh->nodeid = ino;
3397  pthread_mutex_init(&dh->lock, NULL);
3398 
3399  llfi->fh = (uintptr_t) dh;
3400 
3401  memset(&fi, 0, sizeof(fi));
3402  fi.flags = llfi->flags;
3403 
3404  err = get_path(f, ino, &path);
3405  if (!err) {
3406  fuse_prepare_interrupt(f, req, &d);
3407  err = fuse_fs_opendir(f->fs, path, &fi);
3408  fuse_finish_interrupt(f, req, &d);
3409  dh->fh = fi.fh;
3410  }
3411  if (!err) {
3412  if (fuse_reply_open(req, llfi) == -ENOENT) {
3413  /* The opendir syscall was interrupted, so it
3414  must be cancelled */
3415  fuse_fs_releasedir(f->fs, path, &fi);
3416  pthread_mutex_destroy(&dh->lock);
3417  free(dh);
3418  }
3419  } else {
3420  reply_err(req, err);
3421  pthread_mutex_destroy(&dh->lock);
3422  free(dh);
3423  }
3424  free_path(f, ino, path);
3425 }
3426 
3427 static int extend_contents(struct fuse_dh *dh, unsigned minsize)
3428 {
3429  if (minsize > dh->size) {
3430  char *newptr;
3431  unsigned newsize = dh->size;
3432  if (!newsize)
3433  newsize = 1024;
3434  while (newsize < minsize) {
3435  if (newsize >= 0x80000000)
3436  newsize = 0xffffffff;
3437  else
3438  newsize *= 2;
3439  }
3440 
3441  newptr = (char *) realloc(dh->contents, newsize);
3442  if (!newptr) {
3443  dh->error = -ENOMEM;
3444  return -1;
3445  }
3446  dh->contents = newptr;
3447  dh->size = newsize;
3448  }
3449  return 0;
3450 }
3451 
3452 static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name,
3453  struct stat *st)
3454 {
3455  struct fuse_direntry *de;
3456 
3457  de = malloc(sizeof(struct fuse_direntry));
3458  if (!de) {
3459  dh->error = -ENOMEM;
3460  return -1;
3461  }
3462  de->name = strdup(name);
3463  if (!de->name) {
3464  dh->error = -ENOMEM;
3465  free(de);
3466  return -1;
3467  }
3468  de->stat = *st;
3469  de->next = NULL;
3470 
3471  *dh->last = de;
3472  dh->last = &de->next;
3473 
3474  return 0;
3475 }
3476 
3477 static fuse_ino_t lookup_nodeid(struct fuse *f, fuse_ino_t parent,
3478  const char *name)
3479 {
3480  struct node *node;
3481  fuse_ino_t res = FUSE_UNKNOWN_INO;
3482 
3483  pthread_mutex_lock(&f->lock);
3484  node = lookup_node(f, parent, name);
3485  if (node)
3486  res = node->nodeid;
3487  pthread_mutex_unlock(&f->lock);
3488 
3489  return res;
3490 }
3491 
3492 static int fill_dir(void *dh_, const char *name, const struct stat *statp,
3493  off_t off, enum fuse_fill_dir_flags flags)
3494 {
3495  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3496  struct stat stbuf;
3497 
3498  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3499  dh->error = -EIO;
3500  return 1;
3501  }
3502 
3503  if (statp)
3504  stbuf = *statp;
3505  else {
3506  memset(&stbuf, 0, sizeof(stbuf));
3507  stbuf.st_ino = FUSE_UNKNOWN_INO;
3508  }
3509 
3510  if (!dh->fuse->conf.use_ino) {
3511  stbuf.st_ino = FUSE_UNKNOWN_INO;
3512  if (dh->fuse->conf.readdir_ino) {
3513  stbuf.st_ino = (ino_t)
3514  lookup_nodeid(dh->fuse, dh->nodeid, name);
3515  }
3516  }
3517 
3518  if (off) {
3519  size_t newlen;
3520 
3521  if (dh->filled) {
3522  dh->error = -EIO;
3523  return 1;
3524  }
3525 
3526  if (dh->first) {
3527  dh->error = -EIO;
3528  return 1;
3529  }
3530 
3531  if (extend_contents(dh, dh->needlen) == -1)
3532  return 1;
3533 
3534  newlen = dh->len +
3535  fuse_add_direntry(dh->req, dh->contents + dh->len,
3536  dh->needlen - dh->len, name,
3537  &stbuf, off);
3538  if (newlen > dh->needlen)
3539  return 1;
3540 
3541  dh->len = newlen;
3542  } else {
3543  dh->filled = 1;
3544 
3545  if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3546  return 1;
3547  }
3548  return 0;
3549 }
3550 
3551 static int is_dot_or_dotdot(const char *name)
3552 {
3553  return name[0] == '.' && (name[1] == '\0' ||
3554  (name[1] == '.' && name[2] == '\0'));
3555 }
3556 
3557 static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
3558  off_t off, enum fuse_fill_dir_flags flags)
3559 {
3560  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3561  struct fuse_entry_param e = {
3562  /* ino=0 tells the kernel to ignore readdirplus stat info */
3563  .ino = 0,
3564  };
3565  struct fuse *f = dh->fuse;
3566  int res;
3567 
3568  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3569  dh->error = -EIO;
3570  return 1;
3571  }
3572 
3573  if (statp && (flags & FUSE_FILL_DIR_PLUS)) {
3574  e.attr = *statp;
3575 
3576  if (!is_dot_or_dotdot(name)) {
3577  res = do_lookup(f, dh->nodeid, name, &e);
3578  if (res) {
3579  dh->error = res;
3580  return 1;
3581  }
3582  }
3583  } else {
3584  e.attr.st_ino = FUSE_UNKNOWN_INO;
3585  if (statp) {
3586  e.attr.st_mode = statp->st_mode;
3587  if (f->conf.use_ino)
3588  e.attr.st_ino = statp->st_ino;
3589  }
3590  if (!f->conf.use_ino && f->conf.readdir_ino) {
3591  e.attr.st_ino = (ino_t)
3592  lookup_nodeid(f, dh->nodeid, name);
3593  }
3594  }
3595 
3596  if (off) {
3597  size_t newlen;
3598 
3599  if (dh->filled) {
3600  dh->error = -EIO;
3601  return 1;
3602  }
3603 
3604  if (dh->first) {
3605  dh->error = -EIO;
3606  return 1;
3607  }
3608  if (extend_contents(dh, dh->needlen) == -1)
3609  return 1;
3610 
3611  newlen = dh->len +
3612  fuse_add_direntry_plus(dh->req, dh->contents + dh->len,
3613  dh->needlen - dh->len, name,
3614  &e, off);
3615  if (newlen > dh->needlen)
3616  return 1;
3617  dh->len = newlen;
3618  } else {
3619  dh->filled = 1;
3620 
3621  if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1)
3622  return 1;
3623  }
3624 
3625  return 0;
3626 }
3627 
3628 static void free_direntries(struct fuse_direntry *de)
3629 {
3630  while (de) {
3631  struct fuse_direntry *next = de->next;
3632  free(de->name);
3633  free(de);
3634  de = next;
3635  }
3636 }
3637 
3638 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3639  size_t size, off_t off, struct fuse_dh *dh,
3640  struct fuse_file_info *fi,
3641  enum fuse_readdir_flags flags)
3642 {
3643  char *path;
3644  int err;
3645 
3646  if (f->fs->op.readdir)
3647  err = get_path_nullok(f, ino, &path);
3648  else
3649  err = get_path(f, ino, &path);
3650  if (!err) {
3651  struct fuse_intr_data d;
3652  fuse_fill_dir_t filler = fill_dir;
3653 
3654  if (flags & FUSE_READDIR_PLUS)
3655  filler = fill_dir_plus;
3656 
3657  free_direntries(dh->first);
3658  dh->first = NULL;
3659  dh->last = &dh->first;
3660  dh->len = 0;
3661  dh->error = 0;
3662  dh->needlen = size;
3663  dh->filled = 0;
3664  dh->req = req;
3665  fuse_prepare_interrupt(f, req, &d);
3666  err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3667  fuse_finish_interrupt(f, req, &d);
3668  dh->req = NULL;
3669  if (!err)
3670  err = dh->error;
3671  if (err)
3672  dh->filled = 0;
3673  free_path(f, ino, path);
3674  }
3675  return err;
3676 }
3677 
3678 static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh,
3679  off_t off, enum fuse_readdir_flags flags)
3680 {
3681  off_t pos;
3682  struct fuse_direntry *de = dh->first;
3683 
3684  dh->len = 0;
3685 
3686  if (extend_contents(dh, dh->needlen) == -1)
3687  return dh->error;
3688 
3689  for (pos = 0; pos < off; pos++) {
3690  if (!de)
3691  break;
3692 
3693  de = de->next;
3694  }
3695  while (de) {
3696  char *p = dh->contents + dh->len;
3697  unsigned rem = dh->needlen - dh->len;
3698  unsigned thislen;
3699  unsigned newlen;
3700  pos++;
3701 
3702  if (flags & FUSE_READDIR_PLUS) {
3703  struct fuse_entry_param e = {
3704  .ino = 0,
3705  .attr = de->stat,
3706  };
3707  thislen = fuse_add_direntry_plus(req, p, rem,
3708  de->name, &e, pos);
3709  } else {
3710  thislen = fuse_add_direntry(req, p, rem,
3711  de->name, &de->stat, pos);
3712  }
3713  newlen = dh->len + thislen;
3714  if (newlen > dh->needlen)
3715  break;
3716  dh->len = newlen;
3717  de = de->next;
3718  }
3719  return 0;
3720 }
3721 
3722 static void fuse_readdir_common(fuse_req_t req, fuse_ino_t ino, size_t size,
3723  off_t off, struct fuse_file_info *llfi,
3724  enum fuse_readdir_flags flags)
3725 {
3726  struct fuse *f = req_fuse_prepare(req);
3727  struct fuse_file_info fi;
3728  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3729  int err;
3730 
3731  pthread_mutex_lock(&dh->lock);
3732  /* According to SUS, directory contents need to be refreshed on
3733  rewinddir() */
3734  if (!off)
3735  dh->filled = 0;
3736 
3737  if (!dh->filled) {
3738  err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3739  if (err) {
3740  reply_err(req, err);
3741  goto out;
3742  }
3743  }
3744  if (dh->filled) {
3745  dh->needlen = size;
3746  err = readdir_fill_from_list(req, dh, off, flags);
3747  if (err) {
3748  reply_err(req, err);
3749  goto out;
3750  }
3751  }
3752  fuse_reply_buf(req, dh->contents, dh->len);
3753 out:
3754  pthread_mutex_unlock(&dh->lock);
3755 }
3756 
3757 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3758  off_t off, struct fuse_file_info *llfi)
3759 {
3760  fuse_readdir_common(req, ino, size, off, llfi, 0);
3761 }
3762 
3763 static void fuse_lib_readdirplus(fuse_req_t req, fuse_ino_t ino, size_t size,
3764  off_t off, struct fuse_file_info *llfi)
3765 {
3766  fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3767 }
3768 
3769 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3770  struct fuse_file_info *llfi)
3771 {
3772  struct fuse *f = req_fuse_prepare(req);
3773  struct fuse_intr_data d;
3774  struct fuse_file_info fi;
3775  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3776  char *path;
3777 
3778  get_path_nullok(f, ino, &path);
3779 
3780  fuse_prepare_interrupt(f, req, &d);
3781  fuse_fs_releasedir(f->fs, path, &fi);
3782  fuse_finish_interrupt(f, req, &d);
3783  free_path(f, ino, path);
3784 
3785  pthread_mutex_lock(&dh->lock);
3786  pthread_mutex_unlock(&dh->lock);
3787  pthread_mutex_destroy(&dh->lock);
3788  free_direntries(dh->first);
3789  free(dh->contents);
3790  free(dh);
3791  reply_err(req, 0);
3792 }
3793 
3794 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3795  struct fuse_file_info *llfi)
3796 {
3797  struct fuse *f = req_fuse_prepare(req);
3798  struct fuse_file_info fi;
3799  char *path;
3800  int err;
3801 
3802  get_dirhandle(llfi, &fi);
3803 
3804  err = get_path_nullok(f, ino, &path);
3805  if (!err) {
3806  struct fuse_intr_data d;
3807  fuse_prepare_interrupt(f, req, &d);
3808  err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3809  fuse_finish_interrupt(f, req, &d);
3810  free_path(f, ino, path);
3811  }
3812  reply_err(req, err);
3813 }
3814 
3815 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3816 {
3817  struct fuse *f = req_fuse_prepare(req);
3818  struct statvfs buf;
3819  char *path = NULL;
3820  int err = 0;
3821 
3822  memset(&buf, 0, sizeof(buf));
3823  if (ino)
3824  err = get_path(f, ino, &path);
3825 
3826  if (!err) {
3827  struct fuse_intr_data d;
3828  fuse_prepare_interrupt(f, req, &d);
3829  err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3830  fuse_finish_interrupt(f, req, &d);
3831  free_path(f, ino, path);
3832  }
3833 
3834  if (!err)
3835  fuse_reply_statfs(req, &buf);
3836  else
3837  reply_err(req, err);
3838 }
3839 
3840 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3841  const char *value, size_t size, int flags)
3842 {
3843  struct fuse *f = req_fuse_prepare(req);
3844  char *path;
3845  int err;
3846 
3847  err = get_path(f, ino, &path);
3848  if (!err) {
3849  struct fuse_intr_data d;
3850  fuse_prepare_interrupt(f, req, &d);
3851  err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3852  fuse_finish_interrupt(f, req, &d);
3853  free_path(f, ino, path);
3854  }
3855  reply_err(req, err);
3856 }
3857 
3858 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3859  const char *name, char *value, size_t size)
3860 {
3861  int err;
3862  char *path;
3863 
3864  err = get_path(f, ino, &path);
3865  if (!err) {
3866  struct fuse_intr_data d;
3867  fuse_prepare_interrupt(f, req, &d);
3868  err = fuse_fs_getxattr(f->fs, path, name, value, size);
3869  fuse_finish_interrupt(f, req, &d);
3870  free_path(f, ino, path);
3871  }
3872  return err;
3873 }
3874 
3875 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3876  size_t size)
3877 {
3878  struct fuse *f = req_fuse_prepare(req);
3879  int res;
3880 
3881  if (size) {
3882  char *value = (char *) malloc(size);
3883  if (value == NULL) {
3884  reply_err(req, -ENOMEM);
3885  return;
3886  }
3887  res = common_getxattr(f, req, ino, name, value, size);
3888  if (res > 0)
3889  fuse_reply_buf(req, value, res);
3890  else
3891  reply_err(req, res);
3892  free(value);
3893  } else {
3894  res = common_getxattr(f, req, ino, name, NULL, 0);
3895  if (res >= 0)
3896  fuse_reply_xattr(req, res);
3897  else
3898  reply_err(req, res);
3899  }
3900 }
3901 
3902 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3903  char *list, size_t size)
3904 {
3905  char *path;
3906  int err;
3907 
3908  err = get_path(f, ino, &path);
3909  if (!err) {
3910  struct fuse_intr_data d;
3911  fuse_prepare_interrupt(f, req, &d);
3912  err = fuse_fs_listxattr(f->fs, path, list, size);
3913  fuse_finish_interrupt(f, req, &d);
3914  free_path(f, ino, path);
3915  }
3916  return err;
3917 }
3918 
3919 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3920 {
3921  struct fuse *f = req_fuse_prepare(req);
3922  int res;
3923 
3924  if (size) {
3925  char *list = (char *) malloc(size);
3926  if (list == NULL) {
3927  reply_err(req, -ENOMEM);
3928  return;
3929  }
3930  res = common_listxattr(f, req, ino, list, size);
3931  if (res > 0)
3932  fuse_reply_buf(req, list, res);
3933  else
3934  reply_err(req, res);
3935  free(list);
3936  } else {
3937  res = common_listxattr(f, req, ino, NULL, 0);
3938  if (res >= 0)
3939  fuse_reply_xattr(req, res);
3940  else
3941  reply_err(req, res);
3942  }
3943 }
3944 
3945 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3946  const char *name)
3947 {
3948  struct fuse *f = req_fuse_prepare(req);
3949  char *path;
3950  int err;
3951 
3952  err = get_path(f, ino, &path);
3953  if (!err) {
3954  struct fuse_intr_data d;
3955  fuse_prepare_interrupt(f, req, &d);
3956  err = fuse_fs_removexattr(f->fs, path, name);
3957  fuse_finish_interrupt(f, req, &d);
3958  free_path(f, ino, path);
3959  }
3960  reply_err(req, err);
3961 }
3962 
3963 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3964 {
3965  struct lock *l;
3966 
3967  for (l = node->locks; l; l = l->next)
3968  if (l->owner != lock->owner &&
3969  lock->start <= l->end && l->start <= lock->end &&
3970  (l->type == F_WRLCK || lock->type == F_WRLCK))
3971  break;
3972 
3973  return l;
3974 }
3975 
3976 static void delete_lock(struct lock **lockp)
3977 {
3978  struct lock *l = *lockp;
3979  *lockp = l->next;
3980  free(l);
3981 }
3982 
3983 static void insert_lock(struct lock **pos, struct lock *lock)
3984 {
3985  lock->next = *pos;
3986  *pos = lock;
3987 }
3988 
3989 static int locks_insert(struct node *node, struct lock *lock)
3990 {
3991  struct lock **lp;
3992  struct lock *newl1 = NULL;
3993  struct lock *newl2 = NULL;
3994 
3995  if (lock->type != F_UNLCK || lock->start != 0 ||
3996  lock->end != OFFSET_MAX) {
3997  newl1 = malloc(sizeof(struct lock));
3998  newl2 = malloc(sizeof(struct lock));
3999 
4000  if (!newl1 || !newl2) {
4001  free(newl1);
4002  free(newl2);
4003  return -ENOLCK;
4004  }
4005  }
4006 
4007  for (lp = &node->locks; *lp;) {
4008  struct lock *l = *lp;
4009  if (l->owner != lock->owner)
4010  goto skip;
4011 
4012  if (lock->type == l->type) {
4013  if (l->end < lock->start - 1)
4014  goto skip;
4015  if (lock->end < l->start - 1)
4016  break;
4017  if (l->start <= lock->start && lock->end <= l->end)
4018  goto out;
4019  if (l->start < lock->start)
4020  lock->start = l->start;
4021  if (lock->end < l->end)
4022  lock->end = l->end;
4023  goto delete;
4024  } else {
4025  if (l->end < lock->start)
4026  goto skip;
4027  if (lock->end < l->start)
4028  break;
4029  if (lock->start <= l->start && l->end <= lock->end)
4030  goto delete;
4031  if (l->end <= lock->end) {
4032  l->end = lock->start - 1;
4033  goto skip;
4034  }
4035  if (lock->start <= l->start) {
4036  l->start = lock->end + 1;
4037  break;
4038  }
4039  *newl2 = *l;
4040  newl2->start = lock->end + 1;
4041  l->end = lock->start - 1;
4042  insert_lock(&l->next, newl2);
4043  newl2 = NULL;
4044  }
4045  skip:
4046  lp = &l->next;
4047  continue;
4048 
4049  delete:
4050  delete_lock(lp);
4051  }
4052  if (lock->type != F_UNLCK) {
4053  *newl1 = *lock;
4054  insert_lock(lp, newl1);
4055  newl1 = NULL;
4056  }
4057 out:
4058  free(newl1);
4059  free(newl2);
4060  return 0;
4061 }
4062 
4063 static void flock_to_lock(struct flock *flock, struct lock *lock)
4064 {
4065  memset(lock, 0, sizeof(struct lock));
4066  lock->type = flock->l_type;
4067  lock->start = flock->l_start;
4068  lock->end =
4069  flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4070  lock->pid = flock->l_pid;
4071 }
4072 
4073 static void lock_to_flock(struct lock *lock, struct flock *flock)
4074 {
4075  flock->l_type = lock->type;
4076  flock->l_start = lock->start;
4077  flock->l_len =
4078  (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4079  flock->l_pid = lock->pid;
4080 }
4081 
4082 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
4083  const char *path, struct fuse_file_info *fi)
4084 {
4085  struct fuse_intr_data d;
4086  struct flock lock;
4087  struct lock l;
4088  int err;
4089  int errlock;
4090 
4091  fuse_prepare_interrupt(f, req, &d);
4092  memset(&lock, 0, sizeof(lock));
4093  lock.l_type = F_UNLCK;
4094  lock.l_whence = SEEK_SET;
4095  err = fuse_fs_flush(f->fs, path, fi);
4096  errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4097  fuse_finish_interrupt(f, req, &d);
4098 
4099  if (errlock != -ENOSYS) {
4100  flock_to_lock(&lock, &l);
4101  l.owner = fi->lock_owner;
4102  pthread_mutex_lock(&f->lock);
4103  locks_insert(get_node(f, ino), &l);
4104  pthread_mutex_unlock(&f->lock);
4105 
4106  /* if op.lock() is defined FLUSH is needed regardless
4107  of op.flush() */
4108  if (err == -ENOSYS)
4109  err = 0;
4110  }
4111  return err;
4112 }
4113 
4114 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
4115  struct fuse_file_info *fi)
4116 {
4117  struct fuse *f = req_fuse_prepare(req);
4118  struct fuse_intr_data d;
4119  char *path;
4120  int err = 0;
4121 
4122  get_path_nullok(f, ino, &path);
4123  if (fi->flush) {
4124  err = fuse_flush_common(f, req, ino, path, fi);
4125  if (err == -ENOSYS)
4126  err = 0;
4127  }
4128 
4129  fuse_prepare_interrupt(f, req, &d);
4130  fuse_do_release(f, ino, path, fi);
4131  fuse_finish_interrupt(f, req, &d);
4132  free_path(f, ino, path);
4133 
4134  reply_err(req, err);
4135 }
4136 
4137 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
4138  struct fuse_file_info *fi)
4139 {
4140  struct fuse *f = req_fuse_prepare(req);
4141  char *path;
4142  int err;
4143 
4144  get_path_nullok(f, ino, &path);
4145  err = fuse_flush_common(f, req, ino, path, fi);
4146  free_path(f, ino, path);
4147 
4148  reply_err(req, err);
4149 }
4150 
4151 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
4152  struct fuse_file_info *fi, struct flock *lock,
4153  int cmd)
4154 {
4155  struct fuse *f = req_fuse_prepare(req);
4156  char *path;
4157  int err;
4158 
4159  err = get_path_nullok(f, ino, &path);
4160  if (!err) {
4161  struct fuse_intr_data d;
4162  fuse_prepare_interrupt(f, req, &d);
4163  err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4164  fuse_finish_interrupt(f, req, &d);
4165  free_path(f, ino, path);
4166  }
4167  return err;
4168 }
4169 
4170 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
4171  struct fuse_file_info *fi, struct flock *lock)
4172 {
4173  int err;
4174  struct lock l;
4175  struct lock *conflict;
4176  struct fuse *f = req_fuse(req);
4177 
4178  flock_to_lock(lock, &l);
4179  l.owner = fi->lock_owner;
4180  pthread_mutex_lock(&f->lock);
4181  conflict = locks_conflict(get_node(f, ino), &l);
4182  if (conflict)
4183  lock_to_flock(conflict, lock);
4184  pthread_mutex_unlock(&f->lock);
4185  if (!conflict)
4186  err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4187  else
4188  err = 0;
4189 
4190  if (!err)
4191  fuse_reply_lock(req, lock);
4192  else
4193  reply_err(req, err);
4194 }
4195 
4196 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
4197  struct fuse_file_info *fi, struct flock *lock,
4198  int sleep)
4199 {
4200  int err = fuse_lock_common(req, ino, fi, lock,
4201  sleep ? F_SETLKW : F_SETLK);
4202  if (!err) {
4203  struct fuse *f = req_fuse(req);
4204  struct lock l;
4205  flock_to_lock(lock, &l);
4206  l.owner = fi->lock_owner;
4207  pthread_mutex_lock(&f->lock);
4208  locks_insert(get_node(f, ino), &l);
4209  pthread_mutex_unlock(&f->lock);
4210  }
4211  reply_err(req, err);
4212 }
4213 
4214 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
4215  struct fuse_file_info *fi, int op)
4216 {
4217  struct fuse *f = req_fuse_prepare(req);
4218  char *path;
4219  int err;
4220 
4221  err = get_path_nullok(f, ino, &path);
4222  if (err == 0) {
4223  struct fuse_intr_data d;
4224  fuse_prepare_interrupt(f, req, &d);
4225  err = fuse_fs_flock(f->fs, path, fi, op);
4226  fuse_finish_interrupt(f, req, &d);
4227  free_path(f, ino, path);
4228  }
4229  reply_err(req, err);
4230 }
4231 
4232 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
4233  uint64_t idx)
4234 {
4235  struct fuse *f = req_fuse_prepare(req);
4236  struct fuse_intr_data d;
4237  char *path;
4238  int err;
4239 
4240  err = get_path(f, ino, &path);
4241  if (!err) {
4242  fuse_prepare_interrupt(f, req, &d);
4243  err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4244  fuse_finish_interrupt(f, req, &d);
4245  free_path(f, ino, path);
4246  }
4247  if (!err)
4248  fuse_reply_bmap(req, idx);
4249  else
4250  reply_err(req, err);
4251 }
4252 
4253 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, unsigned int cmd,
4254  void *arg, struct fuse_file_info *llfi,
4255  unsigned int flags, const void *in_buf,
4256  size_t in_bufsz, size_t out_bufsz)
4257 {
4258  struct fuse *f = req_fuse_prepare(req);
4259  struct fuse_intr_data d;
4260  struct fuse_file_info fi;
4261  char *path, *out_buf = NULL;
4262  int err;
4263 
4264  err = -EPERM;
4265  if (flags & FUSE_IOCTL_UNRESTRICTED)
4266  goto err;
4267 
4268  if (flags & FUSE_IOCTL_DIR)
4269  get_dirhandle(llfi, &fi);
4270  else
4271  fi = *llfi;
4272 
4273  if (out_bufsz) {
4274  err = -ENOMEM;
4275  out_buf = malloc(out_bufsz);
4276  if (!out_buf)
4277  goto err;
4278  }
4279 
4280  assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4281  if (out_buf && in_bufsz)
4282  memcpy(out_buf, in_buf, in_bufsz);
4283 
4284  err = get_path_nullok(f, ino, &path);
4285  if (err)
4286  goto err;
4287 
4288  fuse_prepare_interrupt(f, req, &d);
4289 
4290  err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4291  out_buf ? out_buf : (void *)in_buf);
4292 
4293  fuse_finish_interrupt(f, req, &d);
4294  free_path(f, ino, path);
4295 
4296  if (err < 0)
4297  goto err;
4298  fuse_reply_ioctl(req, err, out_buf, out_bufsz);
4299  goto out;
4300 err:
4301  reply_err(req, err);
4302 out:
4303  free(out_buf);
4304 }
4305 
4306 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
4307  struct fuse_file_info *fi, struct fuse_pollhandle *ph)
4308 {
4309  struct fuse *f = req_fuse_prepare(req);
4310  struct fuse_intr_data d;
4311  char *path;
4312  int err;
4313  unsigned revents = 0;
4314 
4315  err = get_path_nullok(f, ino, &path);
4316  if (!err) {
4317  fuse_prepare_interrupt(f, req, &d);
4318  err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4319  fuse_finish_interrupt(f, req, &d);
4320  free_path(f, ino, path);
4321  }
4322  if (!err)
4323  fuse_reply_poll(req, revents);
4324  else
4325  reply_err(req, err);
4326 }
4327 
4328 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
4329  off_t offset, off_t length, struct fuse_file_info *fi)
4330 {
4331  struct fuse *f = req_fuse_prepare(req);
4332  struct fuse_intr_data d;
4333  char *path;
4334  int err;
4335 
4336  err = get_path_nullok(f, ino, &path);
4337  if (!err) {
4338  fuse_prepare_interrupt(f, req, &d);
4339  err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4340  fuse_finish_interrupt(f, req, &d);
4341  free_path(f, ino, path);
4342  }
4343  reply_err(req, err);
4344 }
4345 
4346 static void fuse_lib_copy_file_range(fuse_req_t req, fuse_ino_t nodeid_in,
4347  off_t off_in, struct fuse_file_info *fi_in,
4348  fuse_ino_t nodeid_out, off_t off_out,
4349  struct fuse_file_info *fi_out, size_t len,
4350  int flags)
4351 {
4352  struct fuse *f = req_fuse_prepare(req);
4353  struct fuse_intr_data d;
4354  char *path_in, *path_out;
4355  int err;
4356  ssize_t res;
4357 
4358  err = get_path_nullok(f, nodeid_in, &path_in);
4359  if (err) {
4360  reply_err(req, err);
4361  return;
4362  }
4363 
4364  err = get_path_nullok(f, nodeid_out, &path_out);
4365  if (err) {
4366  free_path(f, nodeid_in, path_in);
4367  reply_err(req, err);
4368  return;
4369  }
4370 
4371  fuse_prepare_interrupt(f, req, &d);
4372  res = fuse_fs_copy_file_range(f->fs, path_in, fi_in, off_in, path_out,
4373  fi_out, off_out, len, flags);
4374  fuse_finish_interrupt(f, req, &d);
4375 
4376  if (res >= 0)
4377  fuse_reply_write(req, res);
4378  else
4379  reply_err(req, res);
4380 
4381  free_path(f, nodeid_in, path_in);
4382  free_path(f, nodeid_out, path_out);
4383 }
4384 
4385 static void fuse_lib_lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
4386  struct fuse_file_info *fi)
4387 {
4388  struct fuse *f = req_fuse_prepare(req);
4389  struct fuse_intr_data d;
4390  char *path;
4391  int err;
4392  off_t res;
4393 
4394  err = get_path(f, ino, &path);
4395  if (err) {
4396  reply_err(req, err);
4397  return;
4398  }
4399 
4400  fuse_prepare_interrupt(f, req, &d);
4401  res = fuse_fs_lseek(f->fs, path, off, whence, fi);
4402  fuse_finish_interrupt(f, req, &d);
4403  free_path(f, ino, path);
4404  if (res >= 0)
4405  fuse_reply_lseek(req, res);
4406  else
4407  reply_err(req, res);
4408 }
4409 
4410 static int clean_delay(struct fuse *f)
4411 {
4412  /*
4413  * This is calculating the delay between clean runs. To
4414  * reduce the number of cleans we are doing them 10 times
4415  * within the remember window.
4416  */
4417  int min_sleep = 60;
4418  int max_sleep = 3600;
4419  int sleep_time = f->conf.remember / 10;
4420 
4421  if (sleep_time > max_sleep)
4422  return max_sleep;
4423  if (sleep_time < min_sleep)
4424  return min_sleep;
4425  return sleep_time;
4426 }
4427 
4428 int fuse_clean_cache(struct fuse *f)
4429 {
4430  struct node_lru *lnode;
4431  struct list_head *curr, *next;
4432  struct node *node;
4433  struct timespec now;
4434 
4435  pthread_mutex_lock(&f->lock);
4436 
4437  curr_time(&now);
4438 
4439  for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4440  double age;
4441 
4442  next = curr->next;
4443  lnode = list_entry(curr, struct node_lru, lru);
4444  node = &lnode->node;
4445 
4446  age = diff_timespec(&now, &lnode->forget_time);
4447  if (age <= f->conf.remember)
4448  break;
4449 
4450  assert(node->nlookup == 1);
4451 
4452  /* Don't forget active directories */
4453  if (node->refctr > 1)
4454  continue;
4455 
4456  node->nlookup = 0;
4457  unhash_name(f, node);
4458  unref_node(f, node);
4459  }
4460  pthread_mutex_unlock(&f->lock);
4461 
4462  return clean_delay(f);
4463 }
4464 
4465 static struct fuse_lowlevel_ops fuse_path_ops = {
4466  .init = fuse_lib_init,
4467  .destroy = fuse_lib_destroy,
4468  .lookup = fuse_lib_lookup,
4469  .forget = fuse_lib_forget,
4470  .forget_multi = fuse_lib_forget_multi,
4471  .getattr = fuse_lib_getattr,
4472  .setattr = fuse_lib_setattr,
4473  .access = fuse_lib_access,
4474  .readlink = fuse_lib_readlink,
4475  .mknod = fuse_lib_mknod,
4476  .mkdir = fuse_lib_mkdir,
4477  .unlink = fuse_lib_unlink,
4478  .rmdir = fuse_lib_rmdir,
4479  .symlink = fuse_lib_symlink,
4480  .rename = fuse_lib_rename,
4481  .link = fuse_lib_link,
4482  .create = fuse_lib_create,
4483  .open = fuse_lib_open,
4484  .read = fuse_lib_read,
4485  .write_buf = fuse_lib_write_buf,
4486  .flush = fuse_lib_flush,
4487  .release = fuse_lib_release,
4488  .fsync = fuse_lib_fsync,
4489  .opendir = fuse_lib_opendir,
4490  .readdir = fuse_lib_readdir,
4491  .readdirplus = fuse_lib_readdirplus,
4492  .releasedir = fuse_lib_releasedir,
4493  .fsyncdir = fuse_lib_fsyncdir,
4494  .statfs = fuse_lib_statfs,
4495  .setxattr = fuse_lib_setxattr,
4496  .getxattr = fuse_lib_getxattr,
4497  .listxattr = fuse_lib_listxattr,
4498  .removexattr = fuse_lib_removexattr,
4499  .getlk = fuse_lib_getlk,
4500  .setlk = fuse_lib_setlk,
4501  .flock = fuse_lib_flock,
4502  .bmap = fuse_lib_bmap,
4503  .ioctl = fuse_lib_ioctl,
4504  .poll = fuse_lib_poll,
4505  .fallocate = fuse_lib_fallocate,
4506  .copy_file_range = fuse_lib_copy_file_range,
4507  .lseek = fuse_lib_lseek,
4508 };
4509 
4510 int fuse_notify_poll(struct fuse_pollhandle *ph)
4511 {
4512  return fuse_lowlevel_notify_poll(ph);
4513 }
4514 
4515 struct fuse_session *fuse_get_session(struct fuse *f)
4516 {
4517  return f->se;
4518 }
4519 
4520 static int fuse_session_loop_remember(struct fuse *f)
4521 {
4522  struct fuse_session *se = f->se;
4523  int res = 0;
4524  struct timespec now;
4525  time_t next_clean;
4526  struct pollfd fds = {
4527  .fd = se->fd,
4528  .events = POLLIN
4529  };
4530  struct fuse_buf fbuf = {
4531  .mem = NULL,
4532  };
4533 
4534  curr_time(&now);
4535  next_clean = now.tv_sec;
4536  while (!fuse_session_exited(se)) {
4537  unsigned timeout;
4538 
4539  curr_time(&now);
4540  if (now.tv_sec < next_clean)
4541  timeout = next_clean - now.tv_sec;
4542  else
4543  timeout = 0;
4544 
4545  res = poll(&fds, 1, timeout * 1000);
4546  if (res == -1) {
4547  if (errno == EINTR)
4548  continue;
4549  else
4550  break;
4551  } else if (res > 0) {
4552  res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4553 
4554  if (res == -EINTR)
4555  continue;
4556  if (res <= 0)
4557  break;
4558 
4559  fuse_session_process_buf_int(se, &fbuf, NULL);
4560  } else {
4561  timeout = fuse_clean_cache(f);
4562  curr_time(&now);
4563  next_clean = now.tv_sec + timeout;
4564  }
4565  }
4566 
4567  free(fbuf.mem);
4568  fuse_session_reset(se);
4569  return res < 0 ? -1 : 0;
4570 }
4571 
4572 int fuse_loop(struct fuse *f)
4573 {
4574  if (!f)
4575  return -1;
4576 
4577  if (lru_enabled(f))
4578  return fuse_session_loop_remember(f);
4579 
4580  return fuse_session_loop(f->se);
4581 }
4582 
4583 FUSE_SYMVER("fuse_loop_mt_32", "fuse_loop_mt@@FUSE_3.2")
4584 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
4585 {
4586  if (f == NULL)
4587  return -1;
4588 
4589  int res = fuse_start_cleanup_thread(f);
4590  if (res)
4591  return -1;
4592 
4593  res = fuse_session_loop_mt_32(fuse_get_session(f), config);
4595  return res;
4596 }
4597 
4598 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
4599 FUSE_SYMVER("fuse_loop_mt_31", "fuse_loop_mt@FUSE_3.0")
4600 int fuse_loop_mt_31(struct fuse *f, int clone_fd)
4601 {
4602  struct fuse_loop_config config;
4603  config.clone_fd = clone_fd;
4604  config.max_idle_threads = 10;
4605  return fuse_loop_mt_32(f, &config);
4606 }
4607 
4608 void fuse_exit(struct fuse *f)
4609 {
4610  fuse_session_exit(f->se);
4611 }
4612 
4613 struct fuse_context *fuse_get_context(void)
4614 {
4615  struct fuse_context_i *c = fuse_get_context_internal();
4616 
4617  if (c)
4618  return &c->ctx;
4619  else
4620  return NULL;
4621 }
4622 
4623 int fuse_getgroups(int size, gid_t list[])
4624 {
4625  struct fuse_context_i *c = fuse_get_context_internal();
4626  if (!c)
4627  return -EINVAL;
4628 
4629  return fuse_req_getgroups(c->req, size, list);
4630 }
4631 
4632 int fuse_interrupted(void)
4633 {
4634  struct fuse_context_i *c = fuse_get_context_internal();
4635 
4636  if (c)
4637  return fuse_req_interrupted(c->req);
4638  else
4639  return 0;
4640 }
4641 
4642 int fuse_invalidate_path(struct fuse *f, const char *path) {
4643  fuse_ino_t ino;
4644  int err = lookup_path_in_cache(f, path, &ino);
4645  if (err) {
4646  return err;
4647  }
4648 
4649  return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
4650 }
4651 
4652 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4653 
4654 static const struct fuse_opt fuse_lib_opts[] = {
4655  FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
4657  FUSE_LIB_OPT("debug", debug, 1),
4658  FUSE_LIB_OPT("-d", debug, 1),
4659  FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
4660  FUSE_LIB_OPT("auto_cache", auto_cache, 1),
4661  FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
4662  FUSE_LIB_OPT("no_rofd_flush", no_rofd_flush, 1),
4663  FUSE_LIB_OPT("umask=", set_mode, 1),
4664  FUSE_LIB_OPT("umask=%o", umask, 0),
4665  FUSE_LIB_OPT("uid=", set_uid, 1),
4666  FUSE_LIB_OPT("uid=%d", uid, 0),
4667  FUSE_LIB_OPT("gid=", set_gid, 1),
4668  FUSE_LIB_OPT("gid=%d", gid, 0),
4669  FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
4670  FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
4671  FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
4672  FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
4673  FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
4674  FUSE_LIB_OPT("noforget", remember, -1),
4675  FUSE_LIB_OPT("remember=%u", remember, 0),
4676  FUSE_LIB_OPT("modules=%s", modules, 0),
4677  FUSE_OPT_END
4678 };
4679 
4680 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4681  struct fuse_args *outargs)
4682 {
4683  (void) arg; (void) outargs; (void) data; (void) key;
4684 
4685  /* Pass through unknown options */
4686  return 1;
4687 }
4688 
4689 
4690 static const struct fuse_opt fuse_help_opts[] = {
4691  FUSE_LIB_OPT("modules=%s", modules, 1),
4692  FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP),
4693  FUSE_OPT_END
4694 };
4695 
4696 static void print_module_help(const char *name,
4697  fuse_module_factory_t *fac)
4698 {
4699  struct fuse_args a = FUSE_ARGS_INIT(0, NULL);
4700  if (fuse_opt_add_arg(&a, "") == -1 ||
4701  fuse_opt_add_arg(&a, "-h") == -1)
4702  return;
4703  printf("\nOptions for %s module:\n", name);
4704  (*fac)(&a, NULL);
4705  fuse_opt_free_args(&a);
4706 }
4707 
4708 void fuse_lib_help(struct fuse_args *args)
4709 {
4710  /* These are not all options, but only the ones that
4711  may be of interest to an end-user */
4712  printf(
4713 " -o kernel_cache cache files in kernel\n"
4714 " -o [no]auto_cache enable caching based on modification times (off)\n"
4715 " -o no_rofd_flush disable flushing of read-only fd on close (off)\n"
4716 " -o umask=M set file permissions (octal)\n"
4717 " -o uid=N set file owner\n"
4718 " -o gid=N set file group\n"
4719 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4720 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4721 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4722 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4723 " -o noforget never forget cached inodes\n"
4724 " -o remember=T remember cached inodes for T seconds (0s)\n"
4725 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4726 
4727 
4728  /* Print low-level help */
4730 
4731  /* Print help for builtin modules */
4732  print_module_help("subdir", &fuse_module_subdir_factory);
4733 #ifdef HAVE_ICONV
4734  print_module_help("iconv", &fuse_module_iconv_factory);
4735 #endif
4736 
4737  /* Parse command line options in case we need to
4738  activate more modules */
4739  struct fuse_config conf = { .modules = NULL };
4740  if (fuse_opt_parse(args, &conf, fuse_help_opts,
4741  fuse_lib_opt_proc) == -1
4742  || !conf.modules)
4743  return;
4744 
4745  char *module;
4746  char *next;
4747  struct fuse_module *m;
4748 
4749  // Iterate over all modules
4750  for (module = conf.modules; module; module = next) {
4751  char *p;
4752  for (p = module; *p && *p != ':'; p++);
4753  next = *p ? p + 1 : NULL;
4754  *p = '\0';
4755 
4756  m = fuse_get_module(module);
4757  if (m)
4758  print_module_help(module, &m->factory);
4759  }
4760 }
4761 
4762 
4763 
4764 static int fuse_init_intr_signal(int signum, int *installed)
4765 {
4766  struct sigaction old_sa;
4767 
4768  if (sigaction(signum, NULL, &old_sa) == -1) {
4769  perror("fuse: cannot get old signal handler");
4770  return -1;
4771  }
4772 
4773  if (old_sa.sa_handler == SIG_DFL) {
4774  struct sigaction sa;
4775 
4776  memset(&sa, 0, sizeof(struct sigaction));
4777  sa.sa_handler = fuse_intr_sighandler;
4778  sigemptyset(&sa.sa_mask);
4779 
4780  if (sigaction(signum, &sa, NULL) == -1) {
4781  perror("fuse: cannot set interrupt signal handler");
4782  return -1;
4783  }
4784  *installed = 1;
4785  }
4786  return 0;
4787 }
4788 
4789 static void fuse_restore_intr_signal(int signum)
4790 {
4791  struct sigaction sa;
4792 
4793  memset(&sa, 0, sizeof(struct sigaction));
4794  sa.sa_handler = SIG_DFL;
4795  sigaction(signum, &sa, NULL);
4796 }
4797 
4798 
4799 static int fuse_push_module(struct fuse *f, const char *module,
4800  struct fuse_args *args)
4801 {
4802  struct fuse_fs *fs[2] = { f->fs, NULL };
4803  struct fuse_fs *newfs;
4804  struct fuse_module *m = fuse_get_module(module);
4805 
4806  if (!m)
4807  return -1;
4808 
4809  newfs = m->factory(args, fs);
4810  if (!newfs) {
4811  fuse_put_module(m);
4812  return -1;
4813  }
4814  newfs->m = m;
4815  f->fs = newfs;
4816  return 0;
4817 }
4818 
4819 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4820  void *user_data)
4821 {
4822  struct fuse_fs *fs;
4823 
4824  if (sizeof(struct fuse_operations) < op_size) {
4825  fuse_log(FUSE_LOG_ERR, "fuse: warning: library too old, some operations may not not work\n");
4826  op_size = sizeof(struct fuse_operations);
4827  }
4828 
4829  fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4830  if (!fs) {
4831  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse_fs object\n");
4832  return NULL;
4833  }
4834 
4835  fs->user_data = user_data;
4836  if (op)
4837  memcpy(&fs->op, op, op_size);
4838  return fs;
4839 }
4840 
4841 static int node_table_init(struct node_table *t)
4842 {
4843  t->size = NODE_TABLE_MIN_SIZE;
4844  t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4845  if (t->array == NULL) {
4846  fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
4847  return -1;
4848  }
4849  t->use = 0;
4850  t->split = 0;
4851 
4852  return 0;
4853 }
4854 
4855 static void *fuse_prune_nodes(void *fuse)
4856 {
4857  struct fuse *f = fuse;
4858  int sleep_time;
4859 
4860  while(1) {
4861  sleep_time = fuse_clean_cache(f);
4862  sleep(sleep_time);
4863  }
4864  return NULL;
4865 }
4866 
4867 int fuse_start_cleanup_thread(struct fuse *f)
4868 {
4869  if (lru_enabled(f))
4870  return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4871 
4872  return 0;
4873 }
4874 
4875 void fuse_stop_cleanup_thread(struct fuse *f)
4876 {
4877  if (lru_enabled(f)) {
4878  pthread_mutex_lock(&f->lock);
4879  pthread_cancel(f->prune_thread);
4880  pthread_mutex_unlock(&f->lock);
4881  pthread_join(f->prune_thread, NULL);
4882  }
4883 }
4884 
4885 
4886 FUSE_SYMVER("fuse_new_31", "fuse_new@@FUSE_3.1")
4887 struct fuse *fuse_new_31(struct fuse_args *args,
4888  const struct fuse_operations *op,
4889  size_t op_size, void *user_data)
4890 {
4891  struct fuse *f;
4892  struct node *root;
4893  struct fuse_fs *fs;
4894  struct fuse_lowlevel_ops llop = fuse_path_ops;
4895 
4896  f = (struct fuse *) calloc(1, sizeof(struct fuse));
4897  if (f == NULL) {
4898  fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse object\n");
4899  goto out;
4900  }
4901 
4902  f->conf.entry_timeout = 1.0;
4903  f->conf.attr_timeout = 1.0;
4904  f->conf.negative_timeout = 0.0;
4905  f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4906 
4907  /* Parse options */
4908  if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4909  fuse_lib_opt_proc) == -1)
4910  goto out_free;
4911 
4912  pthread_mutex_lock(&fuse_context_lock);
4913  static int builtin_modules_registered = 0;
4914  /* Have the builtin modules already been registered? */
4915  if (builtin_modules_registered == 0) {
4916  /* If not, register them. */
4917  fuse_register_module("subdir", fuse_module_subdir_factory, NULL);
4918 #ifdef HAVE_ICONV
4919  fuse_register_module("iconv", fuse_module_iconv_factory, NULL);
4920 #endif
4921  builtin_modules_registered= 1;
4922  }
4923  pthread_mutex_unlock(&fuse_context_lock);
4924 
4925  if (fuse_create_context_key() == -1)
4926  goto out_free;
4927 
4928  fs = fuse_fs_new(op, op_size, user_data);
4929  if (!fs)
4930  goto out_delete_context_key;
4931 
4932  f->fs = fs;
4933 
4934  /* Oh f**k, this is ugly! */
4935  if (!fs->op.lock) {
4936  llop.getlk = NULL;
4937  llop.setlk = NULL;
4938  }
4939 
4940  f->pagesize = getpagesize();
4941  init_list_head(&f->partial_slabs);
4942  init_list_head(&f->full_slabs);
4943  init_list_head(&f->lru_table);
4944 
4945  if (f->conf.modules) {
4946  char *module;
4947  char *next;
4948 
4949  for (module = f->conf.modules; module; module = next) {
4950  char *p;
4951  for (p = module; *p && *p != ':'; p++);
4952  next = *p ? p + 1 : NULL;
4953  *p = '\0';
4954  if (module[0] &&
4955  fuse_push_module(f, module, args) == -1)
4956  goto out_free_fs;
4957  }
4958  }
4959 
4960  if (!f->conf.ac_attr_timeout_set)
4961  f->conf.ac_attr_timeout = f->conf.attr_timeout;
4962 
4963 #if defined(__FreeBSD__) || defined(__NetBSD__)
4964  /*
4965  * In FreeBSD, we always use these settings as inode numbers
4966  * are needed to make getcwd(3) work.
4967  */
4968  f->conf.readdir_ino = 1;
4969 #endif
4970 
4971  f->se = fuse_session_new(args, &llop, sizeof(llop), f);
4972  if (f->se == NULL)
4973  goto out_free_fs;
4974 
4975  if (f->conf.debug) {
4976  fuse_log(FUSE_LOG_DEBUG, "nullpath_ok: %i\n", f->conf.nullpath_ok);
4977  }
4978 
4979  /* Trace topmost layer by default */
4980  f->fs->debug = f->conf.debug;
4981  f->ctr = 0;
4982  f->generation = 0;
4983  if (node_table_init(&f->name_table) == -1)
4984  goto out_free_session;
4985 
4986  if (node_table_init(&f->id_table) == -1)
4987  goto out_free_name_table;
4988 
4989  pthread_mutex_init(&f->lock, NULL);
4990 
4991  root = alloc_node(f);
4992  if (root == NULL) {
4993  fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
4994  goto out_free_id_table;
4995  }
4996  if (lru_enabled(f)) {
4997  struct node_lru *lnode = node_lru(root);
4998  init_list_head(&lnode->lru);
4999  }
5000 
5001  strcpy(root->inline_name, "/");
5002  root->name = root->inline_name;
5003 
5004  if (f->conf.intr &&
5005  fuse_init_intr_signal(f->conf.intr_signal,
5006  &f->intr_installed) == -1)
5007  goto out_free_root;
5008 
5009  root->parent = NULL;
5010  root->nodeid = FUSE_ROOT_ID;
5011  inc_nlookup(root);
5012  hash_id(f, root);
5013 
5014  return f;
5015 
5016 out_free_root:
5017  free(root);
5018 out_free_id_table:
5019  free(f->id_table.array);
5020 out_free_name_table:
5021  free(f->name_table.array);
5022 out_free_session:
5023  fuse_session_destroy(f->se);
5024 out_free_fs:
5025  if (f->fs->m)
5026  fuse_put_module(f->fs->m);
5027  free(f->fs);
5028  free(f->conf.modules);
5029 out_delete_context_key:
5030  fuse_delete_context_key();
5031 out_free:
5032  free(f);
5033 out:
5034  return NULL;
5035 }
5036 
5037 /* Emulates 3.0-style fuse_new(), which processes --help */
5038 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
5039  size_t op_size, void *private_data);
5040 FUSE_SYMVER("fuse_new_30", "fuse_new@FUSE_3.0")
5041 struct fuse *fuse_new_30(struct fuse_args *args,
5042  const struct fuse_operations *op,
5043  size_t op_size, void *user_data)
5044 {
5045  struct fuse_config conf;
5046 
5047  memset(&conf, 0, sizeof(conf));
5048 
5049  const struct fuse_opt opts[] = {
5050  FUSE_LIB_OPT("-h", show_help, 1),
5051  FUSE_LIB_OPT("--help", show_help, 1),
5052  FUSE_OPT_END
5053  };
5054 
5055  if (fuse_opt_parse(args, &conf, opts,
5056  fuse_lib_opt_proc) == -1)
5057  return NULL;
5058 
5059  if (conf.show_help) {
5060  fuse_lib_help(args);
5061  return NULL;
5062  } else
5063  return fuse_new_31(args, op, op_size, user_data);
5064 }
5065 
5066 void fuse_destroy(struct fuse *f)
5067 {
5068  size_t i;
5069 
5070  if (f->conf.intr && f->intr_installed)
5071  fuse_restore_intr_signal(f->conf.intr_signal);
5072 
5073  if (f->fs) {
5074  fuse_create_context(f);
5075 
5076  for (i = 0; i < f->id_table.size; i++) {
5077  struct node *node;
5078 
5079  for (node = f->id_table.array[i]; node != NULL;
5080  node = node->id_next) {
5081  if (node->is_hidden) {
5082  char *path;
5083  if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
5084  fuse_fs_unlink(f->fs, path);
5085  free(path);
5086  }
5087  }
5088  }
5089  }
5090  }
5091  for (i = 0; i < f->id_table.size; i++) {
5092  struct node *node;
5093  struct node *next;
5094 
5095  for (node = f->id_table.array[i]; node != NULL; node = next) {
5096  next = node->id_next;
5097  free_node(f, node);
5098  f->id_table.use--;
5099  }
5100  }
5101  assert(list_empty(&f->partial_slabs));
5102  assert(list_empty(&f->full_slabs));
5103 
5104  while (fuse_modules) {
5105  fuse_put_module(fuse_modules);
5106  }
5107  free(f->id_table.array);
5108  free(f->name_table.array);
5109  pthread_mutex_destroy(&f->lock);
5110  fuse_session_destroy(f->se);
5111  free(f->conf.modules);
5112  free(f);
5113  fuse_delete_context_key();
5114 }
5115 
5116 int fuse_mount(struct fuse *f, const char *mountpoint) {
5117  return fuse_session_mount(fuse_get_session(f), mountpoint);
5118 }
5119 
5120 
5121 void fuse_unmount(struct fuse *f) {
5123 }
5124 
5125 int fuse_version(void)
5126 {
5127  return FUSE_VERSION;
5128 }
5129 
5130 const char *fuse_pkgversion(void)
5131 {
5132  return PACKAGE_VERSION;
5133 }
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4509
int fuse_getgroups(int size, gid_t list[])
Definition: fuse.c:4617
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5108
int fuse_interrupted(void)
Definition: fuse.c:4626
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5058
int fuse_start_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4859
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4636
int fuse_loop(struct fuse *f)
Definition: fuse.c:4566
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4811
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:85
void fuse_exit(struct fuse *f)
Definition: fuse.c:4602
int fuse_clean_cache(struct fuse *fuse)
Definition: fuse.c:4422
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4607
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4701
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5113
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
Definition: fuse.h:1258
void fuse_stop_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4867
fuse_fill_dir_flags
Definition: fuse.h:57
@ FUSE_FILL_DIR_PLUS
Definition: fuse.h:67
fuse_readdir_flags
Definition: fuse.h:42
@ FUSE_READDIR_PLUS
Definition: fuse.h:51
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:198
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
@ FUSE_BUF_IS_FD
Definition: fuse_common.h:633
#define FUSE_CAP_EXPORT_SUPPORT
Definition: fuse_common.h:165
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:149
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:284
const char * fuse_pkgversion(void)
Definition: fuse.c:5122
int fuse_version(void)
Definition: fuse.c:5117
@ FUSE_BUF_SPLICE_MOVE
Definition: fuse_common.h:684
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:211
void fuse_log(enum fuse_log_level level, const char *fmt,...)
Definition: fuse_log.c:33
void fuse_session_destroy(struct fuse_session *se)
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
#define FUSE_ROOT_ID
Definition: fuse_lowlevel.h:43
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
void fuse_session_exit(struct fuse_session *se)
int fuse_reply_poll(fuse_req_t req, unsigned revents)
int fuse_reply_err(fuse_req_t req, int err)
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
int fuse_session_exited(struct fuse_session *se)
int fuse_req_interrupted(fuse_req_t req)
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
int fuse_reply_readlink(fuse_req_t req, const char *link)
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
void fuse_session_unmount(struct fuse_session *se)
void fuse_reply_none(fuse_req_t req)
void fuse_lowlevel_help(void)
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
int fuse_reply_write(fuse_req_t req, size_t count)
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
void * fuse_req_userdata(fuse_req_t req)
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
void fuse_session_reset(struct fuse_session *se)
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
int fuse_reply_lseek(fuse_req_t req, off_t off)
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_reply_xattr(fuse_req_t req, size_t count)
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:55
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:34
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
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
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
#define FUSE_OPT_END
Definition: fuse_opt.h:104
enum fuse_buf_flags flags
Definition: fuse_common.h:711
void * mem
Definition: fuse_common.h:718
size_t size
Definition: fuse_common.h:706
size_t off
Definition: fuse_common.h:757
struct fuse_buf buf[1]
Definition: fuse_common.h:762
size_t idx
Definition: fuse_common.h:752
size_t count
Definition: fuse_common.h:747
int show_help
Definition: fuse.h:274
unsigned capable
Definition: fuse_common.h:459
unsigned want
Definition: fuse_common.h:467
void * private_data
Definition: fuse.h:814
mode_t umask
Definition: fuse_lowlevel.h:59
double entry_timeout
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
uint64_t generation
Definition: fuse_lowlevel.h:79
double attr_timeout
Definition: fuse_lowlevel.h:94
struct stat attr
Definition: fuse_lowlevel.h:88
unsigned int direct_io
Definition: fuse_common.h:57
unsigned int keep_cache
Definition: fuse_common.h:64
uint64_t lock_owner
Definition: fuse_common.h:96
uint64_t fh
Definition: fuse_common.h:93
uint32_t poll_events
Definition: fuse_common.h:100
unsigned int noflush
Definition: fuse_common.h:88
unsigned int writepage
Definition: fuse_common.h:54
unsigned int flush
Definition: fuse_common.h:69
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
void(* init)(void *userdata, struct fuse_conn_info *conn)
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)