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