"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.2.6/doc/html/fuse_8c_source.html" (11 May 2018, 765142 Bytes) of package /linux/misc/fuse-3.2.6.tar.xz:


Caution: In this restricted "Fossies" environment the current HTML page may not be correctly presentated and may have some non-functional links. Alternatively you can here view or download the uninterpreted raw source code. A member file download can also be achieved by clicking within a package contents listing on the according byte size field.

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