"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.3.0/doc/html/fuse_8c_source.html" (6 Nov 2018, 776610 Bytes) of package /linux/misc/fuse-3.3.0.tar.xz:


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

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