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