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