libfuse
fuse.c
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of the high-level FUSE API on top of the low-level
6  API.
7 
8  This program can be distributed under the terms of the GNU LGPLv2.
9  See the file COPYING.LIB
10 */
11 
12 
13 /* For pthread_rwlock_t */
14 #define _GNU_SOURCE
15 
16 #include "config.h"
17 #include "fuse_i.h"
18 #include "fuse_lowlevel.h"
19 #include "fuse_opt.h"
20 #include "fuse_misc.h"
21 #include "fuse_kernel.h"
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stddef.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <time.h>
30 #include <fcntl.h>
31 #include <limits.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <dlfcn.h>
35 #include <assert.h>
36 #include <poll.h>
37 #include <sys/param.h>
38 #include <sys/uio.h>
39 #include <sys/time.h>
40 #include <sys/mman.h>
41 #include <sys/file.h>
42 
43 #define FUSE_NODE_SLAB 1
44 
45 #ifndef MAP_ANONYMOUS
46 #undef FUSE_NODE_SLAB
47 #endif
48 
49 #ifndef RENAME_EXCHANGE
50 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
51 #endif
52 
53 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
54 
55 #define FUSE_UNKNOWN_INO 0xffffffff
56 #define OFFSET_MAX 0x7fffffffffffffffLL
57 
58 #define NODE_TABLE_MIN_SIZE 8192
59 
60 struct fuse_fs {
61  struct fuse_operations op;
62  struct fuse_module *m;
63  void *user_data;
64  int debug;
65 };
66 
67 struct fusemod_so {
68  void *handle;
69  int ctr;
70 };
71 
72 struct lock_queue_element {
73  struct lock_queue_element *next;
74  pthread_cond_t cond;
75  fuse_ino_t nodeid1;
76  const char *name1;
77  char **path1;
78  struct node **wnode1;
79  fuse_ino_t nodeid2;
80  const char *name2;
81  char **path2;
82  struct node **wnode2;
83  int err;
84  bool first_locked : 1;
85  bool second_locked : 1;
86  bool done : 1;
87 };
88 
89 struct node_table {
90  struct node **array;
91  size_t use;
92  size_t size;
93  size_t split;
94 };
95 
96 #define container_of(ptr, type, member) ({ \
97  const typeof( ((type *)0)->member ) *__mptr = (ptr); \
98  (type *)( (char *)__mptr - offsetof(type,member) );})
99 
100 #define list_entry(ptr, type, member) \
101  container_of(ptr, type, member)
102 
103 struct list_head {
104  struct list_head *next;
105  struct list_head *prev;
106 };
107 
108 struct node_slab {
109  struct list_head list; /* must be the first member */
110  struct list_head freelist;
111  int used;
112 };
113 
114 struct fuse {
115  struct fuse_session *se;
116  struct node_table name_table;
117  struct node_table id_table;
118  struct list_head lru_table;
119  fuse_ino_t ctr;
120  unsigned int generation;
121  unsigned int hidectr;
122  pthread_mutex_t lock;
123  struct fuse_config conf;
124  int intr_installed;
125  struct fuse_fs *fs;
126  struct lock_queue_element *lockq;
127  int pagesize;
128  struct list_head partial_slabs;
129  struct list_head full_slabs;
130  pthread_t prune_thread;
131 };
132 
133 struct lock {
134  int type;
135  off_t start;
136  off_t end;
137  pid_t pid;
138  uint64_t owner;
139  struct lock *next;
140 };
141 
142 struct node {
143  struct node *name_next;
144  struct node *id_next;
145  fuse_ino_t nodeid;
146  unsigned int generation;
147  int refctr;
148  struct node *parent;
149  char *name;
150  uint64_t nlookup;
151  int open_count;
152  struct timespec stat_updated;
153  struct timespec mtime;
154  off_t size;
155  struct lock *locks;
156  unsigned int is_hidden : 1;
157  unsigned int cache_valid : 1;
158  int treelock;
159  char inline_name[32];
160 };
161 
162 #define TREELOCK_WRITE -1
163 #define TREELOCK_WAIT_OFFSET INT_MIN
164 
165 struct node_lru {
166  struct node node;
167  struct list_head lru;
168  struct timespec forget_time;
169 };
170 
171 struct fuse_direntry {
172  struct stat stat;
173  char *name;
174  struct fuse_direntry *next;
175 };
176 
177 struct fuse_dh {
178  pthread_mutex_t lock;
179  struct fuse *fuse;
180  fuse_req_t req;
181  char *contents;
182  struct fuse_direntry *first;
183  struct fuse_direntry **last;
184  unsigned len;
185  unsigned size;
186  unsigned needlen;
187  int filled;
188  uint64_t fh;
189  int error;
190  fuse_ino_t nodeid;
191 };
192 
193 struct fuse_context_i {
194  struct fuse_context ctx;
195  fuse_req_t req;
196 };
197 
198 /* Defined by FUSE_REGISTER_MODULE() in lib/modules/subdir.c and iconv.c. */
199 extern fuse_module_factory_t fuse_module_subdir_factory;
200 #ifdef HAVE_ICONV
201 extern fuse_module_factory_t fuse_module_iconv_factory;
202 #endif
203 
204 static pthread_key_t fuse_context_key;
205 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
206 static int fuse_context_ref;
207 static struct fuse_module *fuse_modules = NULL;
208 
209 static int fuse_register_module(const char *name,
210  fuse_module_factory_t factory,
211  struct fusemod_so *so)
212 {
213  struct fuse_module *mod;
214 
215  mod = calloc(1, sizeof(struct fuse_module));
216  if (!mod) {
217  fprintf(stderr, "fuse: failed to allocate module\n");
218  return -1;
219  }
220  mod->name = strdup(name);
221  if (!mod->name) {
222  fprintf(stderr, "fuse: failed to allocate module name\n");
223  free(mod);
224  return -1;
225  }
226  mod->factory = factory;
227  mod->ctr = 0;
228  mod->so = so;
229  if (mod->so)
230  mod->so->ctr++;
231  mod->next = fuse_modules;
232  fuse_modules = mod;
233 
234  return 0;
235 }
236 
237 static void fuse_unregister_module(struct fuse_module *m)
238 {
239  struct fuse_module **mp;
240  for (mp = &fuse_modules; *mp; mp = &(*mp)->next) {
241  if (*mp == m) {
242  *mp = (*mp)->next;
243  break;
244  }
245  }
246  free(m->name);
247  free(m);
248 }
249 
250 static int fuse_load_so_module(const char *module)
251 {
252  int ret = -1;
253  char *tmp;
254  struct fusemod_so *so;
255  fuse_module_factory_t factory;
256 
257  tmp = malloc(strlen(module) + 64);
258  if (!tmp) {
259  fprintf(stderr, "fuse: memory allocation failed\n");
260  return -1;
261  }
262  sprintf(tmp, "libfusemod_%s.so", module);
263  so = calloc(1, sizeof(struct fusemod_so));
264  if (!so) {
265  fprintf(stderr, "fuse: failed to allocate module so\n");
266  goto out;
267  }
268 
269  so->handle = dlopen(tmp, RTLD_NOW);
270  if (so->handle == NULL) {
271  fprintf(stderr, "fuse: dlopen(%s) failed: %s\n",
272  tmp, dlerror());
273  goto out_free_so;
274  }
275 
276  sprintf(tmp, "fuse_module_%s_factory", module);
277  *(void**)(&factory) = dlsym(so->handle, tmp);
278  if (factory == NULL) {
279  fprintf(stderr, "fuse: symbol <%s> not found in module: %s\n",
280  tmp, dlerror());
281  goto out_dlclose;
282  }
283  ret = fuse_register_module(module, factory, so);
284  if (ret)
285  goto out_dlclose;
286 
287 out:
288  free(tmp);
289  return ret;
290 
291 out_dlclose:
292  dlclose(so->handle);
293 out_free_so:
294  free(so);
295  goto out;
296 }
297 
298 static struct fuse_module *fuse_find_module(const char *module)
299 {
300  struct fuse_module *m;
301  for (m = fuse_modules; m; m = m->next) {
302  if (strcmp(module, m->name) == 0) {
303  m->ctr++;
304  break;
305  }
306  }
307  return m;
308 }
309 
310 static struct fuse_module *fuse_get_module(const char *module)
311 {
312  struct fuse_module *m;
313 
314  pthread_mutex_lock(&fuse_context_lock);
315  m = fuse_find_module(module);
316  if (!m) {
317  int err = fuse_load_so_module(module);
318  if (!err)
319  m = fuse_find_module(module);
320  }
321  pthread_mutex_unlock(&fuse_context_lock);
322  return m;
323 }
324 
325 static void fuse_put_module(struct fuse_module *m)
326 {
327  pthread_mutex_lock(&fuse_context_lock);
328  if (m->so)
329  assert(m->ctr > 0);
330  /* Builtin modules may already have m->ctr == 0 */
331  if (m->ctr > 0)
332  m->ctr--;
333  if (!m->ctr && m->so) {
334  struct fusemod_so *so = m->so;
335  assert(so->ctr > 0);
336  so->ctr--;
337  if (!so->ctr) {
338  struct fuse_module **mp;
339  for (mp = &fuse_modules; *mp;) {
340  if ((*mp)->so == so)
341  fuse_unregister_module(*mp);
342  else
343  mp = &(*mp)->next;
344  }
345  dlclose(so->handle);
346  free(so);
347  }
348  } else if (!m->ctr) {
349  fuse_unregister_module(m);
350  }
351  pthread_mutex_unlock(&fuse_context_lock);
352 }
353 
354 static void init_list_head(struct list_head *list)
355 {
356  list->next = list;
357  list->prev = list;
358 }
359 
360 static int list_empty(const struct list_head *head)
361 {
362  return head->next == head;
363 }
364 
365 static void list_add(struct list_head *new, struct list_head *prev,
366  struct list_head *next)
367 {
368  next->prev = new;
369  new->next = next;
370  new->prev = prev;
371  prev->next = new;
372 }
373 
374 static inline void list_add_head(struct list_head *new, struct list_head *head)
375 {
376  list_add(new, head, head->next);
377 }
378 
379 static inline void list_add_tail(struct list_head *new, struct list_head *head)
380 {
381  list_add(new, head->prev, head);
382 }
383 
384 static inline void list_del(struct list_head *entry)
385 {
386  struct list_head *prev = entry->prev;
387  struct list_head *next = entry->next;
388 
389  next->prev = prev;
390  prev->next = next;
391 }
392 
393 static inline int lru_enabled(struct fuse *f)
394 {
395  return f->conf.remember > 0;
396 }
397 
398 static struct node_lru *node_lru(struct node *node)
399 {
400  return (struct node_lru *) node;
401 }
402 
403 static size_t get_node_size(struct fuse *f)
404 {
405  if (lru_enabled(f))
406  return sizeof(struct node_lru);
407  else
408  return sizeof(struct node);
409 }
410 
411 #ifdef FUSE_NODE_SLAB
412 static struct node_slab *list_to_slab(struct list_head *head)
413 {
414  return (struct node_slab *) head;
415 }
416 
417 static struct node_slab *node_to_slab(struct fuse *f, struct node *node)
418 {
419  return (struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
420 }
421 
422 static int alloc_slab(struct fuse *f)
423 {
424  void *mem;
425  struct node_slab *slab;
426  char *start;
427  size_t num;
428  size_t i;
429  size_t node_size = get_node_size(f);
430 
431  mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
432  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
433 
434  if (mem == MAP_FAILED)
435  return -1;
436 
437  slab = mem;
438  init_list_head(&slab->freelist);
439  slab->used = 0;
440  num = (f->pagesize - sizeof(struct node_slab)) / node_size;
441 
442  start = (char *) mem + f->pagesize - num * node_size;
443  for (i = 0; i < num; i++) {
444  struct list_head *n;
445 
446  n = (struct list_head *) (start + i * node_size);
447  list_add_tail(n, &slab->freelist);
448  }
449  list_add_tail(&slab->list, &f->partial_slabs);
450 
451  return 0;
452 }
453 
454 static struct node *alloc_node(struct fuse *f)
455 {
456  struct node_slab *slab;
457  struct list_head *node;
458 
459  if (list_empty(&f->partial_slabs)) {
460  int res = alloc_slab(f);
461  if (res != 0)
462  return NULL;
463  }
464  slab = list_to_slab(f->partial_slabs.next);
465  slab->used++;
466  node = slab->freelist.next;
467  list_del(node);
468  if (list_empty(&slab->freelist)) {
469  list_del(&slab->list);
470  list_add_tail(&slab->list, &f->full_slabs);
471  }
472  memset(node, 0, sizeof(struct node));
473 
474  return (struct node *) node;
475 }
476 
477 static void free_slab(struct fuse *f, struct node_slab *slab)
478 {
479  int res;
480 
481  list_del(&slab->list);
482  res = munmap(slab, f->pagesize);
483  if (res == -1)
484  fprintf(stderr, "fuse warning: munmap(%p) failed\n", slab);
485 }
486 
487 static void free_node_mem(struct fuse *f, struct node *node)
488 {
489  struct node_slab *slab = node_to_slab(f, node);
490  struct list_head *n = (struct list_head *) node;
491 
492  slab->used--;
493  if (slab->used) {
494  if (list_empty(&slab->freelist)) {
495  list_del(&slab->list);
496  list_add_tail(&slab->list, &f->partial_slabs);
497  }
498  list_add_head(n, &slab->freelist);
499  } else {
500  free_slab(f, slab);
501  }
502 }
503 #else
504 static struct node *alloc_node(struct fuse *f)
505 {
506  return (struct node *) calloc(1, get_node_size(f));
507 }
508 
509 static void free_node_mem(struct fuse *f, struct node *node)
510 {
511  (void) f;
512  free(node);
513 }
514 #endif
515 
516 static size_t id_hash(struct fuse *f, fuse_ino_t ino)
517 {
518  uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
519  uint64_t oldhash = hash % (f->id_table.size / 2);
520 
521  if (oldhash >= f->id_table.split)
522  return oldhash;
523  else
524  return hash;
525 }
526 
527 static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
528 {
529  size_t hash = id_hash(f, nodeid);
530  struct node *node;
531 
532  for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
533  if (node->nodeid == nodeid)
534  return node;
535 
536  return NULL;
537 }
538 
539 static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
540 {
541  struct node *node = get_node_nocheck(f, nodeid);
542  if (!node) {
543  fprintf(stderr, "fuse internal error: node %llu not found\n",
544  (unsigned long long) nodeid);
545  abort();
546  }
547  return node;
548 }
549 
550 static void curr_time(struct timespec *now);
551 static double diff_timespec(const struct timespec *t1,
552  const struct timespec *t2);
553 
554 static void remove_node_lru(struct node *node)
555 {
556  struct node_lru *lnode = node_lru(node);
557  list_del(&lnode->lru);
558  init_list_head(&lnode->lru);
559 }
560 
561 static void set_forget_time(struct fuse *f, struct node *node)
562 {
563  struct node_lru *lnode = node_lru(node);
564 
565  list_del(&lnode->lru);
566  list_add_tail(&lnode->lru, &f->lru_table);
567  curr_time(&lnode->forget_time);
568 }
569 
570 static void free_node(struct fuse *f, struct node *node)
571 {
572  if (node->name != node->inline_name)
573  free(node->name);
574  free_node_mem(f, node);
575 }
576 
577 static void node_table_reduce(struct node_table *t)
578 {
579  size_t newsize = t->size / 2;
580  void *newarray;
581 
582  if (newsize < NODE_TABLE_MIN_SIZE)
583  return;
584 
585  newarray = realloc(t->array, sizeof(struct node *) * newsize);
586  if (newarray != NULL)
587  t->array = newarray;
588 
589  t->size = newsize;
590  t->split = t->size / 2;
591 }
592 
593 static void remerge_id(struct fuse *f)
594 {
595  struct node_table *t = &f->id_table;
596  int iter;
597 
598  if (t->split == 0)
599  node_table_reduce(t);
600 
601  for (iter = 8; t->split > 0 && iter; iter--) {
602  struct node **upper;
603 
604  t->split--;
605  upper = &t->array[t->split + t->size / 2];
606  if (*upper) {
607  struct node **nodep;
608 
609  for (nodep = &t->array[t->split]; *nodep;
610  nodep = &(*nodep)->id_next);
611 
612  *nodep = *upper;
613  *upper = NULL;
614  break;
615  }
616  }
617 }
618 
619 static void unhash_id(struct fuse *f, struct node *node)
620 {
621  struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
622 
623  for (; *nodep != NULL; nodep = &(*nodep)->id_next)
624  if (*nodep == node) {
625  *nodep = node->id_next;
626  f->id_table.use--;
627 
628  if(f->id_table.use < f->id_table.size / 4)
629  remerge_id(f);
630  return;
631  }
632 }
633 
634 static int node_table_resize(struct node_table *t)
635 {
636  size_t newsize = t->size * 2;
637  void *newarray;
638 
639  newarray = realloc(t->array, sizeof(struct node *) * newsize);
640  if (newarray == NULL)
641  return -1;
642 
643  t->array = newarray;
644  memset(t->array + t->size, 0, t->size * sizeof(struct node *));
645  t->size = newsize;
646  t->split = 0;
647 
648  return 0;
649 }
650 
651 static void rehash_id(struct fuse *f)
652 {
653  struct node_table *t = &f->id_table;
654  struct node **nodep;
655  struct node **next;
656  size_t hash;
657 
658  if (t->split == t->size / 2)
659  return;
660 
661  hash = t->split;
662  t->split++;
663  for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
664  struct node *node = *nodep;
665  size_t newhash = id_hash(f, node->nodeid);
666 
667  if (newhash != hash) {
668  next = nodep;
669  *nodep = node->id_next;
670  node->id_next = t->array[newhash];
671  t->array[newhash] = node;
672  } else {
673  next = &node->id_next;
674  }
675  }
676  if (t->split == t->size / 2)
677  node_table_resize(t);
678 }
679 
680 static void hash_id(struct fuse *f, struct node *node)
681 {
682  size_t hash = id_hash(f, node->nodeid);
683  node->id_next = f->id_table.array[hash];
684  f->id_table.array[hash] = node;
685  f->id_table.use++;
686 
687  if (f->id_table.use >= f->id_table.size / 2)
688  rehash_id(f);
689 }
690 
691 static size_t name_hash(struct fuse *f, fuse_ino_t parent,
692  const char *name)
693 {
694  uint64_t hash = parent;
695  uint64_t oldhash;
696 
697  for (; *name; name++)
698  hash = hash * 31 + (unsigned char) *name;
699 
700  hash %= f->name_table.size;
701  oldhash = hash % (f->name_table.size / 2);
702  if (oldhash >= f->name_table.split)
703  return oldhash;
704  else
705  return hash;
706 }
707 
708 static void unref_node(struct fuse *f, struct node *node);
709 
710 static void remerge_name(struct fuse *f)
711 {
712  struct node_table *t = &f->name_table;
713  int iter;
714 
715  if (t->split == 0)
716  node_table_reduce(t);
717 
718  for (iter = 8; t->split > 0 && iter; iter--) {
719  struct node **upper;
720 
721  t->split--;
722  upper = &t->array[t->split + t->size / 2];
723  if (*upper) {
724  struct node **nodep;
725 
726  for (nodep = &t->array[t->split]; *nodep;
727  nodep = &(*nodep)->name_next);
728 
729  *nodep = *upper;
730  *upper = NULL;
731  break;
732  }
733  }
734 }
735 
736 static void unhash_name(struct fuse *f, struct node *node)
737 {
738  if (node->name) {
739  size_t hash = name_hash(f, node->parent->nodeid, node->name);
740  struct node **nodep = &f->name_table.array[hash];
741 
742  for (; *nodep != NULL; nodep = &(*nodep)->name_next)
743  if (*nodep == node) {
744  *nodep = node->name_next;
745  node->name_next = NULL;
746  unref_node(f, node->parent);
747  if (node->name != node->inline_name)
748  free(node->name);
749  node->name = NULL;
750  node->parent = NULL;
751  f->name_table.use--;
752 
753  if (f->name_table.use < f->name_table.size / 4)
754  remerge_name(f);
755  return;
756  }
757  fprintf(stderr,
758  "fuse internal error: unable to unhash node: %llu\n",
759  (unsigned long long) node->nodeid);
760  abort();
761  }
762 }
763 
764 static void rehash_name(struct fuse *f)
765 {
766  struct node_table *t = &f->name_table;
767  struct node **nodep;
768  struct node **next;
769  size_t hash;
770 
771  if (t->split == t->size / 2)
772  return;
773 
774  hash = t->split;
775  t->split++;
776  for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
777  struct node *node = *nodep;
778  size_t newhash = name_hash(f, node->parent->nodeid, node->name);
779 
780  if (newhash != hash) {
781  next = nodep;
782  if (node->name != node-&gnoenline_name)
if (node-&i>
  • if (node-&i>
  • 9251 693
    678 }
    678 } 678 } 678 } 678 } 678 } 678) {
     070div cla cla = 0ash div> 678) {
     070div cla cla = 0ash div> 723  n> } }97mss="lineno"> 678a = hacla = 0ash div> }97mss="lineno"> 678a = hacla = 0ash struct node **nodep = &f->nam if (f->nameneno7;lru);
    if (f-&"l00752"> 752è/span> 
     me="l00686"> 87">le *t = &f->na class=pan> me="l00686"> 87">le *t = &f->na class=pan> me="l00686"> 87">le *t = &f->na class=pan> me="l00686"> 87">le *t = &f->na class=pan> me="l006860> 87"> 639  newarray = realloc(t->array, 689 689> 706 }