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