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[i].flags & FUSE_BUF_IS_FD))
1781  free(buf->buf[i].mem);
1782  free(buf);
1783  }
1784 }
1785 
1786 int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
1787  struct fuse_bufvec **bufp, size_t size, off_t off,
1788  struct fuse_file_info *fi)
1789 {
1790  fuse_get_context()->private_data = fs->user_data;
1791  if (fs->op.read || fs->op.read_buf) {
1792  int res;
1793 
1794  if (fs->debug)
1795  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, unsigned int cmd,
2308  void *arg, struct fuse_file_info *fi, unsigned int flags,
2309  void *data)
2310 {
2311  fuse_get_context()->private_data = fs->user_data;
2312  if (fs->op.ioctl) {
2313  if (fs->debug)
2314  fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n",
2315  (unsigned long long) fi->fh, cmd, flags);
2316 
2317  return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2318  } else
2319  return -ENOSYS;
2320 }
2321 
2322 int fuse_fs_poll(struct fuse_fs *fs, const char *path,
2323  struct fuse_file_info *fi, struct fuse_pollhandle *ph,
2324  unsigned *reventsp)
2325 {
2326  fuse_get_context()->private_data = fs->user_data;
2327  if (fs->op.poll) {
2328  int res;
2329 
2330  if (fs->debug)
2331  fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n",
2332  (unsigned long long) fi->fh, ph,
2333  fi->poll_events);
2334 
2335  res = fs->op.poll(path, fi, ph, reventsp);
2336 
2337  if (fs->debug && !res)
2338  fprintf(stderr, " poll[%llu] revents: 0x%x\n",
2339  (unsigned long long) fi->fh, *reventsp);
2340 
2341  return res;
2342  } else
2343  return -ENOSYS;
2344 }
2345 
2346 int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
2347  off_t offset, off_t length, struct fuse_file_info *fi)
2348 {
2349  fuse_get_context()->private_data = fs->user_data;
2350  if (fs->op.fallocate) {
2351  if (fs->debug)
2352  fprintf(stderr, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2353  path,
2354  mode,
2355  (unsigned long long) offset,
2356  (unsigned long long) length);
2357 
2358  return fs->op.fallocate(path, mode, offset, length, fi);
2359  } else
2360  return -ENOSYS;
2361 }
2362 
2363 ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, const char *path_in,
2364  struct fuse_file_info *fi_in, off_t off_in,
2365  const char *path_out,
2366  struct fuse_file_info *fi_out, off_t off_out,
2367  size_t len, int flags)
2368 {
2369  fuse_get_context()->private_data = fs->user_data;
2370  if (fs->op.copy_file_range) {
2371  if (fs->debug)
2372  fprintf(stderr, "copy_file_range from %s:%llu to "
2373  "%s:%llu, length: %llu\n",
2374  path_in,
2375  (unsigned long long) off_in,
2376  path_out,
2377  (unsigned long long) off_out,
2378  (unsigned long long) len);
2379 
2380  return fs->op.copy_file_range(path_in, fi_in, off_in, path_out,
2381  fi_out, off_out, len, flags);
2382  } else
2383  return -ENOSYS;
2384 }
2385 
2386 static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
2387 {
2388  struct node *node;
2389  int isopen = 0;
2390  pthread_mutex_lock(&f->lock);
2391  node = lookup_node(f, dir, name);
2392  if (node && node->open_count > 0)
2393  isopen = 1;
2394  pthread_mutex_unlock(&f->lock);
2395  return isopen;
2396 }
2397 
2398 static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
2399  char *newname, size_t bufsize)
2400 {
2401  struct stat buf;
2402  struct node *node;
2403  struct node *newnode;
2404  char *newpath;
2405  int res;
2406  int failctr = 10;
2407 
2408  do {
2409  pthread_mutex_lock(&f->lock);
2410  node = lookup_node(f, dir, oldname);
2411  if (node == NULL) {
2412  pthread_mutex_unlock(&f->lock);
2413  return NULL;
2414  }
2415  do {
2416  f->hidectr ++;
2417  snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
2418  (unsigned int) node->nodeid, f->hidectr);
2419  newnode = lookup_node(f, dir, newname);
2420  } while(newnode);
2421 
2422  res = try_get_path(f, dir, newname, &newpath, NULL, false);
2423  pthread_mutex_unlock(&f->lock);
2424  if (res)
2425  break;
2426 
2427  memset(&buf, 0, sizeof(buf));
2428  res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
2429  if (res == -ENOENT)
2430  break;
2431  free(newpath);
2432  newpath = NULL;
2433  } while(res == 0 && --failctr);
2434 
2435  return newpath;
2436 }
2437 
2438 static int hide_node(struct fuse *f, const char *oldpath,
2439  fuse_ino_t dir, const char *oldname)
2440 {
2441  char newname[64];
2442  char *newpath;
2443  int err = -EBUSY;
2444 
2445  newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
2446  if (newpath) {
2447  err = fuse_fs_rename(f->fs, oldpath, newpath, 0);
2448  if (!err)
2449  err = rename_node(f, dir, oldname, dir, newname, 1);
2450  free(newpath);
2451  }
2452  return err;
2453 }
2454 
2455 static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
2456 {
2457  return stbuf->st_mtime == ts->tv_sec &&
2458  ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2459 }
2460 
2461 #ifndef CLOCK_MONOTONIC
2462 #define CLOCK_MONOTONIC CLOCK_REALTIME
2463 #endif
2464 
2465 static void curr_time(struct timespec *now)
2466 {
2467  static clockid_t clockid = CLOCK_MONOTONIC;
2468  int res = clock_gettime(clockid, now);
2469  if (res == -1 && errno == EINVAL) {
2470  clockid = CLOCK_REALTIME;
2471  res = clock_gettime(clockid, now);
2472  }
2473  if (res == -1) {
2474  perror("fuse: clock_gettime");
2475  abort();
2476  }
2477 }
2478 
2479 static void update_stat(struct node *node, const struct stat *stbuf)
2480 {
2481  if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2482  stbuf->st_size != node->size))
2483  node->cache_valid = 0;
2484  node->mtime.tv_sec = stbuf->st_mtime;
2485  node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2486  node->size = stbuf->st_size;
2487  curr_time(&node->stat_updated);
2488 }
2489 
2490 static int do_lookup(struct fuse *f, fuse_ino_t nodeid, const char *name,
2491  struct fuse_entry_param *e)
2492 {
2493  struct node *node;
2494 
2495  node = find_node(f, nodeid, name);
2496  if (node == NULL)
2497  return -ENOMEM;
2498 
2499  e->ino = node->nodeid;
2500  e->generation = node->generation;
2501  e->entry_timeout = f->conf.entry_timeout;
2502  e->attr_timeout = f->conf.attr_timeout;
2503  if (f->conf.auto_cache) {
2504  pthread_mutex_lock(&f->lock);
2505  update_stat(node, &e->attr);
2506  pthread_mutex_unlock(&f->lock);
2507  }
2508  set_stat(f, e->ino, &e->attr);
2509  return 0;
2510 }
2511 
2512 static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
2513  const char *name, const char *path,
2514  struct fuse_entry_param *e, struct fuse_file_info *fi)
2515 {
2516  int res;
2517 
2518  memset(e, 0, sizeof(struct fuse_entry_param));
2519  res = fuse_fs_getattr(f->fs, path, &e->attr, fi);
2520  if (res == 0) {
2521  res = do_lookup(f, nodeid, name, e);
2522  if (res == 0 && f->conf.debug) {
2523  fprintf(stderr, " NODEID: %llu\n",
2524  (unsigned long long) e->ino);
2525  }
2526  }
2527  return res;
2528 }
2529 
2530 static struct fuse_context_i *fuse_get_context_internal(void)
2531 {
2532  return (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2533 }
2534 
2535 static struct fuse_context_i *fuse_create_context(struct fuse *f)
2536 {
2537  struct fuse_context_i *c = fuse_get_context_internal();
2538  if (c == NULL) {
2539  c = (struct fuse_context_i *)
2540  calloc(1, sizeof(struct fuse_context_i));
2541  if (c == NULL) {
2542  /* This is hard to deal with properly, so just
2543  abort. If memory is so low that the
2544  context cannot be allocated, there's not
2545  much hope for the filesystem anyway */
2546  fprintf(stderr, "fuse: failed to allocate thread specific data\n");
2547  abort();
2548  }
2549  pthread_setspecific(fuse_context_key, c);
2550  } else {
2551  memset(c, 0, sizeof(*c));
2552  }
2553  c->ctx.fuse = f;
2554 
2555  return c;
2556 }
2557 
2558 static void fuse_freecontext(void *data)
2559 {
2560  free(data);
2561 }
2562 
2563 static int fuse_create_context_key(void)
2564 {
2565  int err = 0;
2566  pthread_mutex_lock(&fuse_context_lock);
2567  if (!fuse_context_ref) {
2568  err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2569  if (err) {
2570  fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
2571  strerror(err));
2572  pthread_mutex_unlock(&fuse_context_lock);
2573  return -1;
2574  }
2575  }
2576  fuse_context_ref++;
2577  pthread_mutex_unlock(&fuse_context_lock);
2578  return 0;
2579 }
2580 
2581 static void fuse_delete_context_key(void)
2582 {
2583  pthread_mutex_lock(&fuse_context_lock);
2584  fuse_context_ref--;
2585  if (!fuse_context_ref) {
2586  free(pthread_getspecific(fuse_context_key));
2587  pthread_key_delete(fuse_context_key);
2588  }
2589  pthread_mutex_unlock(&fuse_context_lock);
2590 }
2591 
2592 static struct fuse *req_fuse_prepare(fuse_req_t req)
2593 {
2594  struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2595  const struct fuse_ctx *ctx = fuse_req_ctx(req);
2596  c->req = req;
2597  c->ctx.uid = ctx->uid;
2598  c->ctx.gid = ctx->gid;
2599  c->ctx.pid = ctx->pid;
2600  c->ctx.umask = ctx->umask;
2601  return c->ctx.fuse;
2602 }
2603 
2604 static inline void reply_err(fuse_req_t req, int err)
2605 {
2606  /* fuse_reply_err() uses non-negated errno values */
2607  fuse_reply_err(req, -err);
2608 }
2609 
2610 static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
2611  int err)
2612 {
2613  if (!err) {
2614  struct fuse *f = req_fuse(req);
2615  if (fuse_reply_entry(req, e) == -ENOENT) {
2616  /* Skip forget for negative result */
2617  if (e->ino != 0)
2618  forget_node(f, e->ino, 1);
2619  }
2620  } else
2621  reply_err(req, err);
2622 }
2623 
2624 void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn,
2625  struct fuse_config *cfg)
2626 {
2627  fuse_get_context()->private_data = fs->user_data;
2628  if (!fs->op.write_buf)
2629  conn->want &= ~FUSE_CAP_SPLICE_READ;
2630  if (!fs->op.lock)
2631  conn->want &= ~FUSE_CAP_POSIX_LOCKS;
2632  if (!fs->op.flock)
2633  conn->want &= ~FUSE_CAP_FLOCK_LOCKS;
2634  if (fs->op.init)
2635  fs->user_data = fs->op.init(conn, cfg);
2636 }
2637 
2638 static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
2639 {
2640  struct fuse *f = (struct fuse *) data;
2641 
2642  fuse_create_context(f);
2643  if(conn->capable & FUSE_CAP_EXPORT_SUPPORT)
2644  conn->want |= FUSE_CAP_EXPORT_SUPPORT;
2645  fuse_fs_init(f->fs, conn, &f->conf);
2646 }
2647 
2648 void fuse_fs_destroy(struct fuse_fs *fs)
2649 {
2650  fuse_get_context()->private_data = fs->user_data;
2651  if (fs->op.destroy)
2652  fs->op.destroy(fs->user_data);
2653  if (fs->m)
2654  fuse_put_module(fs->m);
2655  free(fs);
2656 }
2657 
2658 static void fuse_lib_destroy(void *data)
2659 {
2660  struct fuse *f = (struct fuse *) data;
2661 
2662  fuse_create_context(f);
2663  fuse_fs_destroy(f->fs);
2664  f->fs = NULL;
2665 }
2666 
2667 static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
2668  const char *name)
2669 {
2670  struct fuse *f = req_fuse_prepare(req);
2671  struct fuse_entry_param e;
2672  char *path;
2673  int err;
2674  struct node *dot = NULL;
2675 
2676  if (name[0] == '.') {
2677  int len = strlen(name);
2678 
2679  if (len == 1 || (name[1] == '.' && len == 2)) {
2680  pthread_mutex_lock(&f->lock);
2681  if (len == 1) {
2682  if (f->conf.debug)
2683  fprintf(stderr, "LOOKUP-DOT\n");
2684  dot = get_node_nocheck(f, parent);
2685  if (dot == NULL) {
2686  pthread_mutex_unlock(&f->lock);
2687  reply_entry(req, &e, -ESTALE);
2688  return;
2689  }
2690  dot->refctr++;
2691  } else {
2692  if (f->conf.debug)
2693  fprintf(stderr, "LOOKUP-DOTDOT\n");
2694  parent = get_node(f, parent)->parent->nodeid;
2695  }
2696  pthread_mutex_unlock(&f->lock);
2697  name = NULL;
2698  }
2699  }
2700 
2701  err = get_path_name(f, parent, name, &path);
2702  if (!err) {
2703  struct fuse_intr_data d;
2704  if (f->conf.debug)
2705  fprintf(stderr, "LOOKUP %s\n", path);
2706  fuse_prepare_interrupt(f, req, &d);
2707  err = lookup_path(f, parent, name, path, &e, NULL);
2708  if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2709  e.ino = 0;
2710  e.entry_timeout = f->conf.negative_timeout;
2711  err = 0;
2712  }
2713  fuse_finish_interrupt(f, req, &d);
2714  free_path(f, parent, path);
2715  }
2716  if (dot) {
2717  pthread_mutex_lock(&f->lock);
2718  unref_node(f, dot);
2719  pthread_mutex_unlock(&f->lock);
2720  }
2721  reply_entry(req, &e, err);
2722 }
2723 
2724 static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup)
2725 {
2726  if (f->conf.debug)
2727  fprintf(stderr, "FORGET %llu/%llu\n", (unsigned long long)ino,
2728  (unsigned long long) nlookup);
2729  forget_node(f, ino, nlookup);
2730 }
2731 
2732 static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino, uint64_t nlookup)
2733 {
2734  do_forget(req_fuse(req), ino, nlookup);
2735  fuse_reply_none(req);
2736 }
2737 
2738 static void fuse_lib_forget_multi(fuse_req_t req, size_t count,
2739  struct fuse_forget_data *forgets)
2740 {
2741  struct fuse *f = req_fuse(req);
2742  size_t i;
2743 
2744  for (i = 0; i < count; i++)
2745  do_forget(f, forgets[i].ino, forgets[i].nlookup);
2746 
2747  fuse_reply_none(req);
2748 }
2749 
2750 
2751 static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
2752  struct fuse_file_info *fi)
2753 {
2754  struct fuse *f = req_fuse_prepare(req);
2755  struct stat buf;
2756  char *path;
2757  int err;
2758 
2759  memset(&buf, 0, sizeof(buf));
2760 
2761  if (fi != NULL)
2762  err = get_path_nullok(f, ino, &path);
2763  else
2764  err = get_path(f, ino, &path);
2765  if (!err) {
2766  struct fuse_intr_data d;
2767  fuse_prepare_interrupt(f, req, &d);
2768  err = fuse_fs_getattr(f->fs, path, &buf, fi);
2769  fuse_finish_interrupt(f, req, &d);
2770  free_path(f, ino, path);
2771  }
2772  if (!err) {
2773  struct node *node;
2774 
2775  pthread_mutex_lock(&f->lock);
2776  node = get_node(f, ino);
2777  if (node->is_hidden && buf.st_nlink > 0)
2778  buf.st_nlink--;
2779  if (f->conf.auto_cache)
2780  update_stat(node, &buf);
2781  pthread_mutex_unlock(&f->lock);
2782  set_stat(f, ino, &buf);
2783  fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2784  } else
2785  reply_err(req, err);
2786 }
2787 
2788 int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
2789  struct fuse_file_info *fi)
2790 {
2791  fuse_get_context()->private_data = fs->user_data;
2792  if (fs->op.chmod) {
2793  if (fs->debug) {
2794  char buf[10];
2795  fprintf(stderr, "chmod[%s] %s %llo\n",
2796  file_info_string(fi, buf, sizeof(buf)),
2797  path, (unsigned long long) mode);
2798  }
2799  return fs->op.chmod(path, mode, fi);
2800  }
2801  else
2802  return -ENOSYS;
2803 }
2804 
2805 static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
2806  int valid, struct fuse_file_info *fi)
2807 {
2808  struct fuse *f = req_fuse_prepare(req);
2809  struct stat buf;
2810  char *path;
2811  int err;
2812 
2813  memset(&buf, 0, sizeof(buf));
2814  if (fi != NULL)
2815  err = get_path_nullok(f, ino, &path);
2816  else
2817  err = get_path(f, ino, &path);
2818  if (!err) {
2819  struct fuse_intr_data d;
2820  fuse_prepare_interrupt(f, req, &d);
2821  err = 0;
2822  if (!err && (valid & FUSE_SET_ATTR_MODE))
2823  err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
2824  if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2825  uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2826  attr->st_uid : (uid_t) -1;
2827  gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2828  attr->st_gid : (gid_t) -1;
2829  err = fuse_fs_chown(f->fs, path, uid, gid, fi);
2830  }
2831  if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2832  err = fuse_fs_truncate(f->fs, path,
2833  attr->st_size, fi);
2834  }
2835 #ifdef HAVE_UTIMENSAT
2836  if (!err &&
2837  (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2838  struct timespec tv[2];
2839 
2840  tv[0].tv_sec = 0;
2841  tv[1].tv_sec = 0;
2842  tv[0].tv_nsec = UTIME_OMIT;
2843  tv[1].tv_nsec = UTIME_OMIT;
2844 
2845  if (valid & FUSE_SET_ATTR_ATIME_NOW)
2846  tv[0].tv_nsec = UTIME_NOW;
2847  else if (valid & FUSE_SET_ATTR_ATIME)
2848  tv[0] = attr->st_atim;
2849 
2850  if (valid & FUSE_SET_ATTR_MTIME_NOW)
2851  tv[1].tv_nsec = UTIME_NOW;
2852  else if (valid & FUSE_SET_ATTR_MTIME)
2853  tv[1] = attr->st_mtim;
2854 
2855  err = fuse_fs_utimens(f->fs, path, tv, fi);
2856  } else
2857 #endif
2858  if (!err &&
2859  (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2860  (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2861  struct timespec tv[2];
2862  tv[0].tv_sec = attr->st_atime;
2863  tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2864  tv[1].tv_sec = attr->st_mtime;
2865  tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2866  err = fuse_fs_utimens(f->fs, path, tv, fi);
2867  }
2868  if (!err) {
2869  err = fuse_fs_getattr(f->fs, path, &buf, fi);
2870  }
2871  fuse_finish_interrupt(f, req, &d);
2872  free_path(f, ino, path);
2873  }
2874  if (!err) {
2875  if (f->conf.auto_cache) {
2876  pthread_mutex_lock(&f->lock);
2877  update_stat(get_node(f, ino), &buf);
2878  pthread_mutex_unlock(&f->lock);
2879  }
2880  set_stat(f, ino, &buf);
2881  fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2882  } else
2883  reply_err(req, err);
2884 }
2885 
2886 static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
2887 {
2888  struct fuse *f = req_fuse_prepare(req);
2889  char *path;
2890  int err;
2891 
2892  err = get_path(f, ino, &path);
2893  if (!err) {
2894  struct fuse_intr_data d;
2895 
2896  fuse_prepare_interrupt(f, req, &d);
2897  err = fuse_fs_access(f->fs, path, mask);
2898  fuse_finish_interrupt(f, req, &d);
2899  free_path(f, ino, path);
2900  }
2901  reply_err(req, err);
2902 }
2903 
2904 static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
2905 {
2906  struct fuse *f = req_fuse_prepare(req);
2907  char linkname[PATH_MAX + 1];
2908  char *path;
2909  int err;
2910 
2911  err = get_path(f, ino, &path);
2912  if (!err) {
2913  struct fuse_intr_data d;
2914  fuse_prepare_interrupt(f, req, &d);
2915  err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
2916  fuse_finish_interrupt(f, req, &d);
2917  free_path(f, ino, path);
2918  }
2919  if (!err) {
2920  linkname[PATH_MAX] = '\0';
2921  fuse_reply_readlink(req, linkname);
2922  } else
2923  reply_err(req, err);
2924 }
2925 
2926 static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
2927  mode_t mode, dev_t rdev)
2928 {
2929  struct fuse *f = req_fuse_prepare(req);
2930  struct fuse_entry_param e;
2931  char *path;
2932  int err;
2933 
2934  err = get_path_name(f, parent, name, &path);
2935  if (!err) {
2936  struct fuse_intr_data d;
2937 
2938  fuse_prepare_interrupt(f, req, &d);
2939  err = -ENOSYS;
2940  if (S_ISREG(mode)) {
2941  struct fuse_file_info fi;
2942 
2943  memset(&fi, 0, sizeof(fi));
2944  fi.flags = O_CREAT | O_EXCL | O_WRONLY;
2945  err = fuse_fs_create(f->fs, path, mode, &fi);
2946  if (!err) {
2947  err = lookup_path(f, parent, name, path, &e,
2948  &fi);
2949  fuse_fs_release(f->fs, path, &fi);
2950  }
2951  }
2952  if (err == -ENOSYS) {
2953  err = fuse_fs_mknod(f->fs, path, mode, rdev);
2954  if (!err)
2955  err = lookup_path(f, parent, name, path, &e,
2956  NULL);
2957  }
2958  fuse_finish_interrupt(f, req, &d);
2959  free_path(f, parent, path);
2960  }
2961  reply_entry(req, &e, err);
2962 }
2963 
2964 static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
2965  mode_t mode)
2966 {
2967  struct fuse *f = req_fuse_prepare(req);
2968  struct fuse_entry_param e;
2969  char *path;
2970  int err;
2971 
2972  err = get_path_name(f, parent, name, &path);
2973  if (!err) {
2974  struct fuse_intr_data d;
2975 
2976  fuse_prepare_interrupt(f, req, &d);
2977  err = fuse_fs_mkdir(f->fs, path, mode);
2978  if (!err)
2979  err = lookup_path(f, parent, name, path, &e, NULL);
2980  fuse_finish_interrupt(f, req, &d);
2981  free_path(f, parent, path);
2982  }
2983  reply_entry(req, &e, err);
2984 }
2985 
2986 static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
2987  const char *name)
2988 {
2989  struct fuse *f = req_fuse_prepare(req);
2990  struct node *wnode;
2991  char *path;
2992  int err;
2993 
2994  err = get_path_wrlock(f, parent, name, &path, &wnode);
2995  if (!err) {
2996  struct fuse_intr_data d;
2997 
2998  fuse_prepare_interrupt(f, req, &d);
2999  if (!f->conf.hard_remove && is_open(f, parent, name)) {
3000  err = hide_node(f, path, parent, name);
3001  } else {
3002  err = fuse_fs_unlink(f->fs, path);
3003  if (!err)
3004  remove_node(f, parent, name);
3005  }
3006  fuse_finish_interrupt(f, req, &d);
3007  free_path_wrlock(f, parent, wnode, path);
3008  }
3009  reply_err(req, err);
3010 }
3011 
3012 static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
3013 {
3014  struct fuse *f = req_fuse_prepare(req);
3015  struct node *wnode;
3016  char *path;
3017  int err;
3018 
3019  err = get_path_wrlock(f, parent, name, &path, &wnode);
3020  if (!err) {
3021  struct fuse_intr_data d;
3022 
3023  fuse_prepare_interrupt(f, req, &d);
3024  err = fuse_fs_rmdir(f->fs, path);
3025  fuse_finish_interrupt(f, req, &d);
3026  if (!err)
3027  remove_node(f, parent, name);
3028  free_path_wrlock(f, parent, wnode, path);
3029  }
3030  reply_err(req, err);
3031 }
3032 
3033 static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
3034  fuse_ino_t parent, const char *name)
3035 {
3036  struct fuse *f = req_fuse_prepare(req);
3037  struct fuse_entry_param e;
3038  char *path;
3039  int err;
3040 
3041  err = get_path_name(f, parent, name, &path);
3042  if (!err) {
3043  struct fuse_intr_data d;
3044 
3045  fuse_prepare_interrupt(f, req, &d);
3046  err = fuse_fs_symlink(f->fs, linkname, path);
3047  if (!err)
3048  err = lookup_path(f, parent, name, path, &e, NULL);
3049  fuse_finish_interrupt(f, req, &d);
3050  free_path(f, parent, path);
3051  }
3052  reply_entry(req, &e, err);
3053 }
3054 
3055 static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
3056  const char *oldname, fuse_ino_t newdir,
3057  const char *newname, unsigned int flags)
3058 {
3059  struct fuse *f = req_fuse_prepare(req);
3060  char *oldpath;
3061  char *newpath;
3062  struct node *wnode1;
3063  struct node *wnode2;
3064  int err;
3065 
3066  err = get_path2(f, olddir, oldname, newdir, newname,
3067  &oldpath, &newpath, &wnode1, &wnode2);
3068  if (!err) {
3069  struct fuse_intr_data d;
3070  err = 0;
3071  fuse_prepare_interrupt(f, req, &d);
3072  if (!f->conf.hard_remove && !(flags & RENAME_EXCHANGE) &&
3073  is_open(f, newdir, newname))
3074  err = hide_node(f, newpath, newdir, newname);
3075  if (!err) {
3076  err = fuse_fs_rename(f->fs, oldpath, newpath, flags);
3077  if (!err) {
3078  if (flags & RENAME_EXCHANGE) {
3079  err = exchange_node(f, olddir, oldname,
3080  newdir, newname);
3081  } else {
3082  err = rename_node(f, olddir, oldname,
3083  newdir, newname, 0);
3084  }
3085  }
3086  }
3087  fuse_finish_interrupt(f, req, &d);
3088  free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3089  }
3090  reply_err(req, err);
3091 }
3092 
3093 static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
3094  const char *newname)
3095 {
3096  struct fuse *f = req_fuse_prepare(req);
3097  struct fuse_entry_param e;
3098  char *oldpath;
3099  char *newpath;
3100  int err;
3101 
3102  err = get_path2(f, ino, NULL, newparent, newname,
3103  &oldpath, &newpath, NULL, NULL);
3104  if (!err) {
3105  struct fuse_intr_data d;
3106 
3107  fuse_prepare_interrupt(f, req, &d);
3108  err = fuse_fs_link(f->fs, oldpath, newpath);
3109  if (!err)
3110  err = lookup_path(f, newparent, newname, newpath,
3111  &e, NULL);
3112  fuse_finish_interrupt(f, req, &d);
3113  free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3114  }
3115  reply_entry(req, &e, err);
3116 }
3117 
3118 static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
3119  struct fuse_file_info *fi)
3120 {
3121  struct node *node;
3122  int unlink_hidden = 0;
3123 
3124  fuse_fs_release(f->fs, path, fi);
3125 
3126  pthread_mutex_lock(&f->lock);
3127  node = get_node(f, ino);
3128  assert(node->open_count > 0);
3129  --node->open_count;
3130  if (node->is_hidden && !node->open_count) {
3131  unlink_hidden = 1;
3132  node->is_hidden = 0;
3133  }
3134  pthread_mutex_unlock(&f->lock);
3135 
3136  if(unlink_hidden) {
3137  if (path) {
3138  fuse_fs_unlink(f->fs, path);
3139  } else if (f->conf.nullpath_ok) {
3140  char *unlinkpath;
3141 
3142  if (get_path(f, ino, &unlinkpath) == 0)
3143  fuse_fs_unlink(f->fs, unlinkpath);
3144 
3145  free_path(f, ino, unlinkpath);
3146  }
3147  }
3148 }
3149 
3150 static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
3151  const char *name, mode_t mode,
3152  struct fuse_file_info *fi)
3153 {
3154  struct fuse *f = req_fuse_prepare(req);
3155  struct fuse_intr_data d;
3156  struct fuse_entry_param e;
3157  char *path;
3158  int err;
3159 
3160  err = get_path_name(f, parent, name, &path);
3161  if (!err) {
3162  fuse_prepare_interrupt(f, req, &d);
3163  err = fuse_fs_create(f->fs, path, mode, fi);
3164  if (!err) {
3165  err = lookup_path(f, parent, name, path, &e, fi);
3166  if (err)
3167  fuse_fs_release(f->fs, path, fi);
3168  else if (!S_ISREG(e.attr.st_mode)) {
3169  err = -EIO;
3170  fuse_fs_release(f->fs, path, fi);
3171  forget_node(f, e.ino, 1);
3172  } else {
3173  if (f->conf.direct_io)
3174  fi->direct_io = 1;
3175  if (f->conf.kernel_cache)
3176  fi->keep_cache = 1;
3177 
3178  }
3179  }
3180  fuse_finish_interrupt(f, req, &d);
3181  }
3182  if (!err) {
3183  pthread_mutex_lock(&f->lock);
3184  get_node(f, e.ino)->open_count++;
3185  pthread_mutex_unlock(&f->lock);
3186  if (fuse_reply_create(req, &e, fi) == -ENOENT) {
3187  /* The open syscall was interrupted, so it
3188  must be cancelled */
3189  fuse_do_release(f, e.ino, path, fi);
3190  forget_node(f, e.ino, 1);
3191  }
3192  } else {
3193  reply_err(req, err);
3194  }
3195 
3196  free_path(f, parent, path);
3197 }
3198 
3199 static double diff_timespec(const struct timespec *t1,
3200  const struct timespec *t2)
3201 {
3202  return (t1->tv_sec - t2->tv_sec) +
3203  ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
3204 }
3205 
3206 static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
3207  struct fuse_file_info *fi)
3208 {
3209  struct node *node;
3210 
3211  pthread_mutex_lock(&f->lock);
3212  node = get_node(f, ino);
3213  if (node->cache_valid) {
3214  struct timespec now;
3215 
3216  curr_time(&now);
3217  if (diff_timespec(&now, &node->stat_updated) >
3218  f->conf.ac_attr_timeout) {
3219  struct stat stbuf;
3220  int err;
3221  pthread_mutex_unlock(&f->lock);
3222  err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
3223  pthread_mutex_lock(&f->lock);
3224  if (!err)
3225  update_stat(node, &stbuf);
3226  else
3227  node->cache_valid = 0;
3228  }
3229  }
3230  if (node->cache_valid)
3231  fi->keep_cache = 1;
3232 
3233  node->cache_valid = 1;
3234  pthread_mutex_unlock(&f->lock);
3235 }
3236 
3237 static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
3238  struct fuse_file_info *fi)
3239 {
3240  struct fuse *f = req_fuse_prepare(req);
3241  struct fuse_intr_data d;
3242  char *path;
3243  int err;
3244 
3245  err = get_path(f, ino, &path);
3246  if (!err) {
3247  fuse_prepare_interrupt(f, req, &d);
3248  err = fuse_fs_open(f->fs, path, fi);
3249  if (!err) {
3250  if (f->conf.direct_io)
3251  fi->direct_io = 1;
3252  if (f->conf.kernel_cache)
3253  fi->keep_cache = 1;
3254 
3255  if (f->conf.auto_cache)
3256  open_auto_cache(f, ino, path, fi);
3257  }
3258  fuse_finish_interrupt(f, req, &d);
3259  }
3260  if (!err) {
3261  pthread_mutex_lock(&f->lock);
3262  get_node(f, ino)->open_count++;
3263  pthread_mutex_unlock(&f->lock);
3264  if (fuse_reply_open(req, fi) == -ENOENT) {
3265  /* The open syscall was interrupted, so it
3266  must be cancelled */
3267  fuse_do_release(f, ino, path, fi);
3268  }
3269  } else
3270  reply_err(req, err);
3271 
3272  free_path(f, ino, path);
3273 }
3274 
3275 static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
3276  off_t off, struct fuse_file_info *fi)
3277 {
3278  struct fuse *f = req_fuse_prepare(req);
3279  struct fuse_bufvec *buf = NULL;
3280  char *path;
3281  int res;
3282 
3283  res = get_path_nullok(f, ino, &path);
3284  if (res == 0) {
3285  struct fuse_intr_data d;
3286 
3287  fuse_prepare_interrupt(f, req, &d);
3288  res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3289  fuse_finish_interrupt(f, req, &d);
3290  free_path(f, ino, path);
3291  }
3292 
3293  if (res == 0)
3295  else
3296  reply_err(req, res);
3297 
3298  fuse_free_buf(buf);
3299 }
3300 
3301 static void fuse_lib_write_buf(fuse_req_t req, fuse_ino_t ino,
3302  struct fuse_bufvec *buf, off_t off,
3303  struct fuse_file_info *fi)
3304 {
3305  struct fuse *f = req_fuse_prepare(req);
3306  char *path;
3307  int res;
3308 
3309  res = get_path_nullok(f, ino, &path);
3310  if (res == 0) {
3311  struct fuse_intr_data d;
3312 
3313  fuse_prepare_interrupt(f, req, &d);
3314  res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3315  fuse_finish_interrupt(f, req, &d);
3316  free_path(f, ino, path);
3317  }
3318 
3319  if (res >= 0)
3320  fuse_reply_write(req, res);
3321  else
3322  reply_err(req, res);
3323 }
3324 
3325 static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
3326  struct fuse_file_info *fi)
3327 {
3328  struct fuse *f = req_fuse_prepare(req);
3329  char *path;
3330  int err;
3331 
3332  err = get_path_nullok(f, ino, &path);
3333  if (!err) {
3334  struct fuse_intr_data d;
3335 
3336  fuse_prepare_interrupt(f, req, &d);
3337  err = fuse_fs_fsync(f->fs, path, datasync, fi);
3338  fuse_finish_interrupt(f, req, &d);
3339  free_path(f, ino, path);
3340  }
3341  reply_err(req, err);
3342 }
3343 
3344 static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
3345  struct fuse_file_info *fi)
3346 {
3347  struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
3348  memset(fi, 0, sizeof(struct fuse_file_info));
3349  fi->fh = dh->fh;
3350  return dh;
3351 }
3352 
3353 static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
3354  struct fuse_file_info *llfi)
3355 {
3356  struct fuse *f = req_fuse_prepare(req);
3357  struct fuse_intr_data d;
3358  struct fuse_dh *dh;
3359  struct fuse_file_info fi;
3360  char *path;
3361  int err;
3362 
3363  dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
3364  if (dh == NULL) {
3365  reply_err(req, -ENOMEM);
3366  return;
3367  }
3368  memset(dh, 0, sizeof(struct fuse_dh));
3369  dh->fuse = f;
3370  dh->contents = NULL;
3371  dh->first = NULL;
3372  dh->len = 0;
3373  dh->filled = 0;
3374  dh->nodeid = ino;
3375  fuse_mutex_init(&dh->lock);
3376 
3377  llfi->fh = (uintptr_t) dh;
3378 
3379  memset(&fi, 0, sizeof(fi));
3380  fi.flags = llfi->flags;
3381 
3382  err = get_path(f, ino, &path);
3383  if (!err) {
3384  fuse_prepare_interrupt(f, req, &d);
3385  err = fuse_fs_opendir(f->fs, path, &fi);
3386  fuse_finish_interrupt(f, req, &d);
3387  dh->fh = fi.fh;
3388  }
3389  if (!err) {
3390  if (fuse_reply_open(req, llfi) == -ENOENT) {
3391  /* The opendir syscall was interrupted, so it
3392  must be cancelled */
3393  fuse_fs_releasedir(f->fs, path, &fi);
3394  pthread_mutex_destroy(&dh->lock);
3395  free(dh);
3396  }
3397  } else {
3398  reply_err(req, err);
3399  pthread_mutex_destroy(&dh->lock);
3400  free(dh);
3401  }
3402  free_path(f, ino, path);
3403 }
3404 
3405 static int extend_contents(struct fuse_dh *dh, unsigned minsize)
3406 {
3407  if (minsize > dh->size) {
3408  char *newptr;
3409  unsigned newsize = dh->size;
3410  if (!newsize)
3411  newsize = 1024;
3412  while (newsize < minsize) {
3413  if (newsize >= 0x80000000)
3414  newsize = 0xffffffff;
3415  else
3416  newsize *= 2;
3417  }
3418 
3419  newptr = (char *) realloc(dh->contents, newsize);
3420  if (!newptr) {
3421  dh->error = -ENOMEM;
3422  return -1;
3423  }
3424  dh->contents = newptr;
3425  dh->size = newsize;
3426  }
3427  return 0;
3428 }
3429 
3430 static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name,
3431  struct stat *st)
3432 {
3433  struct fuse_direntry *de;
3434 
3435  de = malloc(sizeof(struct fuse_direntry));
3436  if (!de) {
3437  dh->error = -ENOMEM;
3438  return -1;
3439  }
3440  de->name = strdup(name);
3441  if (!de->name) {
3442  dh->error = -ENOMEM;
3443  free(de);
3444  return -1;
3445  }
3446  de->stat = *st;
3447  de->next = NULL;
3448 
3449  *dh->last = de;
3450  dh->last = &de->next;
3451 
3452  return 0;
3453 }
3454 
3455 static fuse_ino_t lookup_nodeid(struct fuse *f, fuse_ino_t parent,
3456  const char *name)
3457 {
3458  struct node *node;
3459  fuse_ino_t res = FUSE_UNKNOWN_INO;
3460 
3461  pthread_mutex_lock(&f->lock);
3462  node = lookup_node(f, parent, name);
3463  if (node)
3464  res = node->nodeid;
3465  pthread_mutex_unlock(&f->lock);
3466 
3467  return res;
3468 }
3469 
3470 static int fill_dir(void *dh_, const char *name, const struct stat *statp,
3471  off_t off, enum fuse_fill_dir_flags flags)
3472 {
3473  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3474  struct stat stbuf;
3475 
3476  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3477  dh->error = -EIO;
3478  return 1;
3479  }
3480 
3481  if (statp)
3482  stbuf = *statp;
3483  else {
3484  memset(&stbuf, 0, sizeof(stbuf));
3485  stbuf.st_ino = FUSE_UNKNOWN_INO;
3486  }
3487 
3488  if (!dh->fuse->conf.use_ino) {
3489  stbuf.st_ino = FUSE_UNKNOWN_INO;
3490  if (dh->fuse->conf.readdir_ino) {
3491  stbuf.st_ino = (ino_t)
3492  lookup_nodeid(dh->fuse, dh->nodeid, name);
3493  }
3494  }
3495 
3496  if (off) {
3497  size_t newlen;
3498 
3499  if (dh->filled) {
3500  dh->error = -EIO;
3501  return 1;
3502  }
3503 
3504  if (dh->first) {
3505  dh->error = -EIO;
3506  return 1;
3507  }
3508 
3509  if (extend_contents(dh, dh->needlen) == -1)
3510  return 1;
3511 
3512  newlen = dh->len +
3513  fuse_add_direntry(dh->req, dh->contents + dh->len,
3514  dh->needlen - dh->len, name,
3515  &stbuf, off);
3516  if (newlen > dh->needlen)
3517  return 1;
3518 
3519  dh->len = newlen;
3520  } else {
3521  dh->filled = 1;
3522 
3523  if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3524  return 1;
3525  }
3526  return 0;
3527 }
3528 
3529 static int is_dot_or_dotdot(const char *name)
3530 {
3531  return name[0] == '.' && (name[1] == '\0' ||
3532  (name[1] == '.' && name[2] == '\0'));
3533 }
3534 
3535 static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
3536  off_t off, enum fuse_fill_dir_flags flags)
3537 {
3538  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3539  struct fuse_entry_param e = {
3540  /* ino=0 tells the kernel to ignore readdirplus stat info */
3541  .ino = 0,
3542  };
3543  struct fuse *f = dh->fuse;
3544  int res;
3545 
3546  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3547  dh->error = -EIO;
3548  return 1;
3549  }
3550 
3551  if (off && statp && (flags & FUSE_FILL_DIR_PLUS)) {
3552  e.attr = *statp;
3553 
3554  if (!is_dot_or_dotdot(name)) {
3555  res = do_lookup(f, dh->nodeid, name, &e);
3556  if (res) {
3557  dh->error = res;
3558  return 1;
3559  }
3560  }
3561  } else {
3562  e.attr.st_ino = FUSE_UNKNOWN_INO;
3563  if (!f->conf.use_ino && f->conf.readdir_ino) {
3564  e.attr.st_ino = (ino_t)
3565  lookup_nodeid(f, dh->nodeid, name);
3566  }
3567  }
3568 
3569  if (off) {
3570  size_t newlen;
3571 
3572  if (dh->filled) {
3573  dh->error = -EIO;
3574  return 1;
3575  }
3576 
3577  if (dh->first) {
3578  dh->error = -EIO;
3579  return 1;
3580  }
3581  if (extend_contents(dh, dh->needlen) == -1)
3582  return 1;
3583 
3584  newlen = dh->len +
3585  fuse_add_direntry_plus(dh->req, dh->contents + dh->len,
3586  dh->needlen - dh->len, name,
3587  &e, off);
3588  if (newlen > dh->needlen)
3589  return 1;
3590  dh->len = newlen;
3591  } else {
3592  dh->filled = 1;
3593 
3594  if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1)
3595  return 1;
3596  }
3597 
3598  return 0;
3599 }
3600 
3601 static void free_direntries(struct fuse_direntry *de)
3602 {
3603  while (de) {
3604  struct fuse_direntry *next = de->next;
3605  free(de->name);
3606  free(de);
3607  de = next;
3608  }
3609 }
3610 
3611 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3612  size_t size, off_t off, struct fuse_dh *dh,
3613  struct fuse_file_info *fi,
3614  enum fuse_readdir_flags flags)
3615 {
3616  char *path;
3617  int err;
3618 
3619  if (f->fs->op.readdir)
3620  err = get_path_nullok(f, ino, &path);
3621  else
3622  err = get_path(f, ino, &path);
3623  if (!err) {
3624  struct fuse_intr_data d;
3625  fuse_fill_dir_t filler = fill_dir;
3626 
3627  if (flags & FUSE_READDIR_PLUS)
3628  filler = fill_dir_plus;
3629 
3630  free_direntries(dh->first);
3631  dh->first = NULL;
3632  dh->last = &dh->first;
3633  dh->len = 0;
3634  dh->error = 0;
3635  dh->needlen = size;
3636  dh->filled = 0;
3637  dh->req = req;
3638  fuse_prepare_interrupt(f, req, &d);
3639  err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3640  fuse_finish_interrupt(f, req, &d);
3641  dh->req = NULL;
3642  if (!err)
3643  err = dh->error;
3644  if (err)
3645  dh->filled = 0;
3646  free_path(f, ino, path);
3647  }
3648  return err;
3649 }
3650 
3651 static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh,
3652  off_t off, enum fuse_readdir_flags flags)
3653 {
3654  off_t pos;
3655  struct fuse_direntry *de = dh->first;
3656 
3657  dh->len = 0;
3658 
3659  if (extend_contents(dh, dh->needlen) == -1)
3660  return dh->error;
3661 
3662  for (pos = 0; pos < off; pos++) {
3663  if (!de)
3664  break;
3665 
3666  de = de->next;
3667  }
3668  while (de) {
3669  char *p = dh->contents + dh->len;
3670  unsigned rem = dh->needlen - dh->len;
3671  unsigned thislen;
3672  unsigned newlen;
3673  pos++;
3674 
3675  if (flags & FUSE_READDIR_PLUS) {
3676  struct fuse_entry_param e = {
3677  .ino = 0,
3678  .attr = de->stat,
3679  };
3680  thislen = fuse_add_direntry_plus(req, p, rem,
3681  de->name, &e, pos);
3682  } else {
3683  thislen = fuse_add_direntry(req, p, rem,
3684  de->name, &de->stat, pos);
3685  }
3686  newlen = dh->len + thislen;
3687  if (newlen > dh->needlen)
3688  break;
3689  dh->len = newlen;
3690  de = de->next;
3691  }
3692  return 0;
3693 }
3694 
3695 static void fuse_readdir_common(fuse_req_t req, fuse_ino_t ino, size_t size,
3696  off_t off, struct fuse_file_info *llfi,
3697  enum fuse_readdir_flags flags)
3698 {
3699  struct fuse *f = req_fuse_prepare(req);
3700  struct fuse_file_info fi;
3701  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3702  int err;
3703 
3704  pthread_mutex_lock(&dh->lock);
3705  /* According to SUS, directory contents need to be refreshed on
3706  rewinddir() */
3707  if (!off)
3708  dh->filled = 0;
3709 
3710  if (!dh->filled) {
3711  err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3712  if (err) {
3713  reply_err(req, err);
3714  goto out;
3715  }
3716  }
3717  if (dh->filled) {
3718  dh->needlen = size;
3719  err = readdir_fill_from_list(req, dh, off, flags);
3720  if (err) {
3721  reply_err(req, err);
3722  goto out;
3723  }
3724  }
3725  fuse_reply_buf(req, dh->contents, dh->len);
3726 out:
3727  pthread_mutex_unlock(&dh->lock);
3728 }
3729 
3730 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3731  off_t off, struct fuse_file_info *llfi)
3732 {
3733  fuse_readdir_common(req, ino, size, off, llfi, 0);
3734 }
3735 
3736 static void fuse_lib_readdirplus(fuse_req_t req, fuse_ino_t ino, size_t size,
3737  off_t off, struct fuse_file_info *llfi)
3738 {
3739  fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3740 }
3741 
3742 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3743  struct fuse_file_info *llfi)
3744 {
3745  struct fuse *f = req_fuse_prepare(req);
3746  struct fuse_intr_data d;
3747  struct fuse_file_info fi;
3748  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3749  char *path;
3750 
3751  get_path_nullok(f, ino, &path);
3752 
3753  fuse_prepare_interrupt(f, req, &d);
3754  fuse_fs_releasedir(f->fs, path, &fi);
3755  fuse_finish_interrupt(f, req, &d);
3756  free_path(f, ino, path);
3757 
3758  pthread_mutex_lock(&dh->lock);
3759  pthread_mutex_unlock(&dh->lock);
3760  pthread_mutex_destroy(&dh->lock);
3761  free_direntries(dh->first);
3762  free(dh->contents);
3763  free(dh);
3764  reply_err(req, 0);
3765 }
3766 
3767 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3768  struct fuse_file_info *llfi)
3769 {
3770  struct fuse *f = req_fuse_prepare(req);
3771  struct fuse_file_info fi;
3772  char *path;
3773  int err;
3774 
3775  get_dirhandle(llfi, &fi);
3776 
3777  err = get_path_nullok(f, ino, &path);
3778  if (!err) {
3779  struct fuse_intr_data d;
3780  fuse_prepare_interrupt(f, req, &d);
3781  err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3782  fuse_finish_interrupt(f, req, &d);
3783  free_path(f, ino, path);
3784  }
3785  reply_err(req, err);
3786 }
3787 
3788 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3789 {
3790  struct fuse *f = req_fuse_prepare(req);
3791  struct statvfs buf;
3792  char *path = NULL;
3793  int err = 0;
3794 
3795  memset(&buf, 0, sizeof(buf));
3796  if (ino)
3797  err = get_path(f, ino, &path);
3798 
3799  if (!err) {
3800  struct fuse_intr_data d;
3801  fuse_prepare_interrupt(f, req, &d);
3802  err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3803  fuse_finish_interrupt(f, req, &d);
3804  free_path(f, ino, path);
3805  }
3806 
3807  if (!err)
3808  fuse_reply_statfs(req, &buf);
3809  else
3810  reply_err(req, err);
3811 }
3812 
3813 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3814  const char *value, size_t size, int flags)
3815 {
3816  struct fuse *f = req_fuse_prepare(req);
3817  char *path;
3818  int err;
3819 
3820  err = get_path(f, ino, &path);
3821  if (!err) {
3822  struct fuse_intr_data d;
3823  fuse_prepare_interrupt(f, req, &d);
3824  err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3825  fuse_finish_interrupt(f, req, &d);
3826  free_path(f, ino, path);
3827  }
3828  reply_err(req, err);
3829 }
3830 
3831 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3832  const char *name, char *value, size_t size)
3833 {
3834  int err;
3835  char *path;
3836 
3837  err = get_path(f, ino, &path);
3838  if (!err) {
3839  struct fuse_intr_data d;
3840  fuse_prepare_interrupt(f, req, &d);
3841  err = fuse_fs_getxattr(f->fs, path, name, value, size);
3842  fuse_finish_interrupt(f, req, &d);
3843  free_path(f, ino, path);
3844  }
3845  return err;
3846 }
3847 
3848 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3849  size_t size)
3850 {
3851  struct fuse *f = req_fuse_prepare(req);
3852  int res;
3853 
3854  if (size) {
3855  char *value = (char *) malloc(size);
3856  if (value == NULL) {
3857  reply_err(req, -ENOMEM);
3858  return;
3859  }
3860  res = common_getxattr(f, req, ino, name, value, size);
3861  if (res > 0)
3862  fuse_reply_buf(req, value, res);
3863  else
3864  reply_err(req, res);
3865  free(value);
3866  } else {
3867  res = common_getxattr(f, req, ino, name, NULL, 0);
3868  if (res >= 0)
3869  fuse_reply_xattr(req, res);
3870  else
3871  reply_err(req, res);
3872  }
3873 }
3874 
3875 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3876  char *list, size_t size)
3877 {
3878  char *path;
3879  int err;
3880 
3881  err = get_path(f, ino, &path);
3882  if (!err) {
3883  struct fuse_intr_data d;
3884  fuse_prepare_interrupt(f, req, &d);
3885  err = fuse_fs_listxattr(f->fs, path, list, size);
3886  fuse_finish_interrupt(f, req, &d);
3887  free_path(f, ino, path);
3888  }
3889  return err;
3890 }
3891 
3892 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3893 {
3894  struct fuse *f = req_fuse_prepare(req);
3895  int res;
3896 
3897  if (size) {
3898  char *list = (char *) malloc(size);
3899  if (list == NULL) {
3900  reply_err(req, -ENOMEM);
3901  return;
3902  }
3903  res = common_listxattr(f, req, ino, list, size);
3904  if (res > 0)
3905  fuse_reply_buf(req, list, res);
3906  else
3907  reply_err(req, res);
3908  free(list);
3909  } else {
3910  res = common_listxattr(f, req, ino, NULL, 0);
3911  if (res >= 0)
3912  fuse_reply_xattr(req, res);
3913  else
3914  reply_err(req, res);
3915  }
3916 }
3917 
3918 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3919  const char *name)
3920 {
3921  struct fuse *f = req_fuse_prepare(req);
3922  char *path;
3923  int err;
3924 
3925  err = get_path(f, ino, &path);
3926  if (!err) {
3927  struct fuse_intr_data d;
3928  fuse_prepare_interrupt(f, req, &d);
3929  err = fuse_fs_removexattr(f->fs, path, name);
3930  fuse_finish_interrupt(f, req, &d);
3931  free_path(f, ino, path);
3932  }
3933  reply_err(req, err);
3934 }
3935 
3936 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3937 {
3938  struct lock *l;
3939 
3940  for (l = node->locks; l; l = l->next)
3941  if (l->owner != lock->owner &&
3942  lock->start <= l->end && l->start <= lock->end &&
3943  (l->type == F_WRLCK || lock->type == F_WRLCK))
3944  break;
3945 
3946  return l;
3947 }
3948 
3949 static void delete_lock(struct lock **lockp)
3950 {
3951  struct lock *l = *lockp;
3952  *lockp = l->next;
3953  free(l);
3954 }
3955 
3956 static void insert_lock(struct lock **pos, struct lock *lock)
3957 {
3958  lock->next = *pos;
3959  *pos = lock;
3960 }
3961 
3962 static int locks_insert(struct node *node, struct lock *lock)
3963 {
3964  struct lock **lp;
3965  struct lock *newl1 = NULL;
3966  struct lock *newl2 = NULL;
3967 
3968  if (lock->type != F_UNLCK || lock->start != 0 ||
3969  lock->end != OFFSET_MAX) {
3970  newl1 = malloc(sizeof(struct lock));
3971  newl2 = malloc(sizeof(struct lock));
3972 
3973  if (!newl1 || !newl2) {
3974  free(newl1);
3975  free(newl2);
3976  return -ENOLCK;
3977  }
3978  }
3979 
3980  for (lp = &node->locks; *lp;) {
3981  struct lock *l = *lp;
3982  if (l->owner != lock->owner)
3983  goto skip;
3984 
3985  if (lock->type == l->type) {
3986  if (l->end < lock->start - 1)
3987  goto skip;
3988  if (lock->end < l->start - 1)
3989  break;
3990  if (l->start <= lock->start && lock->end <= l->end)
3991  goto out;
3992  if (l->start < lock->start)
3993  lock->start = l->start;
3994  if (lock->end < l->end)
3995  lock->end = l->end;
3996  goto delete;
3997  } else {
3998  if (l->end < lock->start)
3999  goto skip;
4000  if (lock->end < l->start)
4001  break;
4002  if (lock->start <= l->start && l->end <= lock->end)
4003  goto delete;
4004  if (l->end <= lock->end) {
4005  l->end = lock->start - 1;
4006  goto skip;
4007  }
4008  if (lock->start <= l->start) {
4009  l->start = lock->end + 1;
4010  break;
4011  }
4012  *newl2 = *l;
4013  newl2->start = lock->end + 1;
4014  l->end = lock->start - 1;
4015  insert_lock(&l->next, newl2);
4016  newl2 = NULL;
4017  }
4018  skip:
4019  lp = &l->next;
4020  continue;
4021 
4022  delete:
4023  delete_lock(lp);
4024  }
4025  if (lock->type != F_UNLCK) {
4026  *newl1 = *lock;
4027  insert_lock(lp, newl1);
4028  newl1 = NULL;
4029  }
4030 out:
4031  free(newl1);
4032  free(newl2);
4033  return 0;
4034 }
4035 
4036 static void flock_to_lock(struct flock *flock, struct lock *lock)
4037 {
4038  memset(lock, 0, sizeof(struct lock));
4039  lock->type = flock->l_type;
4040  lock->start = flock->l_start;
4041  lock->end =
4042  flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4043  lock->pid = flock->l_pid;
4044 }
4045 
4046 static void lock_to_flock(struct lock *lock, struct flock *flock)
4047 {
4048  flock->l_type = lock->type;
4049  flock->l_start = lock->start;
4050  flock->l_len =
4051  (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4052  flock->l_pid = lock->pid;
4053 }
4054 
4055 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
4056  const char *path, struct fuse_file_info *fi)
4057 {
4058  struct fuse_intr_data d;
4059  struct flock lock;
4060  struct lock l;
4061  int err;
4062  int errlock;
4063 
4064  fuse_prepare_interrupt(f, req, &d);
4065  memset(&lock, 0, sizeof(lock));
4066  lock.l_type = F_UNLCK;
4067  lock.l_whence = SEEK_SET;
4068  err = fuse_fs_flush(f->fs, path, fi);
4069  errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4070  fuse_finish_interrupt(f, req, &d);
4071 
4072  if (errlock != -ENOSYS) {
4073  flock_to_lock(&lock, &l);
4074  l.owner = fi->lock_owner;
4075  pthread_mutex_lock(&f->lock);
4076  locks_insert(get_node(f, ino), &l);
4077  pthread_mutex_unlock(&f->lock);
4078 
4079  /* if op.lock() is defined FLUSH is needed regardless
4080  of op.flush() */
4081  if (err == -ENOSYS)
4082  err = 0;
4083  }
4084  return err;
4085 }
4086 
4087 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
4088  struct fuse_file_info *fi)
4089 {
4090  struct fuse *f = req_fuse_prepare(req);
4091  struct fuse_intr_data d;
4092  char *path;
4093  int err = 0;
4094 
4095  get_path_nullok(f, ino, &path);
4096  if (fi->flush) {
4097  err = fuse_flush_common(f, req, ino, path, fi);
4098  if (err == -ENOSYS)
4099  err = 0;
4100  }
4101 
4102  fuse_prepare_interrupt(f, req, &d);
4103  fuse_do_release(f, ino, path, fi);
4104  fuse_finish_interrupt(f, req, &d);
4105  free_path(f, ino, path);
4106 
4107  reply_err(req, err);
4108 }
4109 
4110 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
4111  struct fuse_file_info *fi)
4112 {
4113  struct fuse *f = req_fuse_prepare(req);
4114  char *path;
4115  int err;
4116 
4117  get_path_nullok(f, ino, &path);
4118  err = fuse_flush_common(f, req, ino, path, fi);
4119  free_path(f, ino, path);
4120 
4121  reply_err(req, err);
4122 }
4123 
4124 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
4125  struct fuse_file_info *fi, struct flock *lock,
4126  int cmd)
4127 {
4128  struct fuse *f = req_fuse_prepare(req);
4129  char *path;
4130  int err;
4131 
4132  err = get_path_nullok(f, ino, &path);
4133  if (!err) {
4134  struct fuse_intr_data d;
4135  fuse_prepare_interrupt(f, req, &d);
4136  err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4137  fuse_finish_interrupt(f, req, &d);
4138  free_path(f, ino, path);
4139  }
4140  return err;
4141 }
4142 
4143 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
4144  struct fuse_file_info *fi, struct flock *lock)
4145 {
4146  int err;
4147  struct lock l;
4148  struct lock *conflict;
4149  struct fuse *f = req_fuse(req);
4150 
4151  flock_to_lock(lock, &l);
4152  l.owner = fi->lock_owner;
4153  pthread_mutex_lock(&f->lock);
4154  conflict = locks_conflict(get_node(f, ino), &l);
4155  if (conflict)
4156  lock_to_flock(conflict, lock);
4157  pthread_mutex_unlock(&f->lock);
4158  if (!conflict)
4159  err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4160  else
4161  err = 0;
4162 
4163  if (!err)
4164  fuse_reply_lock(req, lock);
4165  else
4166  reply_err(req, err);
4167 }
4168 
4169 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
4170  struct fuse_file_info *fi, struct flock *lock,
4171  int sleep)
4172 {
4173  int err = fuse_lock_common(req, ino, fi, lock,
4174  sleep ? F_SETLKW : F_SETLK);
4175  if (!err) {
4176  struct fuse *f = req_fuse(req);
4177  struct lock l;
4178  flock_to_lock(lock, &l);
4179  l.owner = fi->lock_owner;
4180  pthread_mutex_lock(&f->lock);
4181  locks_insert(get_node(f, ino), &l);
4182  pthread_mutex_unlock(&f->lock);
4183  }
4184  reply_err(req, err);
4185 }
4186 
4187 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
4188  struct fuse_file_info *fi, int op)
4189 {
4190  struct fuse *f = req_fuse_prepare(req);
4191  char *path;
4192  int err;
4193 
4194  err = get_path_nullok(f, ino, &path);
4195  if (err == 0) {
4196  struct fuse_intr_data d;
4197  fuse_prepare_interrupt(f, req, &d);
4198  err = fuse_fs_flock(f->fs, path, fi, op);
4199  fuse_finish_interrupt(f, req, &d);
4200  free_path(f, ino, path);
4201  }
4202  reply_err(req, err);
4203 }
4204 
4205 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
4206  uint64_t idx)
4207 {
4208  struct fuse *f = req_fuse_prepare(req);
4209  struct fuse_intr_data d;
4210  char *path;
4211  int err;
4212 
4213  err = get_path(f, ino, &path);
4214  if (!err) {
4215  fuse_prepare_interrupt(f, req, &d);
4216  err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4217  fuse_finish_interrupt(f, req, &d);
4218  free_path(f, ino, path);
4219  }
4220  if (!err)
4221  fuse_reply_bmap(req, idx);
4222  else
4223  reply_err(req, err);
4224 }
4225 
4226 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, unsigned int cmd,
4227  void *arg, struct fuse_file_info *llfi,
4228  unsigned int flags, const void *in_buf,
4229  size_t in_bufsz, size_t out_bufsz)
4230 {
4231  struct fuse *f = req_fuse_prepare(req);
4232  struct fuse_intr_data d;
4233  struct fuse_file_info fi;
4234  char *path, *out_buf = NULL;
4235  int err;
4236 
4237  err = -EPERM;
4238  if (flags & FUSE_IOCTL_UNRESTRICTED)
4239  goto err;
4240 
4241  if (flags & FUSE_IOCTL_DIR)
4242  get_dirhandle(llfi, &fi);
4243  else
4244  fi = *llfi;
4245 
4246  if (out_bufsz) {
4247  err = -ENOMEM;
4248  out_buf = malloc(out_bufsz);
4249  if (!out_buf)
4250  goto err;
4251  }
4252 
4253  assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4254  if (out_buf && in_bufsz)
4255  memcpy(out_buf, in_buf, in_bufsz);
4256 
4257  err = get_path_nullok(f, ino, &path);
4258  if (err)
4259  goto err;
4260 
4261  fuse_prepare_interrupt(f, req, &d);
4262 
4263  err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4264  out_buf ? out_buf : (void *)in_buf);
4265 
4266  fuse_finish_interrupt(f, req, &d);
4267  free_path(f, ino, path);
4268 
4269  fuse_reply_ioctl(req, err, out_buf, out_bufsz);
4270  goto out;
4271 err:
4272  reply_err(req, err);
4273 out:
4274  free(out_buf);
4275 }
4276 
4277 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
4278  struct fuse_file_info *fi, struct fuse_pollhandle *ph)
4279 {
4280  struct fuse *f = req_fuse_prepare(req);
4281  struct fuse_intr_data d;
4282  char *path;
4283  int err;
4284  unsigned revents = 0;
4285 
4286  err = get_path_nullok(f, ino, &path);
4287  if (!err) {
4288  fuse_prepare_interrupt(f, req, &d);
4289  err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4290  fuse_finish_interrupt(f, req, &d);
4291  free_path(f, ino, path);
4292  }
4293  if (!err)
4294  fuse_reply_poll(req, revents);
4295  else
4296  reply_err(req, err);
4297 }
4298 
4299 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
4300  off_t offset, off_t length, struct fuse_file_info *fi)
4301 {
4302  struct fuse *f = req_fuse_prepare(req);
4303  struct fuse_intr_data d;
4304  char *path;
4305  int err;
4306 
4307  err = get_path_nullok(f, ino, &path);
4308  if (!err) {
4309  fuse_prepare_interrupt(f, req, &d);
4310  err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4311  fuse_finish_interrupt(f, req, &d);
4312  free_path(f, ino, path);
4313  }
4314  reply_err(req, err);
4315 }
4316 
4317 static void fuse_lib_copy_file_range(fuse_req_t req, fuse_ino_t nodeid_in,
4318  off_t off_in, struct fuse_file_info *fi_in,
4319  fuse_ino_t nodeid_out, off_t off_out,
4320  struct fuse_file_info *fi_out, size_t len,
4321  int flags)
4322 {
4323  struct fuse *f = req_fuse_prepare(req);
4324  struct fuse_intr_data d;
4325  char *path_in, *path_out;
4326  int err;
4327  ssize_t res;
4328 
4329  err = get_path_nullok(f, nodeid_in, &path_in);
4330  if (err) {
4331  reply_err(req, err);
4332  return;
4333  }
4334 
4335  err = get_path_nullok(f, nodeid_out, &path_out);
4336  if (err) {
4337  free_path(f, nodeid_in, path_in);
4338  reply_err(req, err);
4339  return;
4340  }
4341 
4342  fuse_prepare_interrupt(f, req, &d);
4343  res = fuse_fs_copy_file_range(f->fs, path_in, fi_in, off_in, path_out,
4344  fi_out, off_out, len, flags);
4345  fuse_finish_interrupt(f, req, &d);
4346 
4347  if (res >= 0)
4348  fuse_reply_write(req, res);
4349  else
4350  reply_err(req, res);
4351 
4352  free_path(f, nodeid_in, path_in);
4353  free_path(f, nodeid_out, path_out);
4354 }
4355 
4356 static int clean_delay(struct fuse *f)
4357 {
4358  /*
4359  * This is calculating the delay between clean runs. To
4360  * reduce the number of cleans we are doing them 10 times
4361  * within the remember window.
4362  */
4363  int min_sleep = 60;
4364  int max_sleep = 3600;
4365  int sleep_time = f->conf.remember / 10;
4366 
4367  if (sleep_time > max_sleep)
4368  return max_sleep;
4369  if (sleep_time < min_sleep)
4370  return min_sleep;
4371  return sleep_time;
4372 }
4373 
4374 int fuse_clean_cache(struct fuse *f)
4375 {
4376  struct node_lru *lnode;
4377  struct list_head *curr, *next;
4378  struct node *node;
4379  struct timespec now;
4380 
4381  pthread_mutex_lock(&f->lock);
4382 
4383  curr_time(&now);
4384 
4385  for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4386  double age;
4387 
4388  next = curr->next;
4389  lnode = list_entry(curr, struct node_lru, lru);
4390  node = &lnode->node;
4391 
4392  age = diff_timespec(&now, &lnode->forget_time);
4393  if (age <= f->conf.remember)
4394  break;
4395 
4396  assert(node->nlookup == 1);
4397 
4398  /* Don't forget active directories */
4399  if (node->refctr > 1)
4400  continue;
4401 
4402  node->nlookup = 0;
4403  unhash_name(f, node);
4404  unref_node(f, node);
4405  }
4406  pthread_mutex_unlock(&f->lock);
4407 
4408  return clean_delay(f);
4409 }
4410 
4411 static struct fuse_lowlevel_ops fuse_path_ops = {
4412  .init = fuse_lib_init,
4413  .destroy = fuse_lib_destroy,
4414  .lookup = fuse_lib_lookup,
4415  .forget = fuse_lib_forget,
4416  .forget_multi = fuse_lib_forget_multi,
4417  .getattr = fuse_lib_getattr,
4418  .setattr = fuse_lib_setattr,
4419  .access = fuse_lib_access,
4420  .readlink = fuse_lib_readlink,
4421  .mknod = fuse_lib_mknod,
4422  .mkdir = fuse_lib_mkdir,
4423  .unlink = fuse_lib_unlink,
4424  .rmdir = fuse_lib_rmdir,
4425  .symlink = fuse_lib_symlink,
4426  .rename = fuse_lib_rename,
4427  .link = fuse_lib_link,
4428  .create = fuse_lib_create,
4429  .open = fuse_lib_open,
4430  .read = fuse_lib_read,
4431  .write_buf = fuse_lib_write_buf,
4432  .flush = fuse_lib_flush,
4433  .release = fuse_lib_release,
4434  .fsync = fuse_lib_fsync,
4435  .opendir = fuse_lib_opendir,
4436  .readdir = fuse_lib_readdir,
4437  .readdirplus = fuse_lib_readdirplus,
4438  .releasedir = fuse_lib_releasedir,
4439  .fsyncdir = fuse_lib_fsyncdir,
4440  .statfs = fuse_lib_statfs,
4441  .setxattr = fuse_lib_setxattr,
4442  .getxattr = fuse_lib_getxattr,
4443  .listxattr = fuse_lib_listxattr,
4444  .removexattr = fuse_lib_removexattr,
4445  .getlk = fuse_lib_getlk,
4446  .setlk = fuse_lib_setlk,
4447  .flock = fuse_lib_flock,
4448  .bmap = fuse_lib_bmap,
4449  .ioctl = fuse_lib_ioctl,
4450  .poll = fuse_lib_poll,
4451  .fallocate = fuse_lib_fallocate,
4452  .copy_file_range = fuse_lib_copy_file_range,
4453 };
4454 
4455 int fuse_notify_poll(struct fuse_pollhandle *ph)
4456 {
4457  return fuse_lowlevel_notify_poll(ph);
4458 }
4459 
4460 struct fuse_session *fuse_get_session(struct fuse *f)
4461 {
4462  return f->se;
4463 }
4464 
4465 static int fuse_session_loop_remember(struct fuse *f)
4466 {
4467  struct fuse_session *se = f->se;
4468  int res = 0;
4469  struct timespec now;
4470  time_t next_clean;
4471  struct pollfd fds = {
4472  .fd = se->fd,
4473  .events = POLLIN
4474  };
4475  struct fuse_buf fbuf = {
4476  .mem = NULL,
4477  };
4478 
4479  curr_time(&now);
4480  next_clean = now.tv_sec;
4481  while (!fuse_session_exited(se)) {
4482  unsigned timeout;
4483 
4484  curr_time(&now);
4485  if (now.tv_sec < next_clean)
4486  timeout = next_clean - now.tv_sec;
4487  else
4488  timeout = 0;
4489 
4490  res = poll(&fds, 1, timeout * 1000);
4491  if (res == -1) {
4492  if (errno == -EINTR)
4493  continue;
4494  else
4495  break;
4496  } else if (res > 0) {
4497  res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4498 
4499  if (res == -EINTR)
4500  continue;
4501  if (res <= 0)
4502  break;
4503 
4504  fuse_session_process_buf_int(se, &fbuf, NULL);
4505  } else {
4506  timeout = fuse_clean_cache(f);
4507  curr_time(&now);
4508  next_clean = now.tv_sec + timeout;
4509  }
4510  }
4511 
4512  free(fbuf.mem);
4513  fuse_session_reset(se);
4514  return res < 0 ? -1 : 0;
4515 }
4516 
4517 int fuse_loop(struct fuse *f)
4518 {
4519  if (!f)
4520  return -1;
4521 
4522  if (lru_enabled(f))
4523  return fuse_session_loop_remember(f);
4524 
4525  return fuse_session_loop(f->se);
4526 }
4527 
4528 FUSE_SYMVER(".symver fuse_loop_mt_32,fuse_loop_mt@@FUSE_3.2");
4529 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
4530 {
4531  if (f == NULL)
4532  return -1;
4533 
4534  int res = fuse_start_cleanup_thread(f);
4535  if (res)
4536  return -1;
4537 
4538  res = fuse_session_loop_mt_32(fuse_get_session(f), config);
4540  return res;
4541 }
4542 
4543 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
4544 FUSE_SYMVER(".symver fuse_loop_mt_31,fuse_loop_mt@FUSE_3.0");
4545 int fuse_loop_mt_31(struct fuse *f, int clone_fd)
4546 {
4547  struct fuse_loop_config config;
4548  config.clone_fd = clone_fd;
4549  config.max_idle_threads = 10;
4550  return fuse_loop_mt_32(f, &config);
4551 }
4552 
4553 void fuse_exit(struct fuse *f)
4554 {
4555  fuse_session_exit(f->se);
4556 }
4557 
4559 {
4560  struct fuse_context_i *c = fuse_get_context_internal();
4561 
4562  if (c)
4563  return &c->ctx;
4564  else
4565  return NULL;
4566 }
4567 
4568 int fuse_getgroups(int size, gid_t list[])
4569 {
4570  struct fuse_context_i *c = fuse_get_context_internal();
4571  if (!c)
4572  return -EINVAL;
4573 
4574  return fuse_req_getgroups(c->req, size, list);
4575 }
4576 
4578 {
4579  struct fuse_context_i *c = fuse_get_context_internal();
4580 
4581  if (c)
4582  return fuse_req_interrupted(c->req);
4583  else
4584  return 0;
4585 }
4586 
4587 int fuse_invalidate_path(struct fuse *f, const char *path) {
4588  fuse_ino_t ino;
4589  int err = lookup_path_in_cache(f, path, &ino);
4590  if (err) {
4591  return err;
4592  }
4593 
4594  return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
4595 }
4596 
4597 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4598 
4599 static const struct fuse_opt fuse_lib_opts[] = {
4600  FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
4602  FUSE_LIB_OPT("debug", debug, 1),
4603  FUSE_LIB_OPT("-d", debug, 1),
4604  FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
4605  FUSE_LIB_OPT("auto_cache", auto_cache, 1),
4606  FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
4607  FUSE_LIB_OPT("umask=", set_mode, 1),
4608  FUSE_LIB_OPT("umask=%o", umask, 0),
4609  FUSE_LIB_OPT("uid=", set_uid, 1),
4610  FUSE_LIB_OPT("uid=%d", uid, 0),
4611  FUSE_LIB_OPT("gid=", set_gid, 1),
4612  FUSE_LIB_OPT("gid=%d", gid, 0),
4613  FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
4614  FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
4615  FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
4616  FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
4617  FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
4618  FUSE_LIB_OPT("noforget", remember, -1),
4619  FUSE_LIB_OPT("remember=%u", remember, 0),
4620  FUSE_LIB_OPT("modules=%s", modules, 0),
4621  FUSE_OPT_END
4622 };
4623 
4624 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4625  struct fuse_args *outargs)
4626 {
4627  (void) arg; (void) outargs; (void) data; (void) key;
4628 
4629  /* Pass through unknown options */
4630  return 1;
4631 }
4632 
4633 
4634 static const struct fuse_opt fuse_help_opts[] = {
4635  FUSE_LIB_OPT("modules=%s", modules, 1),
4636  FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP),
4637  FUSE_OPT_END
4638 };
4639 
4640 static void print_module_help(const char *name,
4641  fuse_module_factory_t *fac)
4642 {
4643  struct fuse_args a = FUSE_ARGS_INIT(0, NULL);
4644  if (fuse_opt_add_arg(&a, "") == -1 ||
4645  fuse_opt_add_arg(&a, "-h") == -1)
4646  return;
4647  printf("\nOptions for %s module:\n", name);
4648  (*fac)(&a, NULL);
4649  fuse_opt_free_args(&a);
4650 }
4651 
4652 void fuse_lib_help(struct fuse_args *args)
4653 {
4654  /* These are not all options, but only the ones that
4655  may be of interest to an end-user */
4656  printf(
4657 " -o kernel_cache cache files in kernel\n"
4658 " -o [no]auto_cache enable caching based on modification times (off)\n"
4659 " -o umask=M set file permissions (octal)\n"
4660 " -o uid=N set file owner\n"
4661 " -o gid=N set file group\n"
4662 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4663 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4664 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4665 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4666 " -o noforget never forget cached inodes\n"
4667 " -o remember=T remember cached inodes for T seconds (0s)\n"
4668 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4669 
4670 
4671  /* Print low-level help */
4673 
4674  /* Print help for builtin modules */
4675  print_module_help("subdir", &fuse_module_subdir_factory);
4676 #ifdef HAVE_ICONV
4677  print_module_help("iconv", &fuse_module_iconv_factory);
4678 #endif
4679 
4680  /* Parse command line options in case we need to
4681  activate more modules */
4682  struct fuse_config conf = { .modules = NULL };
4683  if (fuse_opt_parse(args, &conf, fuse_help_opts,
4684  fuse_lib_opt_proc) == -1
4685  || !conf.modules)
4686  return;
4687 
4688  char *module;
4689  char *next;
4690  struct fuse_module *m;
4691 
4692  // Iterate over all modules
4693  for (module = conf.modules; module; module = next) {
4694  char *p;
4695  for (p = module; *p && *p != ':'; p++);
4696  next = *p ? p + 1 : NULL;
4697  *p = '\0';
4698 
4699  m = fuse_get_module(module);
4700  if (m)
4701  print_module_help(module, &m->factory);
4702  }
4703 }
4704 
4705 
4706 
4707 static int fuse_init_intr_signal(int signum, int *installed)
4708 {
4709  struct sigaction old_sa;
4710 
4711  if (sigaction(signum, NULL, &old_sa) == -1) {
4712  perror("fuse: cannot get old signal handler");
4713  return -1;
4714  }
4715 
4716  if (old_sa.sa_handler == SIG_DFL) {
4717  struct sigaction sa;
4718 
4719  memset(&sa, 0, sizeof(struct sigaction));
4720  sa.sa_handler = fuse_intr_sighandler;
4721  sigemptyset(&sa.sa_mask);
4722 
4723  if (sigaction(signum, &sa, NULL) == -1) {
4724  perror("fuse: cannot set interrupt signal handler");
4725  return -1;
4726  }
4727  *installed = 1;
4728  }
4729  return 0;
4730 }
4731 
4732 static void fuse_restore_intr_signal(int signum)
4733 {
4734  struct sigaction sa;
4735 
4736  memset(&sa, 0, sizeof(struct sigaction));
4737  sa.sa_handler = SIG_DFL;
4738  sigaction(signum, &sa, NULL);
4739 }
4740 
4741 
4742 static int fuse_push_module(struct fuse *f, const char *module,
4743  struct fuse_args *args)
4744 {
4745  struct fuse_fs *fs[2] = { f->fs, NULL };
4746  struct fuse_fs *newfs;
4747  struct fuse_module *m = fuse_get_module(module);
4748 
4749  if (!m)
4750  return -1;
4751 
4752  newfs = m->factory(args, fs);
4753  if (!newfs) {
4754  fuse_put_module(m);
4755  return -1;
4756  }
4757  newfs->m = m;
4758  f->fs = newfs;
4759  return 0;
4760 }
4761 
4762 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4763  void *user_data)
4764 {
4765  struct fuse_fs *fs;
4766 
4767  if (sizeof(struct fuse_operations) < op_size) {
4768  fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
4769  op_size = sizeof(struct fuse_operations);
4770  }
4771 
4772  fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4773  if (!fs) {
4774  fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
4775  return NULL;
4776  }
4777 
4778  fs->user_data = user_data;
4779  if (op)
4780  memcpy(&fs->op, op, op_size);
4781  return fs;
4782 }
4783 
4784 static int node_table_init(struct node_table *t)
4785 {
4786  t->size = NODE_TABLE_MIN_SIZE;
4787  t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4788  if (t->array == NULL) {
4789  fprintf(stderr, "fuse: memory allocation failed\n");
4790  return -1;
4791  }
4792  t->use = 0;
4793  t->split = 0;
4794 
4795  return 0;
4796 }
4797 
4798 static void *fuse_prune_nodes(void *fuse)
4799 {
4800  struct fuse *f = fuse;
4801  int sleep_time;
4802 
4803  while(1) {
4804  sleep_time = fuse_clean_cache(f);
4805  sleep(sleep_time);
4806  }
4807  return NULL;
4808 }
4809 
4810 int fuse_start_cleanup_thread(struct fuse *f)
4811 {
4812  if (lru_enabled(f))
4813  return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4814 
4815  return 0;
4816 }
4817 
4818 void fuse_stop_cleanup_thread(struct fuse *f)
4819 {
4820  if (lru_enabled(f)) {
4821  pthread_mutex_lock(&f->lock);
4822  pthread_cancel(f->prune_thread);
4823  pthread_mutex_unlock(&f->lock);
4824  pthread_join(f->prune_thread, NULL);
4825  }
4826 }
4827 
4828 
4829 FUSE_SYMVER(".symver fuse_new_31,fuse_new@@FUSE_3.1");
4830 struct fuse *fuse_new_31(struct fuse_args *args,
4831  const struct fuse_operations *op,
4832  size_t op_size, void *user_data)
4833 {
4834  struct fuse *f;
4835  struct node *root;
4836  struct fuse_fs *fs;
4837  struct fuse_lowlevel_ops llop = fuse_path_ops;
4838 
4839  f = (struct fuse *) calloc(1, sizeof(struct fuse));
4840  if (f == NULL) {
4841  fprintf(stderr, "fuse: failed to allocate fuse object\n");
4842  goto out;
4843  }
4844 
4845  f->conf.entry_timeout = 1.0;
4846  f->conf.attr_timeout = 1.0;
4847  f->conf.negative_timeout = 0.0;
4848  f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4849 
4850  /* Parse options */
4851  if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4852  fuse_lib_opt_proc) == -1)
4853  goto out_free;
4854 
4855  pthread_mutex_lock(&fuse_context_lock);
4856  static int builtin_modules_registered = 0;
4857  /* Have the builtin modules already been registered? */
4858  if (builtin_modules_registered == 0) {
4859  /* If not, register them. */
4860  fuse_register_module("subdir", fuse_module_subdir_factory, NULL);
4861 #ifdef HAVE_ICONV
4862  fuse_register_module("iconv", fuse_module_iconv_factory, NULL);
4863 #endif
4864  builtin_modules_registered= 1;
4865  }
4866  pthread_mutex_unlock(&fuse_context_lock);
4867 
4868  if (fuse_create_context_key() == -1)
4869  goto out_free;
4870 
4871  fs = fuse_fs_new(op, op_size, user_data);
4872  if (!fs)
4873  goto out_delete_context_key;
4874 
4875  f->fs = fs;
4876 
4877  /* Oh f**k, this is ugly! */
4878  if (!fs->op.lock) {
4879  llop.getlk = NULL;
4880  llop.setlk = NULL;
4881  }
4882 
4883  f->pagesize = getpagesize();
4884  init_list_head(&f->partial_slabs);
4885  init_list_head(&f->full_slabs);
4886  init_list_head(&f->lru_table);
4887 
4888  if (f->conf.modules) {
4889  char *module;
4890  char *next;
4891 
4892  for (module = f->conf.modules; module; module = next) {
4893  char *p;
4894  for (p = module; *p && *p != ':'; p++);
4895  next = *p ? p + 1 : NULL;
4896  *p = '\0';
4897  if (module[0] &&
4898  fuse_push_module(f, module, args) == -1)
4899  goto out_free_fs;
4900  }
4901  }
4902 
4903  if (!f->conf.ac_attr_timeout_set)
4904  f->conf.ac_attr_timeout = f->conf.attr_timeout;
4905 
4906 #if defined(__FreeBSD__) || defined(__NetBSD__)
4907  /*
4908  * In FreeBSD, we always use these settings as inode numbers
4909  * are needed to make getcwd(3) work.
4910  */
4911  f->conf.readdir_ino = 1;
4912 #endif
4913 
4914  f->se = fuse_session_new(args, &llop, sizeof(llop), f);
4915  if (f->se == NULL)
4916  goto out_free_fs;
4917 
4918  if (f->conf.debug) {
4919  fprintf(stderr, "nullpath_ok: %i\n", f->conf.nullpath_ok);
4920  }
4921 
4922  /* Trace topmost layer by default */
4923  f->fs->debug = f->conf.debug;
4924  f->ctr = 0;
4925  f->generation = 0;
4926  if (node_table_init(&f->name_table) == -1)
4927  goto out_free_session;
4928 
4929  if (node_table_init(&f->id_table) == -1)
4930  goto out_free_name_table;
4931 
4932  fuse_mutex_init(&f->lock);
4933 
4934  root = alloc_node(f);
4935  if (root == NULL) {
4936  fprintf(stderr, "fuse: memory allocation failed\n");
4937  goto out_free_id_table;
4938  }
4939  if (lru_enabled(f)) {
4940  struct node_lru *lnode = node_lru(root);
4941  init_list_head(&lnode->lru);
4942  }
4943 
4944  strcpy(root->inline_name, "/");
4945  root->name = root->inline_name;
4946 
4947  if (f->conf.intr &&
4948  fuse_init_intr_signal(f->conf.intr_signal,
4949  &f->intr_installed) == -1)
4950  goto out_free_root;
4951 
4952  root->parent = NULL;
4953  root->nodeid = FUSE_ROOT_ID;
4954  inc_nlookup(root);
4955  hash_id(f, root);
4956 
4957  return f;
4958 
4959 out_free_root:
4960  free(root);
4961 out_free_id_table:
4962  free(f->id_table.array);
4963 out_free_name_table:
4964  free(f->name_table.array);
4965 out_free_session:
4966  fuse_session_destroy(f->se);
4967 out_free_fs:
4968  if (f->fs->m)
4969  fuse_put_module(f->fs->m);
4970  free(f->fs);
4971  free(f->conf.modules);
4972 out_delete_context_key:
4973  fuse_delete_context_key();
4974 out_free:
4975  free(f);
4976 out:
4977  return NULL;
4978 }
4979 
4980 /* Emulates 3.0-style fuse_new(), which processes --help */
4981 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
4982  size_t op_size, void *private_data);
4983 FUSE_SYMVER(".symver fuse_new_30,fuse_new@FUSE_3.0");
4984 struct fuse *fuse_new_30(struct fuse_args *args,
4985  const struct fuse_operations *op,
4986  size_t op_size, void *user_data)
4987 {
4988  struct fuse_config conf;
4989 
4990  memset(&conf, 0, sizeof(conf));
4991 
4992  const struct fuse_opt opts[] = {
4993  FUSE_LIB_OPT("-h", show_help, 1),
4994  FUSE_LIB_OPT("--help", show_help, 1),
4995  FUSE_OPT_END
4996  };
4997 
4998  if (fuse_opt_parse(args, &conf, opts,
4999  fuse_lib_opt_proc) == -1)
5000  return NULL;
5001 
5002  if (conf.show_help) {
5003  fuse_lib_help(args);
5004  return NULL;
5005  } else
5006  return fuse_new_31(args, op, op_size, user_data);
5007 }
5008 
5009 void fuse_destroy(struct fuse *f)
5010 {
5011  size_t i;
5012 
5013  if (f->conf.intr && f->intr_installed)
5014  fuse_restore_intr_signal(f->conf.intr_signal);
5015 
5016  if (f->fs) {
5017  fuse_create_context(f);
5018 
5019  for (i = 0; i < f->id_table.size; i++) {
5020  struct node *node;
5021 
5022  for (node = f->id_table.array[i]; node != NULL;
5023  node = node->id_next) {
5024  if (node->is_hidden) {
5025  char *path;
5026  if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
5027  fuse_fs_unlink(f->fs, path);
5028  free(path);
5029  }
5030  }
5031  }
5032  }
5033  }
5034  for (i = 0; i < f->id_table.size; i++) {
5035  struct node *node;
5036  struct node *next;
5037 
5038  for (node = f->id_table.array[i]; node != NULL; node = next) {
5039  next = node->id_next;
5040  free_node(f, node);
5041  f->id_table.use--;
5042  }
5043  }
5044  assert(list_empty(&f->partial_slabs));
5045  assert(list_empty(&f->full_slabs));
5046 
5047  while (fuse_modules) {
5048  fuse_put_module(fuse_modules);
5049  }
5050  free(f->id_table.array);
5051  free(f->name_table.array);
5052  pthread_mutex_destroy(&f->lock);
5053  fuse_session_destroy(f->se);
5054  free(f->conf.modules);
5055  free(f);
5056  fuse_delete_context_key();
5057 }
5058 
5059 int fuse_mount(struct fuse *f, const char *mountpoint) {
5060  return fuse_session_mount(fuse_get_session(f), mountpoint);
5061 }
5062 
5063 
5064 void fuse_unmount(struct fuse *f) {
5066 }
5067 
5068 int fuse_version(void)
5069 {
5070  return FUSE_VERSION;
5071 }
5072 
5073 const char *fuse_pkgversion(void)
5074 {
5075  return PACKAGE_VERSION;
5076 }
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
size_t off
Definition: fuse_common.h:710
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
unsigned capable
Definition: fuse_common.h:412
uint64_t fh
Definition: fuse_common.h:91
#define FUSE_CAP_EXPORT_SUPPORT
Definition: fuse_common.h:163
unsigned int writepage
Definition: fuse_common.h:53
void fuse_session_unmount(struct fuse_session *se)
unsigned int direct_io
Definition: fuse_common.h:56
int fuse_getgroups(int size, gid_t list[])
Definition: fuse.c:4568
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
Definition: fuse.c:4545
uint32_t poll_events
Definition: fuse_common.h:98
void fuse_stop_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4818
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
unsigned int max_idle_threads
Definition: fuse_common.h:122
mode_t umask
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
#define FUSE_ROOT_ID
Definition: fuse_lowlevel.h:43
int fuse_version(void)
Definition: fuse.c:5068
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5064
fuse_readdir_flags
Definition: fuse.h:42
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
int fuse_loop(struct fuse *f)
Definition: fuse.c:4517
struct stat attr
Definition: fuse_lowlevel.h:88
int fuse_req_interrupted(fuse_req_t req)
unsigned int keep_cache
Definition: fuse_common.h:63
int fuse_reply_poll(fuse_req_t req, unsigned revents)
Definition: fuse_lowlevel.h:59
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
const char * fuse_pkgversion(void)
Definition: fuse.c:5073
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
int fuse_reply_err(fuse_req_t req, int err)
uint64_t lock_owner
Definition: fuse_common.h:94
void fuse_session_reset(struct fuse_session *se)
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
int fuse_clean_cache(struct fuse *fuse)
Definition: fuse.c:4374
void * fuse_req_userdata(fuse_req_t req)
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4460
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
void fuse_reply_none(fuse_req_t req)
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:209
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:147
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
Definition: fuse.h:1236
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
void fuse_session_destroy(struct fuse_session *se)
void fuse_session_exit(struct fuse_session *se)
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
int fuse_reply_readlink(fuse_req_t req, const char *link)
int fuse_start_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4810
size_t idx
Definition: fuse_common.h:705
size_t count
Definition: fuse_common.h:700
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
enum fuse_buf_flags flags
Definition: fuse_common.h:664
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4762
unsigned int flush
Definition: fuse_common.h:68
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
void fuse_lowlevel_help(void)
int fuse_interrupted(void)
Definition: fuse.c:4577
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5009
#define FUSE_OPT_END
Definition: fuse_opt.h:104
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5059
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
int show_help
Definition: fuse.h:271
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4587
uint64_t generation
Definition: fuse_lowlevel.h:79
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
int fuse_session_exited(struct fuse_session *se)
int fuse_reply_xattr(fuse_req_t req, size_t count)
unsigned want
Definition: fuse_common.h:420
fuse_fill_dir_flags
Definition: fuse.h:54
void * mem
Definition: fuse_common.h:671
struct fuse_buf buf[1]
Definition: fuse_common.h:715
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:281
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
int fuse_reply_write(fuse_req_t req, size_t count)
size_t size
Definition: fuse_common.h:659
double entry_timeout
double attr_timeout
Definition: fuse_lowlevel.h:94
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:196
void * private_data
Definition: fuse.h:800
void(* init)(void *userdata, struct fuse_conn_info *conn)
void fuse_exit(struct fuse *f)
Definition: fuse.c:4553
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4558
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4652
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98