• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   FUSE: Filesystem in Userspace
3   Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4 
5   Implementation of the high-level FUSE API on top of the low-level
6   API.
7 
8   This program can be distributed under the terms of the GNU LGPLv2.
9   See the file COPYING.LIB
10 */
11 
12 #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 
3545 		if (!is_dot_or_dotdot(name)) {
3546 			res = do_lookup(f, dh->nodeid, name, &e);
3547 			if (res) {
3548 				dh->error = res;
3549 				return 1;
3550 			}
3551 		}
3552 	} else {
3553 		e.attr.st_ino = FUSE_UNKNOWN_INO;
3554 		if (statp) {
3555 			e.attr.st_mode = statp->st_mode;
3556 			if (f->conf.use_ino)
3557 				e.attr.st_ino = statp->st_ino;
3558 		}
3559 		if (!f->conf.use_ino && f->conf.readdir_ino) {
3560 			e.attr.st_ino = (ino_t)
3561 				lookup_nodeid(f, dh->nodeid, name);
3562 		}
3563 	}
3564 
3565 	if (off) {
3566 		size_t newlen;
3567 
3568 		if (dh->filled) {
3569 			dh->error = -EIO;
3570 			return 1;
3571 		}
3572 
3573 		if (dh->first) {
3574 			dh->error = -EIO;
3575 			return 1;
3576 		}
3577 		if (extend_contents(dh, dh->needlen) == -1)
3578 			return 1;
3579 
3580 		newlen = dh->len +
3581 			fuse_add_direntry_plus(dh->req, dh->contents + dh->len,
3582 					       dh->needlen - dh->len, name,
3583 					       &e, off);
3584 		if (newlen > dh->needlen)
3585 			return 1;
3586 		dh->len = newlen;
3587 	} else {
3588 		dh->filled = 1;
3589 
3590 		if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1)
3591 			return 1;
3592 	}
3593 
3594 	return 0;
3595 }
3596 
free_direntries(struct fuse_direntry * de)3597 static void free_direntries(struct fuse_direntry *de)
3598 {
3599 	while (de) {
3600 		struct fuse_direntry *next = de->next;
3601 		free(de->name);
3602 		free(de);
3603 		de = next;
3604 	}
3605 }
3606 
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)3607 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3608 			size_t size, off_t off, struct fuse_dh *dh,
3609 			struct fuse_file_info *fi,
3610 			enum fuse_readdir_flags flags)
3611 {
3612 	char *path;
3613 	int err;
3614 
3615 	if (f->fs->op.readdir)
3616 		err = get_path_nullok(f, ino, &path);
3617 	else
3618 		err = get_path(f, ino, &path);
3619 	if (!err) {
3620 		struct fuse_intr_data d;
3621 		fuse_fill_dir_t filler = fill_dir;
3622 
3623 		if (flags & FUSE_READDIR_PLUS)
3624 			filler = fill_dir_plus;
3625 
3626 		free_direntries(dh->first);
3627 		dh->first = NULL;
3628 		dh->last = &dh->first;
3629 		dh->len = 0;
3630 		dh->error = 0;
3631 		dh->needlen = size;
3632 		dh->filled = 0;
3633 		dh->req = req;
3634 		fuse_prepare_interrupt(f, req, &d);
3635 		err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3636 		fuse_finish_interrupt(f, req, &d);
3637 		dh->req = NULL;
3638 		if (!err)
3639 			err = dh->error;
3640 		if (err)
3641 			dh->filled = 0;
3642 		free_path(f, ino, path);
3643 	}
3644 	return err;
3645 }
3646 
readdir_fill_from_list(fuse_req_t req,struct fuse_dh * dh,off_t off,enum fuse_readdir_flags flags)3647 static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh,
3648 				  off_t off, enum fuse_readdir_flags flags)
3649 {
3650 	off_t pos;
3651 	struct fuse_direntry *de = dh->first;
3652 
3653 	dh->len = 0;
3654 
3655 	if (extend_contents(dh, dh->needlen) == -1)
3656 		return dh->error;
3657 
3658 	for (pos = 0; pos < off; pos++) {
3659 		if (!de)
3660 			break;
3661 
3662 		de = de->next;
3663 	}
3664 	while (de) {
3665 		char *p = dh->contents + dh->len;
3666 		unsigned rem = dh->needlen - dh->len;
3667 		unsigned thislen;
3668 		unsigned newlen;
3669 		pos++;
3670 
3671 		if (flags & FUSE_READDIR_PLUS) {
3672 			struct fuse_entry_param e = {
3673 				.ino = 0,
3674 				.attr = de->stat,
3675 			};
3676 			thislen = fuse_add_direntry_plus(req, p, rem,
3677 							 de->name, &e, pos);
3678 		} else {
3679 			thislen = fuse_add_direntry(req, p, rem,
3680 						    de->name, &de->stat, pos);
3681 		}
3682 		newlen = dh->len + thislen;
3683 		if (newlen > dh->needlen)
3684 			break;
3685 		dh->len = newlen;
3686 		de = de->next;
3687 	}
3688 	return 0;
3689 }
3690 
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)3691 static void fuse_readdir_common(fuse_req_t req, fuse_ino_t ino, size_t size,
3692 				off_t off, struct fuse_file_info *llfi,
3693 				enum fuse_readdir_flags flags)
3694 {
3695 	struct fuse *f = req_fuse_prepare(req);
3696 	struct fuse_file_info fi;
3697 	struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3698 	int err;
3699 
3700 	pthread_mutex_lock(&dh->lock);
3701 	/* According to SUS, directory contents need to be refreshed on
3702 	   rewinddir() */
3703 	if (!off)
3704 		dh->filled = 0;
3705 
3706 	if (!dh->filled) {
3707 		err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3708 		if (err) {
3709 			reply_err(req, err);
3710 			goto out;
3711 		}
3712 	}
3713 	if (dh->filled) {
3714 		dh->needlen = size;
3715 		err = readdir_fill_from_list(req, dh, off, flags);
3716 		if (err) {
3717 			reply_err(req, err);
3718 			goto out;
3719 		}
3720 	}
3721 	fuse_reply_buf(req, dh->contents, dh->len);
3722 out:
3723 	pthread_mutex_unlock(&dh->lock);
3724 }
3725 
fuse_lib_readdir(fuse_req_t req,fuse_ino_t ino,size_t size,off_t off,struct fuse_file_info * llfi)3726 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3727 			     off_t off, struct fuse_file_info *llfi)
3728 {
3729 	fuse_readdir_common(req, ino, size, off, llfi, 0);
3730 }
3731 
fuse_lib_readdirplus(fuse_req_t req,fuse_ino_t ino,size_t size,off_t off,struct fuse_file_info * llfi)3732 static void fuse_lib_readdirplus(fuse_req_t req, fuse_ino_t ino, size_t size,
3733 				  off_t off, struct fuse_file_info *llfi)
3734 {
3735 	fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3736 }
3737 
fuse_lib_releasedir(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * llfi)3738 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3739 				struct fuse_file_info *llfi)
3740 {
3741 	struct fuse *f = req_fuse_prepare(req);
3742 	struct fuse_intr_data d;
3743 	struct fuse_file_info fi;
3744 	struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3745 	char *path;
3746 
3747 	get_path_nullok(f, ino, &path);
3748 
3749 	fuse_prepare_interrupt(f, req, &d);
3750 	fuse_fs_releasedir(f->fs, path, &fi);
3751 	fuse_finish_interrupt(f, req, &d);
3752 	free_path(f, ino, path);
3753 
3754 	pthread_mutex_lock(&dh->lock);
3755 	pthread_mutex_unlock(&dh->lock);
3756 	pthread_mutex_destroy(&dh->lock);
3757 	free_direntries(dh->first);
3758 	free(dh->contents);
3759 	free(dh);
3760 	reply_err(req, 0);
3761 }
3762 
fuse_lib_fsyncdir(fuse_req_t req,fuse_ino_t ino,int datasync,struct fuse_file_info * llfi)3763 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3764 			      struct fuse_file_info *llfi)
3765 {
3766 	struct fuse *f = req_fuse_prepare(req);
3767 	struct fuse_file_info fi;
3768 	char *path;
3769 	int err;
3770 
3771 	get_dirhandle(llfi, &fi);
3772 
3773 	err = get_path_nullok(f, ino, &path);
3774 	if (!err) {
3775 		struct fuse_intr_data d;
3776 		fuse_prepare_interrupt(f, req, &d);
3777 		err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3778 		fuse_finish_interrupt(f, req, &d);
3779 		free_path(f, ino, path);
3780 	}
3781 	reply_err(req, err);
3782 }
3783 
fuse_lib_statfs(fuse_req_t req,fuse_ino_t ino)3784 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3785 {
3786 	struct fuse *f = req_fuse_prepare(req);
3787 	struct statvfs buf;
3788 	char *path = NULL;
3789 	int err = 0;
3790 
3791 	memset(&buf, 0, sizeof(buf));
3792 	if (ino)
3793 		err = get_path(f, ino, &path);
3794 
3795 	if (!err) {
3796 		struct fuse_intr_data d;
3797 		fuse_prepare_interrupt(f, req, &d);
3798 		err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3799 		fuse_finish_interrupt(f, req, &d);
3800 		free_path(f, ino, path);
3801 	}
3802 
3803 	if (!err)
3804 		fuse_reply_statfs(req, &buf);
3805 	else
3806 		reply_err(req, err);
3807 }
3808 
fuse_lib_setxattr(fuse_req_t req,fuse_ino_t ino,const char * name,const char * value,size_t size,int flags)3809 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3810 			      const char *value, size_t size, int flags)
3811 {
3812 	struct fuse *f = req_fuse_prepare(req);
3813 	char *path;
3814 	int err;
3815 
3816 	err = get_path(f, ino, &path);
3817 	if (!err) {
3818 		struct fuse_intr_data d;
3819 		fuse_prepare_interrupt(f, req, &d);
3820 		err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3821 		fuse_finish_interrupt(f, req, &d);
3822 		free_path(f, ino, path);
3823 	}
3824 	reply_err(req, err);
3825 }
3826 
common_getxattr(struct fuse * f,fuse_req_t req,fuse_ino_t ino,const char * name,char * value,size_t size)3827 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3828 			   const char *name, char *value, size_t size)
3829 {
3830 	int err;
3831 	char *path;
3832 
3833 	err = get_path(f, ino, &path);
3834 	if (!err) {
3835 		struct fuse_intr_data d;
3836 		fuse_prepare_interrupt(f, req, &d);
3837 		err = fuse_fs_getxattr(f->fs, path, name, value, size);
3838 		fuse_finish_interrupt(f, req, &d);
3839 		free_path(f, ino, path);
3840 	}
3841 	return err;
3842 }
3843 
fuse_lib_getxattr(fuse_req_t req,fuse_ino_t ino,const char * name,size_t size)3844 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3845 			      size_t size)
3846 {
3847 	struct fuse *f = req_fuse_prepare(req);
3848 	int res;
3849 
3850 	if (size) {
3851 		char *value = (char *) malloc(size);
3852 		if (value == NULL) {
3853 			reply_err(req, -ENOMEM);
3854 			return;
3855 		}
3856 		res = common_getxattr(f, req, ino, name, value, size);
3857 		if (res > 0)
3858 			fuse_reply_buf(req, value, res);
3859 		else
3860 			reply_err(req, res);
3861 		free(value);
3862 	} else {
3863 		res = common_getxattr(f, req, ino, name, NULL, 0);
3864 		if (res >= 0)
3865 			fuse_reply_xattr(req, res);
3866 		else
3867 			reply_err(req, res);
3868 	}
3869 }
3870 
common_listxattr(struct fuse * f,fuse_req_t req,fuse_ino_t ino,char * list,size_t size)3871 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3872 			    char *list, size_t size)
3873 {
3874 	char *path;
3875 	int err;
3876 
3877 	err = get_path(f, ino, &path);
3878 	if (!err) {
3879 		struct fuse_intr_data d;
3880 		fuse_prepare_interrupt(f, req, &d);
3881 		err = fuse_fs_listxattr(f->fs, path, list, size);
3882 		fuse_finish_interrupt(f, req, &d);
3883 		free_path(f, ino, path);
3884 	}
3885 	return err;
3886 }
3887 
fuse_lib_listxattr(fuse_req_t req,fuse_ino_t ino,size_t size)3888 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3889 {
3890 	struct fuse *f = req_fuse_prepare(req);
3891 	int res;
3892 
3893 	if (size) {
3894 		char *list = (char *) malloc(size);
3895 		if (list == NULL) {
3896 			reply_err(req, -ENOMEM);
3897 			return;
3898 		}
3899 		res = common_listxattr(f, req, ino, list, size);
3900 		if (res > 0)
3901 			fuse_reply_buf(req, list, res);
3902 		else
3903 			reply_err(req, res);
3904 		free(list);
3905 	} else {
3906 		res = common_listxattr(f, req, ino, NULL, 0);
3907 		if (res >= 0)
3908 			fuse_reply_xattr(req, res);
3909 		else
3910 			reply_err(req, res);
3911 	}
3912 }
3913 
fuse_lib_removexattr(fuse_req_t req,fuse_ino_t ino,const char * name)3914 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3915 				 const char *name)
3916 {
3917 	struct fuse *f = req_fuse_prepare(req);
3918 	char *path;
3919 	int err;
3920 
3921 	err = get_path(f, ino, &path);
3922 	if (!err) {
3923 		struct fuse_intr_data d;
3924 		fuse_prepare_interrupt(f, req, &d);
3925 		err = fuse_fs_removexattr(f->fs, path, name);
3926 		fuse_finish_interrupt(f, req, &d);
3927 		free_path(f, ino, path);
3928 	}
3929 	reply_err(req, err);
3930 }
3931 
locks_conflict(struct node * node,const struct lock * lock)3932 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3933 {
3934 	struct lock *l;
3935 
3936 	for (l = node->locks; l; l = l->next)
3937 		if (l->owner != lock->owner &&
3938 		    lock->start <= l->end && l->start <= lock->end &&
3939 		    (l->type == F_WRLCK || lock->type == F_WRLCK))
3940 			break;
3941 
3942 	return l;
3943 }
3944 
delete_lock(struct lock ** lockp)3945 static void delete_lock(struct lock **lockp)
3946 {
3947 	struct lock *l = *lockp;
3948 	*lockp = l->next;
3949 	free(l);
3950 }
3951 
insert_lock(struct lock ** pos,struct lock * lock)3952 static void insert_lock(struct lock **pos, struct lock *lock)
3953 {
3954 	lock->next = *pos;
3955 	*pos = lock;
3956 }
3957 
locks_insert(struct node * node,struct lock * lock)3958 static int locks_insert(struct node *node, struct lock *lock)
3959 {
3960 	struct lock **lp;
3961 	struct lock *newl1 = NULL;
3962 	struct lock *newl2 = NULL;
3963 
3964 	if (lock->type != F_UNLCK || lock->start != 0 ||
3965 	    lock->end != OFFSET_MAX) {
3966 		newl1 = malloc(sizeof(struct lock));
3967 		newl2 = malloc(sizeof(struct lock));
3968 
3969 		if (!newl1 || !newl2) {
3970 			free(newl1);
3971 			free(newl2);
3972 			return -ENOLCK;
3973 		}
3974 	}
3975 
3976 	for (lp = &node->locks; *lp;) {
3977 		struct lock *l = *lp;
3978 		if (l->owner != lock->owner)
3979 			goto skip;
3980 
3981 		if (lock->type == l->type) {
3982 			if (l->end < lock->start - 1)
3983 				goto skip;
3984 			if (lock->end < l->start - 1)
3985 				break;
3986 			if (l->start <= lock->start && lock->end <= l->end)
3987 				goto out;
3988 			if (l->start < lock->start)
3989 				lock->start = l->start;
3990 			if (lock->end < l->end)
3991 				lock->end = l->end;
3992 			goto delete;
3993 		} else {
3994 			if (l->end < lock->start)
3995 				goto skip;
3996 			if (lock->end < l->start)
3997 				break;
3998 			if (lock->start <= l->start && l->end <= lock->end)
3999 				goto delete;
4000 			if (l->end <= lock->end) {
4001 				l->end = lock->start - 1;
4002 				goto skip;
4003 			}
4004 			if (lock->start <= l->start) {
4005 				l->start = lock->end + 1;
4006 				break;
4007 			}
4008 			*newl2 = *l;
4009 			newl2->start = lock->end + 1;
4010 			l->end = lock->start - 1;
4011 			insert_lock(&l->next, newl2);
4012 			newl2 = NULL;
4013 		}
4014 	skip:
4015 		lp = &l->next;
4016 		continue;
4017 
4018 	delete:
4019 		delete_lock(lp);
4020 	}
4021 	if (lock->type != F_UNLCK) {
4022 		*newl1 = *lock;
4023 		insert_lock(lp, newl1);
4024 		newl1 = NULL;
4025 	}
4026 out:
4027 	free(newl1);
4028 	free(newl2);
4029 	return 0;
4030 }
4031 
flock_to_lock(struct flock * flock,struct lock * lock)4032 static void flock_to_lock(struct flock *flock, struct lock *lock)
4033 {
4034 	memset(lock, 0, sizeof(struct lock));
4035 	lock->type = flock->l_type;
4036 	lock->start = flock->l_start;
4037 	lock->end =
4038 		flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4039 	lock->pid = flock->l_pid;
4040 }
4041 
lock_to_flock(struct lock * lock,struct flock * flock)4042 static void lock_to_flock(struct lock *lock, struct flock *flock)
4043 {
4044 	flock->l_type = lock->type;
4045 	flock->l_start = lock->start;
4046 	flock->l_len =
4047 		(lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4048 	flock->l_pid = lock->pid;
4049 }
4050 
fuse_flush_common(struct fuse * f,fuse_req_t req,fuse_ino_t ino,const char * path,struct fuse_file_info * fi)4051 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
4052 			     const char *path, struct fuse_file_info *fi)
4053 {
4054 	struct fuse_intr_data d;
4055 	struct flock lock;
4056 	struct lock l;
4057 	int err;
4058 	int errlock;
4059 
4060 	fuse_prepare_interrupt(f, req, &d);
4061 	memset(&lock, 0, sizeof(lock));
4062 	lock.l_type = F_UNLCK;
4063 	lock.l_whence = SEEK_SET;
4064 	err = fuse_fs_flush(f->fs, path, fi);
4065 	errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4066 	fuse_finish_interrupt(f, req, &d);
4067 
4068 	if (errlock != -ENOSYS) {
4069 		flock_to_lock(&lock, &l);
4070 		l.owner = fi->lock_owner;
4071 		pthread_mutex_lock(&f->lock);
4072 		locks_insert(get_node(f, ino), &l);
4073 		pthread_mutex_unlock(&f->lock);
4074 
4075 		/* if op.lock() is defined FLUSH is needed regardless
4076 		   of op.flush() */
4077 		if (err == -ENOSYS)
4078 			err = 0;
4079 	}
4080 	return err;
4081 }
4082 
fuse_lib_release(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)4083 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
4084 			     struct fuse_file_info *fi)
4085 {
4086 	struct fuse *f = req_fuse_prepare(req);
4087 	struct fuse_intr_data d;
4088 	char *path;
4089 	int err = 0;
4090 
4091 	get_path_nullok(f, ino, &path);
4092 	if (fi->flush) {
4093 		err = fuse_flush_common(f, req, ino, path, fi);
4094 		if (err == -ENOSYS)
4095 			err = 0;
4096 	}
4097 
4098 	fuse_prepare_interrupt(f, req, &d);
4099 	fuse_do_release(f, ino, path, fi);
4100 	fuse_finish_interrupt(f, req, &d);
4101 	free_path(f, ino, path);
4102 
4103 	reply_err(req, err);
4104 }
4105 
fuse_lib_flush(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)4106 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
4107 			   struct fuse_file_info *fi)
4108 {
4109 	struct fuse *f = req_fuse_prepare(req);
4110 	char *path;
4111 	int err;
4112 
4113 	get_path_nullok(f, ino, &path);
4114 	err = fuse_flush_common(f, req, ino, path, fi);
4115 	free_path(f, ino, path);
4116 
4117 	reply_err(req, err);
4118 }
4119 
fuse_lock_common(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi,struct flock * lock,int cmd)4120 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
4121 			    struct fuse_file_info *fi, struct flock *lock,
4122 			    int cmd)
4123 {
4124 	struct fuse *f = req_fuse_prepare(req);
4125 	char *path;
4126 	int err;
4127 
4128 	err = get_path_nullok(f, ino, &path);
4129 	if (!err) {
4130 		struct fuse_intr_data d;
4131 		fuse_prepare_interrupt(f, req, &d);
4132 		err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4133 		fuse_finish_interrupt(f, req, &d);
4134 		free_path(f, ino, path);
4135 	}
4136 	return err;
4137 }
4138 
fuse_lib_getlk(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi,struct flock * lock)4139 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
4140 			   struct fuse_file_info *fi, struct flock *lock)
4141 {
4142 	int err;
4143 	struct lock l;
4144 	struct lock *conflict;
4145 	struct fuse *f = req_fuse(req);
4146 
4147 	flock_to_lock(lock, &l);
4148 	l.owner = fi->lock_owner;
4149 	pthread_mutex_lock(&f->lock);
4150 	conflict = locks_conflict(get_node(f, ino), &l);
4151 	if (conflict)
4152 		lock_to_flock(conflict, lock);
4153 	pthread_mutex_unlock(&f->lock);
4154 	if (!conflict)
4155 		err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4156 	else
4157 		err = 0;
4158 
4159 	if (!err)
4160 		fuse_reply_lock(req, lock);
4161 	else
4162 		reply_err(req, err);
4163 }
4164 
fuse_lib_setlk(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi,struct flock * lock,int sleep)4165 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
4166 			   struct fuse_file_info *fi, struct flock *lock,
4167 			   int sleep)
4168 {
4169 	int err = fuse_lock_common(req, ino, fi, lock,
4170 				   sleep ? F_SETLKW : F_SETLK);
4171 	if (!err) {
4172 		struct fuse *f = req_fuse(req);
4173 		struct lock l;
4174 		flock_to_lock(lock, &l);
4175 		l.owner = fi->lock_owner;
4176 		pthread_mutex_lock(&f->lock);
4177 		locks_insert(get_node(f, ino), &l);
4178 		pthread_mutex_unlock(&f->lock);
4179 	}
4180 	reply_err(req, err);
4181 }
4182 
fuse_lib_flock(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi,int op)4183 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
4184 			   struct fuse_file_info *fi, int op)
4185 {
4186 	struct fuse *f = req_fuse_prepare(req);
4187 	char *path;
4188 	int err;
4189 
4190 	err = get_path_nullok(f, ino, &path);
4191 	if (err == 0) {
4192 		struct fuse_intr_data d;
4193 		fuse_prepare_interrupt(f, req, &d);
4194 		err = fuse_fs_flock(f->fs, path, fi, op);
4195 		fuse_finish_interrupt(f, req, &d);
4196 		free_path(f, ino, path);
4197 	}
4198 	reply_err(req, err);
4199 }
4200 
fuse_lib_bmap(fuse_req_t req,fuse_ino_t ino,size_t blocksize,uint64_t idx)4201 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
4202 			  uint64_t idx)
4203 {
4204 	struct fuse *f = req_fuse_prepare(req);
4205 	struct fuse_intr_data d;
4206 	char *path;
4207 	int err;
4208 
4209 	err = get_path(f, ino, &path);
4210 	if (!err) {
4211 		fuse_prepare_interrupt(f, req, &d);
4212 		err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4213 		fuse_finish_interrupt(f, req, &d);
4214 		free_path(f, ino, path);
4215 	}
4216 	if (!err)
4217 		fuse_reply_bmap(req, idx);
4218 	else
4219 		reply_err(req, err);
4220 }
4221 
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)4222 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, unsigned int cmd,
4223 			   void *arg, struct fuse_file_info *llfi,
4224 			   unsigned int flags, const void *in_buf,
4225 			   size_t in_bufsz, size_t out_bufsz)
4226 {
4227 	struct fuse *f = req_fuse_prepare(req);
4228 	struct fuse_intr_data d;
4229 	struct fuse_file_info fi;
4230 	char *path, *out_buf = NULL;
4231 	int err;
4232 
4233 	err = -EPERM;
4234 	if (flags & FUSE_IOCTL_UNRESTRICTED)
4235 		goto err;
4236 
4237 	if (flags & FUSE_IOCTL_DIR)
4238 		get_dirhandle(llfi, &fi);
4239 	else
4240 		fi = *llfi;
4241 
4242 	if (out_bufsz) {
4243 		err = -ENOMEM;
4244 		out_buf = malloc(out_bufsz);
4245 		if (!out_buf)
4246 			goto err;
4247 	}
4248 
4249 	assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4250 	if (out_buf && in_bufsz)
4251 		memcpy(out_buf, in_buf, in_bufsz);
4252 
4253 	err = get_path_nullok(f, ino, &path);
4254 	if (err)
4255 		goto err;
4256 
4257 	fuse_prepare_interrupt(f, req, &d);
4258 
4259 	err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4260 			    out_buf ? out_buf : (void *)in_buf);
4261 
4262 	fuse_finish_interrupt(f, req, &d);
4263 	free_path(f, ino, path);
4264 
4265 	if (err < 0)
4266 		goto err;
4267 	fuse_reply_ioctl(req, err, out_buf, out_bufsz);
4268 	goto out;
4269 err:
4270 	reply_err(req, err);
4271 out:
4272 	free(out_buf);
4273 }
4274 
fuse_lib_poll(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi,struct fuse_pollhandle * ph)4275 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
4276 			  struct fuse_file_info *fi, struct fuse_pollhandle *ph)
4277 {
4278 	struct fuse *f = req_fuse_prepare(req);
4279 	struct fuse_intr_data d;
4280 	char *path;
4281 	int err;
4282 	unsigned revents = 0;
4283 
4284 	err = get_path_nullok(f, ino, &path);
4285 	if (!err) {
4286 		fuse_prepare_interrupt(f, req, &d);
4287 		err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4288 		fuse_finish_interrupt(f, req, &d);
4289 		free_path(f, ino, path);
4290 	}
4291 	if (!err)
4292 		fuse_reply_poll(req, revents);
4293 	else
4294 		reply_err(req, err);
4295 }
4296 
fuse_lib_fallocate(fuse_req_t req,fuse_ino_t ino,int mode,off_t offset,off_t length,struct fuse_file_info * fi)4297 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
4298 		off_t offset, off_t length, struct fuse_file_info *fi)
4299 {
4300 	struct fuse *f = req_fuse_prepare(req);
4301 	struct fuse_intr_data d;
4302 	char *path;
4303 	int err;
4304 
4305 	err = get_path_nullok(f, ino, &path);
4306 	if (!err) {
4307 		fuse_prepare_interrupt(f, req, &d);
4308 		err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4309 		fuse_finish_interrupt(f, req, &d);
4310 		free_path(f, ino, path);
4311 	}
4312 	reply_err(req, err);
4313 }
4314 
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)4315 static void fuse_lib_copy_file_range(fuse_req_t req, fuse_ino_t nodeid_in,
4316 				     off_t off_in, struct fuse_file_info *fi_in,
4317 				     fuse_ino_t nodeid_out, off_t off_out,
4318 				     struct fuse_file_info *fi_out, size_t len,
4319 				     int flags)
4320 {
4321 	struct fuse *f = req_fuse_prepare(req);
4322 	struct fuse_intr_data d;
4323 	char *path_in, *path_out;
4324 	int err;
4325 	ssize_t res;
4326 
4327 	err = get_path_nullok(f, nodeid_in, &path_in);
4328 	if (err) {
4329 		reply_err(req, err);
4330 		return;
4331 	}
4332 
4333 	err = get_path_nullok(f, nodeid_out, &path_out);
4334 	if (err) {
4335 		free_path(f, nodeid_in, path_in);
4336 		reply_err(req, err);
4337 		return;
4338 	}
4339 
4340 	fuse_prepare_interrupt(f, req, &d);
4341 	res = fuse_fs_copy_file_range(f->fs, path_in, fi_in, off_in, path_out,
4342 				      fi_out, off_out, len, flags);
4343 	fuse_finish_interrupt(f, req, &d);
4344 
4345 	if (res >= 0)
4346 		fuse_reply_write(req, res);
4347 	else
4348 		reply_err(req, res);
4349 
4350 	free_path(f, nodeid_in, path_in);
4351 	free_path(f, nodeid_out, path_out);
4352 }
4353 
fuse_lib_lseek(fuse_req_t req,fuse_ino_t ino,off_t off,int whence,struct fuse_file_info * fi)4354 static void fuse_lib_lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
4355 			   struct fuse_file_info *fi)
4356 {
4357 	struct fuse *f = req_fuse_prepare(req);
4358 	struct fuse_intr_data d;
4359 	char *path;
4360 	int err;
4361 	off_t res;
4362 
4363 	err = get_path(f, ino, &path);
4364 	if (err) {
4365 		reply_err(req, err);
4366 		return;
4367 	}
4368 
4369 	fuse_prepare_interrupt(f, req, &d);
4370 	res = fuse_fs_lseek(f->fs, path, off, whence, fi);
4371 	fuse_finish_interrupt(f, req, &d);
4372 	free_path(f, ino, path);
4373 	if (res >= 0)
4374 		fuse_reply_lseek(req, res);
4375 	else
4376 		reply_err(req, res);
4377 }
4378 
clean_delay(struct fuse * f)4379 static int clean_delay(struct fuse *f)
4380 {
4381 	/*
4382 	 * This is calculating the delay between clean runs.  To
4383 	 * reduce the number of cleans we are doing them 10 times
4384 	 * within the remember window.
4385 	 */
4386 	int min_sleep = 60;
4387 	int max_sleep = 3600;
4388 	int sleep_time = f->conf.remember / 10;
4389 
4390 	if (sleep_time > max_sleep)
4391 		return max_sleep;
4392 	if (sleep_time < min_sleep)
4393 		return min_sleep;
4394 	return sleep_time;
4395 }
4396 
fuse_clean_cache(struct fuse * f)4397 int fuse_clean_cache(struct fuse *f)
4398 {
4399 	struct node_lru *lnode;
4400 	struct list_head *curr, *next;
4401 	struct node *node;
4402 	struct timespec now;
4403 
4404 	pthread_mutex_lock(&f->lock);
4405 
4406 	curr_time(&now);
4407 
4408 	for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4409 		double age;
4410 
4411 		next = curr->next;
4412 		lnode = list_entry(curr, struct node_lru, lru);
4413 		node = &lnode->node;
4414 
4415 		age = diff_timespec(&now, &lnode->forget_time);
4416 		if (age <= f->conf.remember)
4417 			break;
4418 
4419 		assert(node->nlookup == 1);
4420 
4421 		/* Don't forget active directories */
4422 		if (node->refctr > 1)
4423 			continue;
4424 
4425 		node->nlookup = 0;
4426 		unhash_name(f, node);
4427 		unref_node(f, node);
4428 	}
4429 	pthread_mutex_unlock(&f->lock);
4430 
4431 	return clean_delay(f);
4432 }
4433 
4434 static struct fuse_lowlevel_ops fuse_path_ops = {
4435 	.init = fuse_lib_init,
4436 	.destroy = fuse_lib_destroy,
4437 	.lookup = fuse_lib_lookup,
4438 	.forget = fuse_lib_forget,
4439 	.forget_multi = fuse_lib_forget_multi,
4440 	.getattr = fuse_lib_getattr,
4441 	.setattr = fuse_lib_setattr,
4442 	.access = fuse_lib_access,
4443 	.readlink = fuse_lib_readlink,
4444 	.mknod = fuse_lib_mknod,
4445 	.mkdir = fuse_lib_mkdir,
4446 	.unlink = fuse_lib_unlink,
4447 	.rmdir = fuse_lib_rmdir,
4448 	.symlink = fuse_lib_symlink,
4449 	.rename = fuse_lib_rename,
4450 	.link = fuse_lib_link,
4451 	.create = fuse_lib_create,
4452 	.open = fuse_lib_open,
4453 	.read = fuse_lib_read,
4454 	.write_buf = fuse_lib_write_buf,
4455 	.flush = fuse_lib_flush,
4456 	.release = fuse_lib_release,
4457 	.fsync = fuse_lib_fsync,
4458 	.opendir = fuse_lib_opendir,
4459 	.readdir = fuse_lib_readdir,
4460 	.readdirplus = fuse_lib_readdirplus,
4461 	.releasedir = fuse_lib_releasedir,
4462 	.fsyncdir = fuse_lib_fsyncdir,
4463 	.statfs = fuse_lib_statfs,
4464 	.setxattr = fuse_lib_setxattr,
4465 	.getxattr = fuse_lib_getxattr,
4466 	.listxattr = fuse_lib_listxattr,
4467 	.removexattr = fuse_lib_removexattr,
4468 	.getlk = fuse_lib_getlk,
4469 	.setlk = fuse_lib_setlk,
4470 	.flock = fuse_lib_flock,
4471 	.bmap = fuse_lib_bmap,
4472 	.ioctl = fuse_lib_ioctl,
4473 	.poll = fuse_lib_poll,
4474 	.fallocate = fuse_lib_fallocate,
4475 	.copy_file_range = fuse_lib_copy_file_range,
4476 	.lseek = fuse_lib_lseek,
4477 };
4478 
fuse_notify_poll(struct fuse_pollhandle * ph)4479 int fuse_notify_poll(struct fuse_pollhandle *ph)
4480 {
4481 	return fuse_lowlevel_notify_poll(ph);
4482 }
4483 
fuse_get_session(struct fuse * f)4484 struct fuse_session *fuse_get_session(struct fuse *f)
4485 {
4486 	return f->se;
4487 }
4488 
fuse_session_loop_remember(struct fuse * f)4489 static int fuse_session_loop_remember(struct fuse *f)
4490 {
4491 	struct fuse_session *se = f->se;
4492 	int res = 0;
4493 	struct timespec now;
4494 	time_t next_clean;
4495 	struct pollfd fds = {
4496 		.fd = se->fd,
4497 		.events = POLLIN
4498 	};
4499 	struct fuse_buf fbuf = {
4500 		.mem = NULL,
4501 	};
4502 
4503 	curr_time(&now);
4504 	next_clean = now.tv_sec;
4505 	while (!fuse_session_exited(se)) {
4506 		unsigned timeout;
4507 
4508 		curr_time(&now);
4509 		if (now.tv_sec < next_clean)
4510 			timeout = next_clean - now.tv_sec;
4511 		else
4512 			timeout = 0;
4513 
4514 		res = poll(&fds, 1, timeout * 1000);
4515 		if (res == -1) {
4516 			if (errno == EINTR)
4517 				continue;
4518 			else
4519 				break;
4520 		} else if (res > 0) {
4521 			res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4522 
4523 			if (res == -EINTR)
4524 				continue;
4525 			if (res <= 0)
4526 				break;
4527 
4528 			fuse_session_process_buf_int(se, &fbuf, NULL);
4529 		} else {
4530 			timeout = fuse_clean_cache(f);
4531 			curr_time(&now);
4532 			next_clean = now.tv_sec + timeout;
4533 		}
4534 	}
4535 
4536 	free(fbuf.mem);
4537 	fuse_session_reset(se);
4538 	return res < 0 ? -1 : 0;
4539 }
4540 
fuse_loop(struct fuse * f)4541 int fuse_loop(struct fuse *f)
4542 {
4543 	if (!f)
4544 		return -1;
4545 
4546 	if (lru_enabled(f))
4547 		return fuse_session_loop_remember(f);
4548 
4549 	return fuse_session_loop(f->se);
4550 }
4551 
4552 FUSE_SYMVER("fuse_loop_mt_312", "fuse_loop_mt@@FUSE_3.12")
fuse_loop_mt_312(struct fuse * f,struct fuse_loop_config * config)4553 int fuse_loop_mt_312(struct fuse *f, struct fuse_loop_config *config)
4554 {
4555 	if (f == NULL)
4556 		return -1;
4557 
4558 	int res = fuse_start_cleanup_thread(f);
4559 	if (res)
4560 		return -1;
4561 
4562 	res = fuse_session_loop_mt_312(fuse_get_session(f), config);
4563 	fuse_stop_cleanup_thread(f);
4564 	return res;
4565 }
4566 
4567 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config_v1 *config_v1);
4568 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)4569 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config_v1 *config_v1)
4570 {
4571 	struct fuse_loop_config *config = fuse_loop_cfg_create();
4572 	if (config == NULL)
4573 		return ENOMEM;
4574 
4575 	fuse_loop_cfg_convert(config, config_v1);
4576 
4577 	int res = fuse_loop_mt_312(f, config);
4578 
4579 	fuse_loop_cfg_destroy(config);
4580 
4581 	return res;
4582 }
4583 
4584 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
4585 FUSE_SYMVER("fuse_loop_mt_31", "fuse_loop_mt@FUSE_3.0")
fuse_loop_mt_31(struct fuse * f,int clone_fd)4586 int fuse_loop_mt_31(struct fuse *f, int clone_fd)
4587 {
4588 	int err;
4589 	struct fuse_loop_config *config = fuse_loop_cfg_create();
4590 
4591 	if (config == NULL)
4592 		return ENOMEM;
4593 
4594 	fuse_loop_cfg_set_clone_fd(config, clone_fd);
4595 
4596 	err = fuse_loop_mt_312(f, config);
4597 
4598 	fuse_loop_cfg_destroy(config);
4599 
4600 	return err;
4601 }
4602 
fuse_exit(struct fuse * f)4603 void fuse_exit(struct fuse *f)
4604 {
4605 	fuse_session_exit(f->se);
4606 }
4607 
fuse_get_context(void)4608 struct fuse_context *fuse_get_context(void)
4609 {
4610 	struct fuse_context_i *c = fuse_get_context_internal();
4611 
4612 	if (c)
4613 		return &c->ctx;
4614 	else
4615 		return NULL;
4616 }
4617 
fuse_getgroups(int size,gid_t list[])4618 int fuse_getgroups(int size, gid_t list[])
4619 {
4620 	struct fuse_context_i *c = fuse_get_context_internal();
4621 	if (!c)
4622 		return -EINVAL;
4623 
4624 	return fuse_req_getgroups(c->req, size, list);
4625 }
4626 
fuse_interrupted(void)4627 int fuse_interrupted(void)
4628 {
4629 	struct fuse_context_i *c = fuse_get_context_internal();
4630 
4631 	if (c)
4632 		return fuse_req_interrupted(c->req);
4633 	else
4634 		return 0;
4635 }
4636 
fuse_invalidate_path(struct fuse * f,const char * path)4637 int fuse_invalidate_path(struct fuse *f, const char *path) {
4638 	fuse_ino_t ino;
4639 	int err = lookup_path_in_cache(f, path, &ino);
4640 	if (err) {
4641 		return err;
4642 	}
4643 
4644 	return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
4645 }
4646 
4647 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4648 
4649 static const struct fuse_opt fuse_lib_opts[] = {
4650 	FUSE_OPT_KEY("debug",		      FUSE_OPT_KEY_KEEP),
4651 	FUSE_OPT_KEY("-d",		      FUSE_OPT_KEY_KEEP),
4652 	FUSE_LIB_OPT("debug",		      debug, 1),
4653 	FUSE_LIB_OPT("-d",		      debug, 1),
4654 	FUSE_LIB_OPT("kernel_cache",	      kernel_cache, 1),
4655 	FUSE_LIB_OPT("auto_cache",	      auto_cache, 1),
4656 	FUSE_LIB_OPT("noauto_cache",	      auto_cache, 0),
4657 	FUSE_LIB_OPT("no_rofd_flush",	      no_rofd_flush, 1),
4658 	FUSE_LIB_OPT("umask=",		      set_mode, 1),
4659 	FUSE_LIB_OPT("umask=%o",	      umask, 0),
4660 	FUSE_LIB_OPT("uid=",		      set_uid, 1),
4661 	FUSE_LIB_OPT("uid=%d",		      uid, 0),
4662 	FUSE_LIB_OPT("gid=",		      set_gid, 1),
4663 	FUSE_LIB_OPT("gid=%d",		      gid, 0),
4664 	FUSE_LIB_OPT("entry_timeout=%lf",     entry_timeout, 0),
4665 	FUSE_LIB_OPT("attr_timeout=%lf",      attr_timeout, 0),
4666 	FUSE_LIB_OPT("ac_attr_timeout=%lf",   ac_attr_timeout, 0),
4667 	FUSE_LIB_OPT("ac_attr_timeout=",      ac_attr_timeout_set, 1),
4668 	FUSE_LIB_OPT("negative_timeout=%lf",  negative_timeout, 0),
4669 	FUSE_LIB_OPT("noforget",              remember, -1),
4670 	FUSE_LIB_OPT("remember=%u",           remember, 0),
4671 	FUSE_LIB_OPT("modules=%s",	      modules, 0),
4672 	FUSE_LIB_OPT("parallel_direct_write=%d", parallel_direct_writes, 0),
4673 	FUSE_OPT_END
4674 };
4675 
fuse_lib_opt_proc(void * data,const char * arg,int key,struct fuse_args * outargs)4676 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4677 			     struct fuse_args *outargs)
4678 {
4679 	(void) arg; (void) outargs; (void) data; (void) key;
4680 
4681 	/* Pass through unknown options */
4682 	return 1;
4683 }
4684 
4685 
4686 static const struct fuse_opt fuse_help_opts[] = {
4687 	FUSE_LIB_OPT("modules=%s", modules, 1),
4688 	FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP),
4689 	FUSE_OPT_END
4690 };
4691 
print_module_help(const char * name,fuse_module_factory_t * fac)4692 static void print_module_help(const char *name,
4693 			      fuse_module_factory_t *fac)
4694 {
4695 	struct fuse_args a = FUSE_ARGS_INIT(0, NULL);
4696 	if (fuse_opt_add_arg(&a, "") == -1 ||
4697 	    fuse_opt_add_arg(&a, "-h") == -1)
4698 		return;
4699 	printf("\nOptions for %s module:\n", name);
4700 	(*fac)(&a, NULL);
4701 	fuse_opt_free_args(&a);
4702 }
4703 
fuse_lib_help(struct fuse_args * args)4704 void fuse_lib_help(struct fuse_args *args)
4705 {
4706 	/* These are not all options, but only the ones that
4707 	   may be of interest to an end-user */
4708 	printf(
4709 "    -o kernel_cache        cache files in kernel\n"
4710 "    -o [no]auto_cache      enable caching based on modification times (off)\n"
4711 "    -o no_rofd_flush       disable flushing of read-only fd on close (off)\n"
4712 "    -o umask=M             set file permissions (octal)\n"
4713 "    -o uid=N               set file owner\n"
4714 "    -o gid=N               set file group\n"
4715 "    -o entry_timeout=T     cache timeout for names (1.0s)\n"
4716 "    -o negative_timeout=T  cache timeout for deleted names (0.0s)\n"
4717 "    -o attr_timeout=T      cache timeout for attributes (1.0s)\n"
4718 "    -o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)\n"
4719 "    -o noforget            never forget cached inodes\n"
4720 "    -o remember=T          remember cached inodes for T seconds (0s)\n"
4721 "    -o modules=M1[:M2...]  names of modules to push onto filesystem stack\n");
4722 
4723 
4724 	/* Print low-level help */
4725 	fuse_lowlevel_help();
4726 
4727 	/* Print help for builtin modules */
4728 	print_module_help("subdir", &fuse_module_subdir_factory);
4729 #ifdef HAVE_ICONV
4730 	print_module_help("iconv", &fuse_module_iconv_factory);
4731 #endif
4732 
4733 	/* Parse command line options in case we need to
4734 	   activate more modules */
4735 	struct fuse_config conf = { .modules = NULL };
4736 	if (fuse_opt_parse(args, &conf, fuse_help_opts,
4737 			   fuse_lib_opt_proc) == -1
4738 	    || !conf.modules)
4739 		return;
4740 
4741 	char *module;
4742 	char *next;
4743 	struct fuse_module *m;
4744 
4745 	// Iterate over all modules
4746 	for (module = conf.modules; module; module = next) {
4747 		char *p;
4748 		for (p = module; *p && *p != ':'; p++);
4749 		next = *p ? p + 1 : NULL;
4750 		*p = '\0';
4751 
4752 		m = fuse_get_module(module);
4753 		if (m)
4754 			print_module_help(module, &m->factory);
4755 	}
4756 }
4757 
4758 
4759 
fuse_init_intr_signal(int signum,int * installed)4760 static int fuse_init_intr_signal(int signum, int *installed)
4761 {
4762 	struct sigaction old_sa;
4763 
4764 	if (sigaction(signum, NULL, &old_sa) == -1) {
4765 		perror("fuse: cannot get old signal handler");
4766 		return -1;
4767 	}
4768 
4769 	if (old_sa.sa_handler == SIG_DFL) {
4770 		struct sigaction sa;
4771 
4772 		memset(&sa, 0, sizeof(struct sigaction));
4773 		sa.sa_handler = fuse_intr_sighandler;
4774 		sigemptyset(&sa.sa_mask);
4775 
4776 		if (sigaction(signum, &sa, NULL) == -1) {
4777 			perror("fuse: cannot set interrupt signal handler");
4778 			return -1;
4779 		}
4780 		*installed = 1;
4781 	}
4782 	return 0;
4783 }
4784 
fuse_restore_intr_signal(int signum)4785 static void fuse_restore_intr_signal(int signum)
4786 {
4787 	struct sigaction sa;
4788 
4789 	memset(&sa, 0, sizeof(struct sigaction));
4790 	sa.sa_handler = SIG_DFL;
4791 	sigaction(signum, &sa, NULL);
4792 }
4793 
4794 
fuse_push_module(struct fuse * f,const char * module,struct fuse_args * args)4795 static int fuse_push_module(struct fuse *f, const char *module,
4796 			    struct fuse_args *args)
4797 {
4798 	struct fuse_fs *fs[2] = { f->fs, NULL };
4799 	struct fuse_fs *newfs;
4800 	struct fuse_module *m = fuse_get_module(module);
4801 
4802 	if (!m)
4803 		return -1;
4804 
4805 	newfs = m->factory(args, fs);
4806 	if (!newfs) {
4807 		fuse_put_module(m);
4808 		return -1;
4809 	}
4810 	f->fs = newfs;
4811 	return 0;
4812 }
4813 
fuse_fs_new(const struct fuse_operations * op,size_t op_size,void * user_data)4814 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4815 			    void *user_data)
4816 {
4817 	struct fuse_fs *fs;
4818 
4819 	if (sizeof(struct fuse_operations) < op_size) {
4820 		fuse_log(FUSE_LOG_ERR, "fuse: warning: library too old, some operations may not not work\n");
4821 		op_size = sizeof(struct fuse_operations);
4822 	}
4823 
4824 	fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4825 	if (!fs) {
4826 		fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse_fs object\n");
4827 		return NULL;
4828 	}
4829 
4830 	fs->user_data = user_data;
4831 	if (op)
4832 		memcpy(&fs->op, op, op_size);
4833 	return fs;
4834 }
4835 
node_table_init(struct node_table * t)4836 static int node_table_init(struct node_table *t)
4837 {
4838 	t->size = NODE_TABLE_MIN_SIZE;
4839 	t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4840 	if (t->array == NULL) {
4841 		fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
4842 		return -1;
4843 	}
4844 	t->use = 0;
4845 	t->split = 0;
4846 
4847 	return 0;
4848 }
4849 
fuse_prune_nodes(void * fuse)4850 static void *fuse_prune_nodes(void *fuse)
4851 {
4852 	struct fuse *f = fuse;
4853 	int sleep_time;
4854 
4855 	while(1) {
4856 		sleep_time = fuse_clean_cache(f);
4857 		sleep(sleep_time);
4858 	}
4859 	return NULL;
4860 }
4861 
fuse_start_cleanup_thread(struct fuse * f)4862 int fuse_start_cleanup_thread(struct fuse *f)
4863 {
4864 	if (lru_enabled(f))
4865 		return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4866 
4867 	return 0;
4868 }
4869 
fuse_stop_cleanup_thread(struct fuse * f)4870 void fuse_stop_cleanup_thread(struct fuse *f)
4871 {
4872 	if (lru_enabled(f)) {
4873 		pthread_mutex_lock(&f->lock);
4874 		pthread_cancel(f->prune_thread);
4875 		pthread_mutex_unlock(&f->lock);
4876 		pthread_join(f->prune_thread, NULL);
4877 	}
4878 }
4879 
4880 
4881 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)4882 struct fuse *fuse_new_31(struct fuse_args *args,
4883 		      const struct fuse_operations *op,
4884 		      size_t op_size, void *user_data)
4885 {
4886 	struct fuse *f;
4887 	struct node *root;
4888 	struct fuse_fs *fs;
4889 	struct fuse_lowlevel_ops llop = fuse_path_ops;
4890 
4891 	f = (struct fuse *) calloc(1, sizeof(struct fuse));
4892 	if (f == NULL) {
4893 		fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse object\n");
4894 		goto out;
4895 	}
4896 
4897 	f->conf.entry_timeout = 1.0;
4898 	f->conf.attr_timeout = 1.0;
4899 	f->conf.negative_timeout = 0.0;
4900 	f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4901 
4902 	/* Parse options */
4903 	if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4904 			   fuse_lib_opt_proc) == -1)
4905 		goto out_free;
4906 
4907 	pthread_mutex_lock(&fuse_context_lock);
4908 	static int builtin_modules_registered = 0;
4909 	/* Have the builtin modules already been registered? */
4910 	if (builtin_modules_registered == 0) {
4911 		/* If not, register them. */
4912 		fuse_register_module("subdir", fuse_module_subdir_factory, NULL);
4913 #ifdef HAVE_ICONV
4914 		fuse_register_module("iconv", fuse_module_iconv_factory, NULL);
4915 #endif
4916 		builtin_modules_registered= 1;
4917 	}
4918 	pthread_mutex_unlock(&fuse_context_lock);
4919 
4920 	if (fuse_create_context_key() == -1)
4921 		goto out_free;
4922 
4923 	fs = fuse_fs_new(op, op_size, user_data);
4924 	if (!fs)
4925 		goto out_delete_context_key;
4926 
4927 	f->fs = fs;
4928 
4929 	/* Oh f**k, this is ugly! */
4930 	if (!fs->op.lock) {
4931 		llop.getlk = NULL;
4932 		llop.setlk = NULL;
4933 	}
4934 
4935 	f->pagesize = getpagesize();
4936 	init_list_head(&f->partial_slabs);
4937 	init_list_head(&f->full_slabs);
4938 	init_list_head(&f->lru_table);
4939 
4940 	if (f->conf.modules) {
4941 		char *module;
4942 		char *next;
4943 
4944 		for (module = f->conf.modules; module; module = next) {
4945 			char *p;
4946 			for (p = module; *p && *p != ':'; p++);
4947 			next = *p ? p + 1 : NULL;
4948 			*p = '\0';
4949 			if (module[0] &&
4950 			    fuse_push_module(f, module, args) == -1)
4951 				goto out_free_fs;
4952 		}
4953 	}
4954 
4955 	if (!f->conf.ac_attr_timeout_set)
4956 		f->conf.ac_attr_timeout = f->conf.attr_timeout;
4957 
4958 #if defined(__FreeBSD__) || defined(__NetBSD__)
4959 	/*
4960 	 * In FreeBSD, we always use these settings as inode numbers
4961 	 * are needed to make getcwd(3) work.
4962 	 */
4963 	f->conf.readdir_ino = 1;
4964 #endif
4965 
4966 	f->se = fuse_session_new(args, &llop, sizeof(llop), f);
4967 	if (f->se == NULL)
4968 		goto out_free_fs;
4969 
4970 	if (f->conf.debug) {
4971 		fuse_log(FUSE_LOG_DEBUG, "nullpath_ok: %i\n", f->conf.nullpath_ok);
4972 	}
4973 
4974 	/* Trace topmost layer by default */
4975 	f->fs->debug = f->conf.debug;
4976 	f->ctr = 0;
4977 	f->generation = 0;
4978 	if (node_table_init(&f->name_table) == -1)
4979 		goto out_free_session;
4980 
4981 	if (node_table_init(&f->id_table) == -1)
4982 		goto out_free_name_table;
4983 
4984 	pthread_mutex_init(&f->lock, NULL);
4985 
4986 	root = alloc_node(f);
4987 	if (root == NULL) {
4988 		fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n");
4989 		goto out_free_id_table;
4990 	}
4991 	if (lru_enabled(f)) {
4992 		struct node_lru *lnode = node_lru(root);
4993 		init_list_head(&lnode->lru);
4994 	}
4995 
4996 	strcpy(root->inline_name, "/");
4997 	root->name = root->inline_name;
4998 
4999 	if (f->conf.intr &&
5000 	    fuse_init_intr_signal(f->conf.intr_signal,
5001 				  &f->intr_installed) == -1)
5002 		goto out_free_root;
5003 
5004 	root->parent = NULL;
5005 	root->nodeid = FUSE_ROOT_ID;
5006 	inc_nlookup(root);
5007 	hash_id(f, root);
5008 
5009 	return f;
5010 
5011 out_free_root:
5012 	free(root);
5013 out_free_id_table:
5014 	free(f->id_table.array);
5015 out_free_name_table:
5016 	free(f->name_table.array);
5017 out_free_session:
5018 	fuse_session_destroy(f->se);
5019 out_free_fs:
5020 	free(f->fs);
5021 	free(f->conf.modules);
5022 out_delete_context_key:
5023 	fuse_delete_context_key();
5024 out_free:
5025 	free(f);
5026 out:
5027 	return NULL;
5028 }
5029 
5030 /* Emulates 3.0-style fuse_new(), which processes --help */
5031 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
5032 			 size_t op_size, void *private_data);
5033 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)5034 struct fuse *fuse_new_30(struct fuse_args *args,
5035 			 const struct fuse_operations *op,
5036 			 size_t op_size, void *user_data)
5037 {
5038 	struct fuse_config conf;
5039 
5040 	memset(&conf, 0, sizeof(conf));
5041 
5042 	const struct fuse_opt opts[] = {
5043 		FUSE_LIB_OPT("-h", show_help, 1),
5044 		FUSE_LIB_OPT("--help", show_help, 1),
5045 		FUSE_OPT_END
5046 	};
5047 
5048 	if (fuse_opt_parse(args, &conf, opts,
5049 			   fuse_lib_opt_proc) == -1)
5050 		return NULL;
5051 
5052 	if (conf.show_help) {
5053 		fuse_lib_help(args);
5054 		return NULL;
5055 	} else
5056 		return fuse_new_31(args, op, op_size, user_data);
5057 }
5058 
fuse_destroy(struct fuse * f)5059 void fuse_destroy(struct fuse *f)
5060 {
5061 	size_t i;
5062 
5063 	if (f->conf.intr && f->intr_installed)
5064 		fuse_restore_intr_signal(f->conf.intr_signal);
5065 
5066 	if (f->fs) {
5067 		fuse_create_context(f);
5068 
5069 		for (i = 0; i < f->id_table.size; i++) {
5070 			struct node *node;
5071 
5072 			for (node = f->id_table.array[i]; node != NULL;
5073 			     node = node->id_next) {
5074 				if (node->is_hidden) {
5075 					char *path;
5076 					if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
5077 						fuse_fs_unlink(f->fs, path);
5078 						free(path);
5079 					}
5080 				}
5081 			}
5082 		}
5083 	}
5084 	for (i = 0; i < f->id_table.size; i++) {
5085 		struct node *node;
5086 		struct node *next;
5087 
5088 		for (node = f->id_table.array[i]; node != NULL; node = next) {
5089 			next = node->id_next;
5090 			free_node(f, node);
5091 			f->id_table.use--;
5092 		}
5093 	}
5094 	assert(list_empty(&f->partial_slabs));
5095 	assert(list_empty(&f->full_slabs));
5096 
5097 	while (fuse_modules) {
5098 		fuse_put_module(fuse_modules);
5099 	}
5100 	free(f->id_table.array);
5101 	free(f->name_table.array);
5102 	pthread_mutex_destroy(&f->lock);
5103 	fuse_session_destroy(f->se);
5104 	free(f->fs);
5105 	free(f->conf.modules);
5106 	free(f);
5107 	fuse_delete_context_key();
5108 }
5109 
fuse_mount(struct fuse * f,const char * mountpoint)5110 int fuse_mount(struct fuse *f, const char *mountpoint) {
5111 	return fuse_session_mount(fuse_get_session(f), mountpoint);
5112 }
5113 
5114 
fuse_unmount(struct fuse * f)5115 void fuse_unmount(struct fuse *f) {
5116 	fuse_session_unmount(fuse_get_session(f));
5117 }
5118 
fuse_version(void)5119 int fuse_version(void)
5120 {
5121 	return FUSE_VERSION;
5122 }
5123 
fuse_pkgversion(void)5124 const char *fuse_pkgversion(void)
5125 {
5126 	return PACKAGE_VERSION;
5127 }
5128