"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.10.4/doc/html/fuse_8c_source.html" (9 Jun 2021, 801033 Bytes) of package /linux/misc/fuse-3.10.4.tar.xz:


Caution: In this restricted "Fossies" environment the current HTML page may not be correctly presentated and may have some non-functional links. You can here alternatively try to browse the pure source code or just view or download the uninterpreted raw source code. If the rendering is insufficient you may try to find and view the page on the project site itself.

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