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