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