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