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