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