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