2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU LGPLv2.
6 See the file COPYING.LIB
10 /* For pthread_rwlock_t */
15 #include "fuse_lowlevel.h"
17 #include "fuse_misc.h"
18 #include "fuse_kernel.h"
34 #include <sys/param.h>
39 #define FUSE_NODE_SLAB 1
45 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
47 #define FUSE_UNKNOWN_INO 0xffffffff
48 #define OFFSET_MAX 0x7fffffffffffffffLL
50 #define NODE_TABLE_MIN_SIZE 8192
57 double negative_timeout
;
59 double ac_attr_timeout
;
60 int ac_attr_timeout_set
;
80 struct fuse_operations op
;
81 struct fuse_module
*m
;
91 struct lock_queue_element
{
92 struct lock_queue_element
*next
;
101 struct node
**wnode2
;
103 bool first_locked
: 1;
104 bool second_locked
: 1;
115 #define container_of(ptr, type, member) ({ \
116 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
117 (type *)( (char *)__mptr - offsetof(type,member) );})
119 #define list_entry(ptr, type, member) \
120 container_of(ptr, type, member)
123 struct list_head
*next
;
124 struct list_head
*prev
;
128 struct list_head list
; /* must be the first member */
129 struct list_head freelist
;
134 struct fuse_session
*se
;
135 struct node_table name_table
;
136 struct node_table id_table
;
137 struct list_head lru_table
;
139 unsigned int generation
;
140 unsigned int hidectr
;
141 pthread_mutex_t lock
;
142 struct fuse_config conf
;
145 struct lock_queue_element
*lockq
;
147 struct list_head partial_slabs
;
148 struct list_head full_slabs
;
149 pthread_t prune_thread
;
162 struct node
*name_next
;
163 struct node
*id_next
;
165 unsigned int generation
;
171 struct timespec stat_updated
;
172 struct timespec mtime
;
175 unsigned int is_hidden
: 1;
176 unsigned int cache_valid
: 1;
178 char inline_name
[32];
181 #define TREELOCK_WRITE -1
182 #define TREELOCK_WAIT_OFFSET INT_MIN
186 struct list_head lru
;
187 struct timespec forget_time
;
191 pthread_mutex_t lock
;
205 struct fuse_context_i
{
206 struct fuse_context ctx
;
210 static pthread_key_t fuse_context_key
;
211 static pthread_mutex_t fuse_context_lock
= PTHREAD_MUTEX_INITIALIZER
;
212 static int fuse_context_ref
;
213 static struct fusemod_so
*fuse_current_so
;
214 static struct fuse_module
*fuse_modules
;
216 static int fuse_load_so_name(const char *soname
)
218 struct fusemod_so
*so
;
220 so
= calloc(1, sizeof(struct fusemod_so
));
222 fprintf(stderr
, "fuse: memory allocation failed\n");
226 fuse_current_so
= so
;
227 so
->handle
= dlopen(soname
, RTLD_NOW
);
228 fuse_current_so
= NULL
;
230 fprintf(stderr
, "fuse: %s\n", dlerror());
234 fprintf(stderr
, "fuse: %s did not register any modules\n",
247 static int fuse_load_so_module(const char *module
)
250 char *soname
= malloc(strlen(module
) + 64);
252 fprintf(stderr
, "fuse: memory allocation failed\n");
255 sprintf(soname
, "libfusemod_%s.so", module
);
256 res
= fuse_load_so_name(soname
);
261 static struct fuse_module
*fuse_find_module(const char *module
)
263 struct fuse_module
*m
;
264 for (m
= fuse_modules
; m
; m
= m
->next
) {
265 if (strcmp(module
, m
->name
) == 0) {
273 static struct fuse_module
*fuse_get_module(const char *module
)
275 struct fuse_module
*m
;
277 pthread_mutex_lock(&fuse_context_lock
);
278 m
= fuse_find_module(module
);
280 int err
= fuse_load_so_module(module
);
282 m
= fuse_find_module(module
);
284 pthread_mutex_unlock(&fuse_context_lock
);
288 static void fuse_put_module(struct fuse_module
*m
)
290 pthread_mutex_lock(&fuse_context_lock
);
293 if (!m
->ctr
&& m
->so
) {
294 struct fusemod_so
*so
= m
->so
;
298 struct fuse_module
**mp
;
299 for (mp
= &fuse_modules
; *mp
;) {
309 pthread_mutex_unlock(&fuse_context_lock
);
312 static void init_list_head(struct list_head
*list
)
318 static int list_empty(const struct list_head
*head
)
320 return head
->next
== head
;
323 static void list_add(struct list_head
*new, struct list_head
*prev
,
324 struct list_head
*next
)
332 static inline void list_add_head(struct list_head
*new, struct list_head
*head
)
334 list_add(new, head
, head
->next
);
337 static inline void list_add_tail(struct list_head
*new, struct list_head
*head
)
339 list_add(new, head
->prev
, head
);
342 static inline void list_del(struct list_head
*entry
)
344 struct list_head
*prev
= entry
->prev
;
345 struct list_head
*next
= entry
->next
;
351 static inline int lru_enabled(struct fuse
*f
)
353 return f
->conf
.remember
> 0;
356 static struct node_lru
*node_lru(struct node
*node
)
358 return (struct node_lru
*) node
;
361 static size_t get_node_size(struct fuse
*f
)
364 return sizeof(struct node_lru
);
366 return sizeof(struct node
);
369 #ifdef FUSE_NODE_SLAB
370 static struct node_slab
*list_to_slab(struct list_head
*head
)
372 return (struct node_slab
*) head
;
375 static struct node_slab
*node_to_slab(struct fuse
*f
, struct node
*node
)
377 return (struct node_slab
*) (((uintptr_t) node
) & ~((uintptr_t) f
->pagesize
- 1));
380 static int alloc_slab(struct fuse
*f
)
383 struct node_slab
*slab
;
387 size_t node_size
= get_node_size(f
);
389 mem
= mmap(NULL
, f
->pagesize
, PROT_READ
| PROT_WRITE
,
390 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
392 if (mem
== MAP_FAILED
)
396 init_list_head(&slab
->freelist
);
398 num
= (f
->pagesize
- sizeof(struct node_slab
)) / node_size
;
400 start
= (char *) mem
+ f
->pagesize
- num
* node_size
;
401 for (i
= 0; i
< num
; i
++) {
404 n
= (struct list_head
*) (start
+ i
* node_size
);
405 list_add_tail(n
, &slab
->freelist
);
407 list_add_tail(&slab
->list
, &f
->partial_slabs
);
412 static struct node
*alloc_node(struct fuse
*f
)
414 struct node_slab
*slab
;
415 struct list_head
*node
;
417 if (list_empty(&f
->partial_slabs
)) {
418 int res
= alloc_slab(f
);
422 slab
= list_to_slab(f
->partial_slabs
.next
);
424 node
= slab
->freelist
.next
;
426 if (list_empty(&slab
->freelist
)) {
427 list_del(&slab
->list
);
428 list_add_tail(&slab
->list
, &f
->full_slabs
);
430 memset(node
, 0, sizeof(struct node
));
432 return (struct node
*) node
;
435 static void free_slab(struct fuse
*f
, struct node_slab
*slab
)
439 list_del(&slab
->list
);
440 res
= munmap(slab
, f
->pagesize
);
442 fprintf(stderr
, "fuse warning: munmap(%p) failed\n", slab
);
445 static void free_node_mem(struct fuse
*f
, struct node
*node
)
447 struct node_slab
*slab
= node_to_slab(f
, node
);
448 struct list_head
*n
= (struct list_head
*) node
;
452 if (list_empty(&slab
->freelist
)) {
453 list_del(&slab
->list
);
454 list_add_tail(&slab
->list
, &f
->partial_slabs
);
456 list_add_head(n
, &slab
->freelist
);
462 static struct node
*alloc_node(struct fuse
*f
)
464 return (struct node
*) calloc(1, get_node_size(f
));
467 static void free_node_mem(struct fuse
*f
, struct node
*node
)
474 static size_t id_hash(struct fuse
*f
, fuse_ino_t ino
)
476 uint64_t hash
= ((uint32_t) ino
* 2654435761U) % f
->id_table
.size
;
477 uint64_t oldhash
= hash
% (f
->id_table
.size
/ 2);
479 if (oldhash
>= f
->id_table
.split
)
485 static struct node
*get_node_nocheck(struct fuse
*f
, fuse_ino_t nodeid
)
487 size_t hash
= id_hash(f
, nodeid
);
490 for (node
= f
->id_table
.array
[hash
]; node
!= NULL
; node
= node
->id_next
)
491 if (node
->nodeid
== nodeid
)
497 static struct node
*get_node(struct fuse
*f
, fuse_ino_t nodeid
)
499 struct node
*node
= get_node_nocheck(f
, nodeid
);
501 fprintf(stderr
, "fuse internal error: node %llu not found\n",
502 (unsigned long long) nodeid
);
508 static void curr_time(struct timespec
*now
);
509 static double diff_timespec(const struct timespec
*t1
,
510 const struct timespec
*t2
);
512 static void remove_node_lru(struct node
*node
)
514 struct node_lru
*lnode
= node_lru(node
);
515 list_del(&lnode
->lru
);
516 init_list_head(&lnode
->lru
);
519 static void set_forget_time(struct fuse
*f
, struct node
*node
)
521 struct node_lru
*lnode
= node_lru(node
);
523 list_del(&lnode
->lru
);
524 list_add_tail(&lnode
->lru
, &f
->lru_table
);
525 curr_time(&lnode
->forget_time
);
528 static void free_node(struct fuse
*f
, struct node
*node
)
530 if (node
->name
!= node
->inline_name
)
532 free_node_mem(f
, node
);
535 static void node_table_reduce(struct node_table
*t
)
537 size_t newsize
= t
->size
/ 2;
540 if (newsize
< NODE_TABLE_MIN_SIZE
)
543 newarray
= realloc(t
->array
, sizeof(struct node
*) * newsize
);
544 if (newarray
!= NULL
)
548 t
->split
= t
->size
/ 2;
551 static void remerge_id(struct fuse
*f
)
553 struct node_table
*t
= &f
->id_table
;
557 node_table_reduce(t
);
559 for (iter
= 8; t
->split
> 0 && iter
; iter
--) {
563 upper
= &t
->array
[t
->split
+ t
->size
/ 2];
567 for (nodep
= &t
->array
[t
->split
]; *nodep
;
568 nodep
= &(*nodep
)->id_next
);
577 static void unhash_id(struct fuse
*f
, struct node
*node
)
579 struct node
**nodep
= &f
->id_table
.array
[id_hash(f
, node
->nodeid
)];
581 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->id_next
)
582 if (*nodep
== node
) {
583 *nodep
= node
->id_next
;
586 if(f
->id_table
.use
< f
->id_table
.size
/ 4)
592 static int node_table_resize(struct node_table
*t
)
594 size_t newsize
= t
->size
* 2;
597 newarray
= realloc(t
->array
, sizeof(struct node
*) * newsize
);
598 if (newarray
== NULL
)
602 memset(t
->array
+ t
->size
, 0, t
->size
* sizeof(struct node
*));
609 static void rehash_id(struct fuse
*f
)
611 struct node_table
*t
= &f
->id_table
;
616 if (t
->split
== t
->size
/ 2)
621 for (nodep
= &t
->array
[hash
]; *nodep
!= NULL
; nodep
= next
) {
622 struct node
*node
= *nodep
;
623 size_t newhash
= id_hash(f
, node
->nodeid
);
625 if (newhash
!= hash
) {
627 *nodep
= node
->id_next
;
628 node
->id_next
= t
->array
[newhash
];
629 t
->array
[newhash
] = node
;
631 next
= &node
->id_next
;
634 if (t
->split
== t
->size
/ 2)
635 node_table_resize(t
);
638 static void hash_id(struct fuse
*f
, struct node
*node
)
640 size_t hash
= id_hash(f
, node
->nodeid
);
641 node
->id_next
= f
->id_table
.array
[hash
];
642 f
->id_table
.array
[hash
] = node
;
645 if (f
->id_table
.use
>= f
->id_table
.size
/ 2)
649 static size_t name_hash(struct fuse
*f
, fuse_ino_t parent
,
652 uint64_t hash
= parent
;
655 for (; *name
; name
++)
656 hash
= hash
* 31 + (unsigned char) *name
;
658 hash
%= f
->name_table
.size
;
659 oldhash
= hash
% (f
->name_table
.size
/ 2);
660 if (oldhash
>= f
->name_table
.split
)
666 static void unref_node(struct fuse
*f
, struct node
*node
);
668 static void remerge_name(struct fuse
*f
)
670 struct node_table
*t
= &f
->name_table
;
674 node_table_reduce(t
);
676 for (iter
= 8; t
->split
> 0 && iter
; iter
--) {
680 upper
= &t
->array
[t
->split
+ t
->size
/ 2];
684 for (nodep
= &t
->array
[t
->split
]; *nodep
;
685 nodep
= &(*nodep
)->name_next
);
694 static void unhash_name(struct fuse
*f
, struct node
*node
)
697 size_t hash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
698 struct node
**nodep
= &f
->name_table
.array
[hash
];
700 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->name_next
)
701 if (*nodep
== node
) {
702 *nodep
= node
->name_next
;
703 node
->name_next
= NULL
;
704 unref_node(f
, node
->parent
);
705 if (node
->name
!= node
->inline_name
)
711 if (f
->name_table
.use
< f
->name_table
.size
/ 4)
716 "fuse internal error: unable to unhash node: %llu\n",
717 (unsigned long long) node
->nodeid
);
722 static void rehash_name(struct fuse
*f
)
724 struct node_table
*t
= &f
->name_table
;
729 if (t
->split
== t
->size
/ 2)
734 for (nodep
= &t
->array
[hash
]; *nodep
!= NULL
; nodep
= next
) {
735 struct node
*node
= *nodep
;
736 size_t newhash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
738 if (newhash
!= hash
) {
740 *nodep
= node
->name_next
;
741 node
->name_next
= t
->array
[newhash
];
742 t
->array
[newhash
] = node
;
744 next
= &node
->name_next
;
747 if (t
->split
== t
->size
/ 2)
748 node_table_resize(t
);
751 static int hash_name(struct fuse
*f
, struct node
*node
, fuse_ino_t parentid
,
754 size_t hash
= name_hash(f
, parentid
, name
);
755 struct node
*parent
= get_node(f
, parentid
);
756 if (strlen(name
) < sizeof(node
->inline_name
)) {
757 strcpy(node
->inline_name
, name
);
758 node
->name
= node
->inline_name
;
760 node
->name
= strdup(name
);
761 if (node
->name
== NULL
)
766 node
->parent
= parent
;
767 node
->name_next
= f
->name_table
.array
[hash
];
768 f
->name_table
.array
[hash
] = node
;
771 if (f
->name_table
.use
>= f
->name_table
.size
/ 2)
777 static void delete_node(struct fuse
*f
, struct node
*node
)
780 fprintf(stderr
, "DELETE: %llu\n",
781 (unsigned long long) node
->nodeid
);
783 assert(node
->treelock
== 0);
784 unhash_name(f
, node
);
786 remove_node_lru(node
);
791 static void unref_node(struct fuse
*f
, struct node
*node
)
793 assert(node
->refctr
> 0);
796 delete_node(f
, node
);
799 static fuse_ino_t
next_id(struct fuse
*f
)
802 f
->ctr
= (f
->ctr
+ 1) & 0xffffffff;
805 } while (f
->ctr
== 0 || f
->ctr
== FUSE_UNKNOWN_INO
||
806 get_node_nocheck(f
, f
->ctr
) != NULL
);
810 static struct node
*lookup_node(struct fuse
*f
, fuse_ino_t parent
,
813 size_t hash
= name_hash(f
, parent
, name
);
816 for (node
= f
->name_table
.array
[hash
]; node
!= NULL
; node
= node
->name_next
)
817 if (node
->parent
->nodeid
== parent
&&
818 strcmp(node
->name
, name
) == 0)
824 static void inc_nlookup(struct node
*node
)
831 static struct node
*find_node(struct fuse
*f
, fuse_ino_t parent
,
836 pthread_mutex_lock(&f
->lock
);
838 node
= get_node(f
, parent
);
840 node
= lookup_node(f
, parent
, name
);
842 node
= alloc_node(f
);
846 node
->nodeid
= next_id(f
);
847 node
->generation
= f
->generation
;
848 if (f
->conf
.remember
)
851 if (hash_name(f
, node
, parent
, name
) == -1) {
857 if (lru_enabled(f
)) {
858 struct node_lru
*lnode
= node_lru(node
);
859 init_list_head(&lnode
->lru
);
861 } else if (lru_enabled(f
) && node
->nlookup
== 1) {
862 remove_node_lru(node
);
866 pthread_mutex_unlock(&f
->lock
);
870 static char *add_name(char **buf
, unsigned *bufsize
, char *s
, const char *name
)
872 size_t len
= strlen(name
);
874 if (s
- len
<= *buf
) {
875 unsigned pathlen
= *bufsize
- (s
- *buf
);
876 unsigned newbufsize
= *bufsize
;
879 while (newbufsize
< pathlen
+ len
+ 1) {
880 if (newbufsize
>= 0x80000000)
881 newbufsize
= 0xffffffff;
886 newbuf
= realloc(*buf
, newbufsize
);
891 s
= newbuf
+ newbufsize
- pathlen
;
892 memmove(s
, newbuf
+ *bufsize
- pathlen
, pathlen
);
893 *bufsize
= newbufsize
;
896 strncpy(s
, name
, len
);
903 static void unlock_path(struct fuse
*f
, fuse_ino_t nodeid
, struct node
*wnode
,
909 assert(wnode
->treelock
== TREELOCK_WRITE
);
913 for (node
= get_node(f
, nodeid
);
914 node
!= end
&& node
->nodeid
!= FUSE_ROOT_ID
; node
= node
->parent
) {
915 assert(node
->treelock
!= 0);
916 assert(node
->treelock
!= TREELOCK_WAIT_OFFSET
);
917 assert(node
->treelock
!= TREELOCK_WRITE
);
919 if (node
->treelock
== TREELOCK_WAIT_OFFSET
)
924 static int try_get_path(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
925 char **path
, struct node
**wnodep
, bool need_lock
)
927 unsigned bufsize
= 256;
931 struct node
*wnode
= NULL
;
937 buf
= malloc(bufsize
);
941 s
= buf
+ bufsize
- 1;
945 s
= add_name(&buf
, &bufsize
, s
, name
);
953 wnode
= lookup_node(f
, nodeid
, name
);
955 if (wnode
->treelock
!= 0) {
956 if (wnode
->treelock
> 0)
957 wnode
->treelock
+= TREELOCK_WAIT_OFFSET
;
961 wnode
->treelock
= TREELOCK_WRITE
;
965 for (node
= get_node(f
, nodeid
); node
->nodeid
!= FUSE_ROOT_ID
;
966 node
= node
->parent
) {
968 if (node
->name
== NULL
|| node
->parent
== NULL
)
972 s
= add_name(&buf
, &bufsize
, s
, node
->name
);
978 if (node
->treelock
< 0)
986 memmove(buf
, s
, bufsize
- (s
- buf
));
998 unlock_path(f
, nodeid
, wnode
, node
);
1006 static void queue_element_unlock(struct fuse
*f
, struct lock_queue_element
*qe
)
1010 if (qe
->first_locked
) {
1011 wnode
= qe
->wnode1
? *qe
->wnode1
: NULL
;
1012 unlock_path(f
, qe
->nodeid1
, wnode
, NULL
);
1013 qe
->first_locked
= false;
1015 if (qe
->second_locked
) {
1016 wnode
= qe
->wnode2
? *qe
->wnode2
: NULL
;
1017 unlock_path(f
, qe
->nodeid2
, wnode
, NULL
);
1018 qe
->second_locked
= false;
1022 static void queue_element_wakeup(struct fuse
*f
, struct lock_queue_element
*qe
)
1025 bool first
= (qe
== f
->lockq
);
1028 /* Just waiting for it to be unlocked */
1029 if (get_node(f
, qe
->nodeid1
)->treelock
== 0)
1030 pthread_cond_signal(&qe
->cond
);
1035 if (!qe
->first_locked
) {
1036 err
= try_get_path(f
, qe
->nodeid1
, qe
->name1
, qe
->path1
,
1039 qe
->first_locked
= true;
1040 else if (err
!= -EAGAIN
)
1043 if (!qe
->second_locked
&& qe
->path2
) {
1044 err
= try_get_path(f
, qe
->nodeid2
, qe
->name2
, qe
->path2
,
1047 qe
->second_locked
= true;
1048 else if (err
!= -EAGAIN
)
1052 if (qe
->first_locked
&& (qe
->second_locked
|| !qe
->path2
)) {
1058 * Only let the first element be partially locked otherwise there could
1061 * But do allow the first element to be partially locked to prevent
1065 queue_element_unlock(f
, qe
);
1071 queue_element_unlock(f
, qe
);
1075 pthread_cond_signal(&qe
->cond
);
1078 static void wake_up_queued(struct fuse
*f
)
1080 struct lock_queue_element
*qe
;
1082 for (qe
= f
->lockq
; qe
!= NULL
; qe
= qe
->next
)
1083 queue_element_wakeup(f
, qe
);
1086 static void debug_path(struct fuse
*f
, const char *msg
, fuse_ino_t nodeid
,
1087 const char *name
, bool wr
)
1089 if (f
->conf
.debug
) {
1090 struct node
*wnode
= NULL
;
1093 wnode
= lookup_node(f
, nodeid
, name
);
1096 fprintf(stderr
, "%s %llu (w)\n",
1097 msg
, (unsigned long long) wnode
->nodeid
);
1099 fprintf(stderr
, "%s %llu\n",
1100 msg
, (unsigned long long) nodeid
);
1105 static void queue_path(struct fuse
*f
, struct lock_queue_element
*qe
)
1107 struct lock_queue_element
**qp
;
1110 qe
->first_locked
= false;
1111 qe
->second_locked
= false;
1112 pthread_cond_init(&qe
->cond
, NULL
);
1114 for (qp
= &f
->lockq
; *qp
!= NULL
; qp
= &(*qp
)->next
);
1118 static void dequeue_path(struct fuse
*f
, struct lock_queue_element
*qe
)
1120 struct lock_queue_element
**qp
;
1122 pthread_cond_destroy(&qe
->cond
);
1123 for (qp
= &f
->lockq
; *qp
!= qe
; qp
= &(*qp
)->next
);
1127 static int wait_path(struct fuse
*f
, struct lock_queue_element
*qe
)
1132 pthread_cond_wait(&qe
->cond
, &f
->lock
);
1133 } while (!qe
->done
);
1135 dequeue_path(f
, qe
);
1140 static int get_path_common(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1141 char **path
, struct node
**wnode
)
1145 pthread_mutex_lock(&f
->lock
);
1146 err
= try_get_path(f
, nodeid
, name
, path
, wnode
, true);
1147 if (err
== -EAGAIN
) {
1148 struct lock_queue_element qe
= {
1154 debug_path(f
, "QUEUE PATH", nodeid
, name
, !!wnode
);
1155 err
= wait_path(f
, &qe
);
1156 debug_path(f
, "DEQUEUE PATH", nodeid
, name
, !!wnode
);
1158 pthread_mutex_unlock(&f
->lock
);
1163 static int get_path(struct fuse
*f
, fuse_ino_t nodeid
, char **path
)
1165 return get_path_common(f
, nodeid
, NULL
, path
, NULL
);
1168 static int get_path_nullok(struct fuse
*f
, fuse_ino_t nodeid
, char **path
)
1172 if (f
->conf
.nopath
) {
1175 err
= get_path_common(f
, nodeid
, NULL
, path
, NULL
);
1183 static int get_path_name(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1186 return get_path_common(f
, nodeid
, name
, path
, NULL
);
1189 static int get_path_wrlock(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1190 char **path
, struct node
**wnode
)
1192 return get_path_common(f
, nodeid
, name
, path
, wnode
);
1195 static int try_get_path2(struct fuse
*f
, fuse_ino_t nodeid1
, const char *name1
,
1196 fuse_ino_t nodeid2
, const char *name2
,
1197 char **path1
, char **path2
,
1198 struct node
**wnode1
, struct node
**wnode2
)
1202 /* FIXME: locking two paths needs deadlock checking */
1203 err
= try_get_path(f
, nodeid1
, name1
, path1
, wnode1
, true);
1205 err
= try_get_path(f
, nodeid2
, name2
, path2
, wnode2
, true);
1207 struct node
*wn1
= wnode1
? *wnode1
: NULL
;
1209 unlock_path(f
, nodeid1
, wn1
, NULL
);
1216 static int get_path2(struct fuse
*f
, fuse_ino_t nodeid1
, const char *name1
,
1217 fuse_ino_t nodeid2
, const char *name2
,
1218 char **path1
, char **path2
,
1219 struct node
**wnode1
, struct node
**wnode2
)
1223 pthread_mutex_lock(&f
->lock
);
1224 err
= try_get_path2(f
, nodeid1
, name1
, nodeid2
, name2
,
1225 path1
, path2
, wnode1
, wnode2
);
1226 if (err
== -EAGAIN
) {
1227 struct lock_queue_element qe
= {
1238 debug_path(f
, "QUEUE PATH1", nodeid1
, name1
, !!wnode1
);
1239 debug_path(f
, " PATH2", nodeid2
, name2
, !!wnode2
);
1240 err
= wait_path(f
, &qe
);
1241 debug_path(f
, "DEQUEUE PATH1", nodeid1
, name1
, !!wnode1
);
1242 debug_path(f
, " PATH2", nodeid2
, name2
, !!wnode2
);
1244 pthread_mutex_unlock(&f
->lock
);
1249 static void free_path_wrlock(struct fuse
*f
, fuse_ino_t nodeid
,
1250 struct node
*wnode
, char *path
)
1252 pthread_mutex_lock(&f
->lock
);
1253 unlock_path(f
, nodeid
, wnode
, NULL
);
1256 pthread_mutex_unlock(&f
->lock
);
1260 static void free_path(struct fuse
*f
, fuse_ino_t nodeid
, char *path
)
1263 free_path_wrlock(f
, nodeid
, NULL
, path
);
1266 static void free_path2(struct fuse
*f
, fuse_ino_t nodeid1
, fuse_ino_t nodeid2
,
1267 struct node
*wnode1
, struct node
*wnode2
,
1268 char *path1
, char *path2
)
1270 pthread_mutex_lock(&f
->lock
);
1271 unlock_path(f
, nodeid1
, wnode1
, NULL
);
1272 unlock_path(f
, nodeid2
, wnode2
, NULL
);
1274 pthread_mutex_unlock(&f
->lock
);
1279 static void forget_node(struct fuse
*f
, fuse_ino_t nodeid
, uint64_t nlookup
)
1282 if (nodeid
== FUSE_ROOT_ID
)
1284 pthread_mutex_lock(&f
->lock
);
1285 node
= get_node(f
, nodeid
);
1288 * Node may still be locked due to interrupt idiocy in open,
1289 * create and opendir
1291 while (node
->nlookup
== nlookup
&& node
->treelock
) {
1292 struct lock_queue_element qe
= {
1296 debug_path(f
, "QUEUE PATH (forget)", nodeid
, NULL
, false);
1300 pthread_cond_wait(&qe
.cond
, &f
->lock
);
1301 } while (node
->nlookup
== nlookup
&& node
->treelock
);
1303 dequeue_path(f
, &qe
);
1304 debug_path(f
, "DEQUEUE_PATH (forget)", nodeid
, NULL
, false);
1307 assert(node
->nlookup
>= nlookup
);
1308 node
->nlookup
-= nlookup
;
1309 if (!node
->nlookup
) {
1310 unref_node(f
, node
);
1311 } else if (lru_enabled(f
) && node
->nlookup
== 1) {
1312 set_forget_time(f
, node
);
1314 pthread_mutex_unlock(&f
->lock
);
1317 static void unlink_node(struct fuse
*f
, struct node
*node
)
1319 if (f
->conf
.remember
) {
1320 assert(node
->nlookup
> 1);
1323 unhash_name(f
, node
);
1326 static void remove_node(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
1330 pthread_mutex_lock(&f
->lock
);
1331 node
= lookup_node(f
, dir
, name
);
1333 unlink_node(f
, node
);
1334 pthread_mutex_unlock(&f
->lock
);
1337 static int rename_node(struct fuse
*f
, fuse_ino_t olddir
, const char *oldname
,
1338 fuse_ino_t newdir
, const char *newname
, int hide
)
1341 struct node
*newnode
;
1344 pthread_mutex_lock(&f
->lock
);
1345 node
= lookup_node(f
, olddir
, oldname
);
1346 newnode
= lookup_node(f
, newdir
, newname
);
1350 if (newnode
!= NULL
) {
1352 fprintf(stderr
, "fuse: hidden file got created during hiding\n");
1356 unlink_node(f
, newnode
);
1359 unhash_name(f
, node
);
1360 if (hash_name(f
, node
, newdir
, newname
) == -1) {
1366 node
->is_hidden
= 1;
1369 pthread_mutex_unlock(&f
->lock
);
1373 static void set_stat(struct fuse
*f
, fuse_ino_t nodeid
, struct stat
*stbuf
)
1375 if (!f
->conf
.use_ino
)
1376 stbuf
->st_ino
= nodeid
;
1377 if (f
->conf
.set_mode
)
1378 stbuf
->st_mode
= (stbuf
->st_mode
& S_IFMT
) |
1379 (0777 & ~f
->conf
.umask
);
1380 if (f
->conf
.set_uid
)
1381 stbuf
->st_uid
= f
->conf
.uid
;
1382 if (f
->conf
.set_gid
)
1383 stbuf
->st_gid
= f
->conf
.gid
;
1386 static struct fuse
*req_fuse(fuse_req_t req
)
1388 return (struct fuse
*) fuse_req_userdata(req
);
1391 static void fuse_intr_sighandler(int sig
)
1397 struct fuse_intr_data
{
1399 pthread_cond_t cond
;
1403 static void fuse_interrupt(fuse_req_t req
, void *d_
)
1405 struct fuse_intr_data
*d
= d_
;
1406 struct fuse
*f
= req_fuse(req
);
1408 if (d
->id
== pthread_self())
1411 pthread_mutex_lock(&f
->lock
);
1412 while (!d
->finished
) {
1414 struct timespec timeout
;
1416 pthread_kill(d
->id
, f
->conf
.intr_signal
);
1417 gettimeofday(&now
, NULL
);
1418 timeout
.tv_sec
= now
.tv_sec
+ 1;
1419 timeout
.tv_nsec
= now
.tv_usec
* 1000;
1420 pthread_cond_timedwait(&d
->cond
, &f
->lock
, &timeout
);
1422 pthread_mutex_unlock(&f
->lock
);
1425 static void fuse_do_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
1426 struct fuse_intr_data
*d
)
1428 pthread_mutex_lock(&f
->lock
);
1430 pthread_cond_broadcast(&d
->cond
);
1431 pthread_mutex_unlock(&f
->lock
);
1432 fuse_req_interrupt_func(req
, NULL
, NULL
);
1433 pthread_cond_destroy(&d
->cond
);
1436 static void fuse_do_prepare_interrupt(fuse_req_t req
, struct fuse_intr_data
*d
)
1438 d
->id
= pthread_self();
1439 pthread_cond_init(&d
->cond
, NULL
);
1441 fuse_req_interrupt_func(req
, fuse_interrupt
, d
);
1444 static inline void fuse_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
1445 struct fuse_intr_data
*d
)
1448 fuse_do_finish_interrupt(f
, req
, d
);
1451 static inline void fuse_prepare_interrupt(struct fuse
*f
, fuse_req_t req
,
1452 struct fuse_intr_data
*d
)
1455 fuse_do_prepare_interrupt(req
, d
);
1458 int fuse_fs_getattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
)
1460 fuse_get_context()->private_data
= fs
->user_data
;
1461 if (fs
->op
.getattr
) {
1463 fprintf(stderr
, "getattr %s\n", path
);
1465 return fs
->op
.getattr(path
, buf
);
1471 int fuse_fs_fgetattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
,
1472 struct fuse_file_info
*fi
)
1474 fuse_get_context()->private_data
= fs
->user_data
;
1475 if (fs
->op
.fgetattr
) {
1477 fprintf(stderr
, "fgetattr[%llu] %s\n",
1478 (unsigned long long) fi
->fh
, path
);
1480 return fs
->op
.fgetattr(path
, buf
, fi
);
1481 } else if (path
&& fs
->op
.getattr
) {
1483 fprintf(stderr
, "getattr %s\n", path
);
1485 return fs
->op
.getattr(path
, buf
);
1491 int fuse_fs_rename(struct fuse_fs
*fs
, const char *oldpath
,
1492 const char *newpath
)
1494 fuse_get_context()->private_data
= fs
->user_data
;
1495 if (fs
->op
.rename
) {
1497 fprintf(stderr
, "rename %s %s\n", oldpath
, newpath
);
1499 return fs
->op
.rename(oldpath
, newpath
);
1505 int fuse_fs_unlink(struct fuse_fs
*fs
, const char *path
)
1507 fuse_get_context()->private_data
= fs
->user_data
;
1508 if (fs
->op
.unlink
) {
1510 fprintf(stderr
, "unlink %s\n", path
);
1512 return fs
->op
.unlink(path
);
1518 int fuse_fs_rmdir(struct fuse_fs
*fs
, const char *path
)
1520 fuse_get_context()->private_data
= fs
->user_data
;
1523 fprintf(stderr
, "rmdir %s\n", path
);
1525 return fs
->op
.rmdir(path
);
1531 int fuse_fs_symlink(struct fuse_fs
*fs
, const char *linkname
, const char *path
)
1533 fuse_get_context()->private_data
= fs
->user_data
;
1534 if (fs
->op
.symlink
) {
1536 fprintf(stderr
, "symlink %s %s\n", linkname
, path
);
1538 return fs
->op
.symlink(linkname
, path
);
1544 int fuse_fs_link(struct fuse_fs
*fs
, const char *oldpath
, const char *newpath
)
1546 fuse_get_context()->private_data
= fs
->user_data
;
1549 fprintf(stderr
, "link %s %s\n", oldpath
, newpath
);
1551 return fs
->op
.link(oldpath
, newpath
);
1557 int fuse_fs_release(struct fuse_fs
*fs
, const char *path
,
1558 struct fuse_file_info
*fi
)
1560 fuse_get_context()->private_data
= fs
->user_data
;
1561 if (fs
->op
.release
) {
1563 fprintf(stderr
, "release%s[%llu] flags: 0x%x\n",
1564 fi
->flush
? "+flush" : "",
1565 (unsigned long long) fi
->fh
, fi
->flags
);
1567 return fs
->op
.release(path
, fi
);
1573 int fuse_fs_opendir(struct fuse_fs
*fs
, const char *path
,
1574 struct fuse_file_info
*fi
)
1576 fuse_get_context()->private_data
= fs
->user_data
;
1577 if (fs
->op
.opendir
) {
1581 fprintf(stderr
, "opendir flags: 0x%x %s\n", fi
->flags
,
1584 err
= fs
->op
.opendir(path
, fi
);
1586 if (fs
->debug
&& !err
)
1587 fprintf(stderr
, " opendir[%lli] flags: 0x%x %s\n",
1588 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1596 int fuse_fs_open(struct fuse_fs
*fs
, const char *path
,
1597 struct fuse_file_info
*fi
)
1599 fuse_get_context()->private_data
= fs
->user_data
;
1604 fprintf(stderr
, "open flags: 0x%x %s\n", fi
->flags
,
1607 err
= fs
->op
.open(path
, fi
);
1609 if (fs
->debug
&& !err
)
1610 fprintf(stderr
, " open[%lli] flags: 0x%x %s\n",
1611 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1619 static void fuse_free_buf(struct fuse_bufvec
*buf
)
1624 for (i
= 0; i
< buf
->count
; i
++)
1625 free(buf
->buf
[i
].mem
);
1630 int fuse_fs_read_buf(struct fuse_fs
*fs
, const char *path
,
1631 struct fuse_bufvec
**bufp
, size_t size
, off_t off
,
1632 struct fuse_file_info
*fi
)
1634 fuse_get_context()->private_data
= fs
->user_data
;
1635 if (fs
->op
.read
|| fs
->op
.read_buf
) {
1640 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1641 (unsigned long long) fi
->fh
,
1642 size
, (unsigned long long) off
, fi
->flags
);
1644 if (fs
->op
.read_buf
) {
1645 res
= fs
->op
.read_buf(path
, bufp
, size
, off
, fi
);
1647 struct fuse_bufvec
*buf
;
1650 buf
= malloc(sizeof(struct fuse_bufvec
));
1659 *buf
= FUSE_BUFVEC_INIT(size
);
1660 buf
->buf
[0].mem
= mem
;
1663 res
= fs
->op
.read(path
, mem
, size
, off
, fi
);
1665 buf
->buf
[0].size
= res
;
1668 if (fs
->debug
&& res
>= 0)
1669 fprintf(stderr
, " read[%llu] %zu bytes from %llu\n",
1670 (unsigned long long) fi
->fh
,
1671 fuse_buf_size(*bufp
),
1672 (unsigned long long) off
);
1673 if (res
>= 0 && fuse_buf_size(*bufp
) > (int) size
)
1674 fprintf(stderr
, "fuse: read too many bytes\n");
1685 int fuse_fs_read(struct fuse_fs
*fs
, const char *path
, char *mem
, size_t size
,
1686 off_t off
, struct fuse_file_info
*fi
)
1689 struct fuse_bufvec
*buf
= NULL
;
1691 res
= fuse_fs_read_buf(fs
, path
, &buf
, size
, off
, fi
);
1693 struct fuse_bufvec dst
= FUSE_BUFVEC_INIT(size
);
1695 dst
.buf
[0].mem
= mem
;
1696 res
= fuse_buf_copy(&dst
, buf
, 0);
1703 int fuse_fs_write_buf(struct fuse_fs
*fs
, const char *path
,
1704 struct fuse_bufvec
*buf
, off_t off
,
1705 struct fuse_file_info
*fi
)
1707 fuse_get_context()->private_data
= fs
->user_data
;
1708 if (fs
->op
.write_buf
|| fs
->op
.write
) {
1710 size_t size
= fuse_buf_size(buf
);
1712 assert(buf
->idx
== 0 && buf
->off
== 0);
1715 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1716 fi
->writepage
? "page" : "",
1717 (unsigned long long) fi
->fh
,
1719 (unsigned long long) off
,
1722 if (fs
->op
.write_buf
) {
1723 res
= fs
->op
.write_buf(path
, buf
, off
, fi
);
1726 struct fuse_buf
*flatbuf
;
1727 struct fuse_bufvec tmp
= FUSE_BUFVEC_INIT(size
);
1729 if (buf
->count
== 1 &&
1730 !(buf
->buf
[0].flags
& FUSE_BUF_IS_FD
)) {
1731 flatbuf
= &buf
->buf
[0];
1738 tmp
.buf
[0].mem
= mem
;
1739 res
= fuse_buf_copy(&tmp
, buf
, 0);
1743 tmp
.buf
[0].size
= res
;
1744 flatbuf
= &tmp
.buf
[0];
1747 res
= fs
->op
.write(path
, flatbuf
->mem
, flatbuf
->size
,
1753 if (fs
->debug
&& res
>= 0)
1754 fprintf(stderr
, " write%s[%llu] %u bytes to %llu\n",
1755 fi
->writepage
? "page" : "",
1756 (unsigned long long) fi
->fh
, res
,
1757 (unsigned long long) off
);
1758 if (res
> (int) size
)
1759 fprintf(stderr
, "fuse: wrote too many bytes\n");
1767 int fuse_fs_write(struct fuse_fs
*fs
, const char *path
, const char *mem
,
1768 size_t size
, off_t off
, struct fuse_file_info
*fi
)
1770 struct fuse_bufvec bufv
= FUSE_BUFVEC_INIT(size
);
1772 bufv
.buf
[0].mem
= (void *) mem
;
1774 return fuse_fs_write_buf(fs
, path
, &bufv
, off
, fi
);
1777 int fuse_fs_fsync(struct fuse_fs
*fs
, const char *path
, int datasync
,
1778 struct fuse_file_info
*fi
)
1780 fuse_get_context()->private_data
= fs
->user_data
;
1783 fprintf(stderr
, "fsync[%llu] datasync: %i\n",
1784 (unsigned long long) fi
->fh
, datasync
);
1786 return fs
->op
.fsync(path
, datasync
, fi
);
1792 int fuse_fs_fsyncdir(struct fuse_fs
*fs
, const char *path
, int datasync
,
1793 struct fuse_file_info
*fi
)
1795 fuse_get_context()->private_data
= fs
->user_data
;
1796 if (fs
->op
.fsyncdir
) {
1798 fprintf(stderr
, "fsyncdir[%llu] datasync: %i\n",
1799 (unsigned long long) fi
->fh
, datasync
);
1801 return fs
->op
.fsyncdir(path
, datasync
, fi
);
1807 int fuse_fs_flush(struct fuse_fs
*fs
, const char *path
,
1808 struct fuse_file_info
*fi
)
1810 fuse_get_context()->private_data
= fs
->user_data
;
1813 fprintf(stderr
, "flush[%llu]\n",
1814 (unsigned long long) fi
->fh
);
1816 return fs
->op
.flush(path
, fi
);
1822 int fuse_fs_statfs(struct fuse_fs
*fs
, const char *path
, struct statvfs
*buf
)
1824 fuse_get_context()->private_data
= fs
->user_data
;
1825 if (fs
->op
.statfs
) {
1827 fprintf(stderr
, "statfs %s\n", path
);
1829 return fs
->op
.statfs(path
, buf
);
1831 buf
->f_namemax
= 255;
1837 int fuse_fs_releasedir(struct fuse_fs
*fs
, const char *path
,
1838 struct fuse_file_info
*fi
)
1840 fuse_get_context()->private_data
= fs
->user_data
;
1841 if (fs
->op
.releasedir
) {
1843 fprintf(stderr
, "releasedir[%llu] flags: 0x%x\n",
1844 (unsigned long long) fi
->fh
, fi
->flags
);
1846 return fs
->op
.releasedir(path
, fi
);
1852 int fuse_fs_readdir(struct fuse_fs
*fs
, const char *path
, void *buf
,
1853 fuse_fill_dir_t filler
, off_t off
,
1854 struct fuse_file_info
*fi
)
1856 fuse_get_context()->private_data
= fs
->user_data
;
1857 if (fs
->op
.readdir
) {
1859 fprintf(stderr
, "readdir[%llu] from %llu\n",
1860 (unsigned long long) fi
->fh
,
1861 (unsigned long long) off
);
1863 return fs
->op
.readdir(path
, buf
, filler
, off
, fi
);
1869 int fuse_fs_create(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
1870 struct fuse_file_info
*fi
)
1872 fuse_get_context()->private_data
= fs
->user_data
;
1873 if (fs
->op
.create
) {
1878 "create flags: 0x%x %s 0%o umask=0%03o\n",
1879 fi
->flags
, path
, mode
,
1880 fuse_get_context()->umask
);
1882 err
= fs
->op
.create(path
, mode
, fi
);
1884 if (fs
->debug
&& !err
)
1885 fprintf(stderr
, " create[%llu] flags: 0x%x %s\n",
1886 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1894 int fuse_fs_lock(struct fuse_fs
*fs
, const char *path
,
1895 struct fuse_file_info
*fi
, int cmd
, struct flock
*lock
)
1897 fuse_get_context()->private_data
= fs
->user_data
;
1900 fprintf(stderr
, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
1901 (unsigned long long) fi
->fh
,
1902 (cmd
== F_GETLK
? "F_GETLK" :
1903 (cmd
== F_SETLK
? "F_SETLK" :
1904 (cmd
== F_SETLKW
? "F_SETLKW" : "???"))),
1905 (lock
->l_type
== F_RDLCK
? "F_RDLCK" :
1906 (lock
->l_type
== F_WRLCK
? "F_WRLCK" :
1907 (lock
->l_type
== F_UNLCK
? "F_UNLCK" :
1909 (unsigned long long) lock
->l_start
,
1910 (unsigned long long) lock
->l_len
,
1911 (unsigned long long) lock
->l_pid
);
1913 return fs
->op
.lock(path
, fi
, cmd
, lock
);
1919 int fuse_fs_flock(struct fuse_fs
*fs
, const char *path
,
1920 struct fuse_file_info
*fi
, int op
)
1922 fuse_get_context()->private_data
= fs
->user_data
;
1925 int xop
= op
& ~LOCK_NB
;
1927 fprintf(stderr
, "lock[%llu] %s%s\n",
1928 (unsigned long long) fi
->fh
,
1929 xop
== LOCK_SH
? "LOCK_SH" :
1930 (xop
== LOCK_EX
? "LOCK_EX" :
1931 (xop
== LOCK_UN
? "LOCK_UN" : "???")),
1932 (op
& LOCK_NB
) ? "|LOCK_NB" : "");
1934 return fs
->op
.flock(path
, fi
, op
);
1940 int fuse_fs_chown(struct fuse_fs
*fs
, const char *path
, uid_t uid
, gid_t gid
)
1942 fuse_get_context()->private_data
= fs
->user_data
;
1945 fprintf(stderr
, "chown %s %lu %lu\n", path
,
1946 (unsigned long) uid
, (unsigned long) gid
);
1948 return fs
->op
.chown(path
, uid
, gid
);
1954 int fuse_fs_truncate(struct fuse_fs
*fs
, const char *path
, off_t size
)
1956 fuse_get_context()->private_data
= fs
->user_data
;
1957 if (fs
->op
.truncate
) {
1959 fprintf(stderr
, "truncate %s %llu\n", path
,
1960 (unsigned long long) size
);
1962 return fs
->op
.truncate(path
, size
);
1968 int fuse_fs_ftruncate(struct fuse_fs
*fs
, const char *path
, off_t size
,
1969 struct fuse_file_info
*fi
)
1971 fuse_get_context()->private_data
= fs
->user_data
;
1972 if (fs
->op
.ftruncate
) {
1974 fprintf(stderr
, "ftruncate[%llu] %llu\n",
1975 (unsigned long long) fi
->fh
,
1976 (unsigned long long) size
);
1978 return fs
->op
.ftruncate(path
, size
, fi
);
1979 } else if (path
&& fs
->op
.truncate
) {
1981 fprintf(stderr
, "truncate %s %llu\n", path
,
1982 (unsigned long long) size
);
1984 return fs
->op
.truncate(path
, size
);
1990 int fuse_fs_utimens(struct fuse_fs
*fs
, const char *path
,
1991 const struct timespec tv
[2])
1993 fuse_get_context()->private_data
= fs
->user_data
;
1994 if (fs
->op
.utimens
) {
1996 fprintf(stderr
, "utimens %s %li.%09lu %li.%09lu\n",
1997 path
, tv
[0].tv_sec
, tv
[0].tv_nsec
,
1998 tv
[1].tv_sec
, tv
[1].tv_nsec
);
2000 return fs
->op
.utimens(path
, tv
);
2006 int fuse_fs_access(struct fuse_fs
*fs
, const char *path
, int mask
)
2008 fuse_get_context()->private_data
= fs
->user_data
;
2009 if (fs
->op
.access
) {
2011 fprintf(stderr
, "access %s 0%o\n", path
, mask
);
2013 return fs
->op
.access(path
, mask
);
2019 int fuse_fs_readlink(struct fuse_fs
*fs
, const char *path
, char *buf
,
2022 fuse_get_context()->private_data
= fs
->user_data
;
2023 if (fs
->op
.readlink
) {
2025 fprintf(stderr
, "readlink %s %lu\n", path
,
2026 (unsigned long) len
);
2028 return fs
->op
.readlink(path
, buf
, len
);
2034 int fuse_fs_mknod(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
2037 fuse_get_context()->private_data
= fs
->user_data
;
2040 fprintf(stderr
, "mknod %s 0%o 0x%llx umask=0%03o\n",
2041 path
, mode
, (unsigned long long) rdev
,
2042 fuse_get_context()->umask
);
2044 return fs
->op
.mknod(path
, mode
, rdev
);
2050 int fuse_fs_mkdir(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
2052 fuse_get_context()->private_data
= fs
->user_data
;
2055 fprintf(stderr
, "mkdir %s 0%o umask=0%03o\n",
2056 path
, mode
, fuse_get_context()->umask
);
2058 return fs
->op
.mkdir(path
, mode
);
2064 int fuse_fs_setxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
2065 const char *value
, size_t size
, int flags
)
2067 fuse_get_context()->private_data
= fs
->user_data
;
2068 if (fs
->op
.setxattr
) {
2070 fprintf(stderr
, "setxattr %s %s %lu 0x%x\n",
2071 path
, name
, (unsigned long) size
, flags
);
2073 return fs
->op
.setxattr(path
, name
, value
, size
, flags
);
2079 int fuse_fs_getxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
2080 char *value
, size_t size
)
2082 fuse_get_context()->private_data
= fs
->user_data
;
2083 if (fs
->op
.getxattr
) {
2085 fprintf(stderr
, "getxattr %s %s %lu\n",
2086 path
, name
, (unsigned long) size
);
2088 return fs
->op
.getxattr(path
, name
, value
, size
);
2094 int fuse_fs_listxattr(struct fuse_fs
*fs
, const char *path
, char *list
,
2097 fuse_get_context()->private_data
= fs
->user_data
;
2098 if (fs
->op
.listxattr
) {
2100 fprintf(stderr
, "listxattr %s %lu\n",
2101 path
, (unsigned long) size
);
2103 return fs
->op
.listxattr(path
, list
, size
);
2109 int fuse_fs_bmap(struct fuse_fs
*fs
, const char *path
, size_t blocksize
,
2112 fuse_get_context()->private_data
= fs
->user_data
;
2115 fprintf(stderr
, "bmap %s blocksize: %lu index: %llu\n",
2116 path
, (unsigned long) blocksize
,
2117 (unsigned long long) *idx
);
2119 return fs
->op
.bmap(path
, blocksize
, idx
);
2125 int fuse_fs_removexattr(struct fuse_fs
*fs
, const char *path
, const char *name
)
2127 fuse_get_context()->private_data
= fs
->user_data
;
2128 if (fs
->op
.removexattr
) {
2130 fprintf(stderr
, "removexattr %s %s\n", path
, name
);
2132 return fs
->op
.removexattr(path
, name
);
2138 int fuse_fs_ioctl(struct fuse_fs
*fs
, const char *path
, int cmd
, void *arg
,
2139 struct fuse_file_info
*fi
, unsigned int flags
, void *data
)
2141 fuse_get_context()->private_data
= fs
->user_data
;
2144 fprintf(stderr
, "ioctl[%llu] 0x%x flags: 0x%x\n",
2145 (unsigned long long) fi
->fh
, cmd
, flags
);
2147 return fs
->op
.ioctl(path
, cmd
, arg
, fi
, flags
, data
);
2152 int fuse_fs_poll(struct fuse_fs
*fs
, const char *path
,
2153 struct fuse_file_info
*fi
, struct fuse_pollhandle
*ph
,
2156 fuse_get_context()->private_data
= fs
->user_data
;
2161 fprintf(stderr
, "poll[%llu] ph: %p, events 0x%x\n",
2162 (unsigned long long) fi
->fh
, ph
,
2165 res
= fs
->op
.poll(path
, fi
, ph
, reventsp
);
2167 if (fs
->debug
&& !res
)
2168 fprintf(stderr
, " poll[%llu] revents: 0x%x\n",
2169 (unsigned long long) fi
->fh
, *reventsp
);
2176 int fuse_fs_fallocate(struct fuse_fs
*fs
, const char *path
, int mode
,
2177 off_t offset
, off_t length
, struct fuse_file_info
*fi
)
2179 fuse_get_context()->private_data
= fs
->user_data
;
2180 if (fs
->op
.fallocate
) {
2182 fprintf(stderr
, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2185 (unsigned long long) offset
,
2186 (unsigned long long) length
);
2188 return fs
->op
.fallocate(path
, mode
, offset
, length
, fi
);
2193 static int is_open(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
2197 pthread_mutex_lock(&f
->lock
);
2198 node
= lookup_node(f
, dir
, name
);
2199 if (node
&& node
->open_count
> 0)
2201 pthread_mutex_unlock(&f
->lock
);
2205 static char *hidden_name(struct fuse
*f
, fuse_ino_t dir
, const char *oldname
,
2206 char *newname
, size_t bufsize
)
2210 struct node
*newnode
;
2216 pthread_mutex_lock(&f
->lock
);
2217 node
= lookup_node(f
, dir
, oldname
);
2219 pthread_mutex_unlock(&f
->lock
);
2224 snprintf(newname
, bufsize
, ".fuse_hidden%08x%08x",
2225 (unsigned int) node
->nodeid
, f
->hidectr
);
2226 newnode
= lookup_node(f
, dir
, newname
);
2229 res
= try_get_path(f
, dir
, newname
, &newpath
, NULL
, false);
2230 pthread_mutex_unlock(&f
->lock
);
2234 res
= fuse_fs_getattr(f
->fs
, newpath
, &buf
);
2239 } while(res
== 0 && --failctr
);
2244 static int hide_node(struct fuse
*f
, const char *oldpath
,
2245 fuse_ino_t dir
, const char *oldname
)
2251 newpath
= hidden_name(f
, dir
, oldname
, newname
, sizeof(newname
));
2253 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
2255 err
= rename_node(f
, dir
, oldname
, dir
, newname
, 1);
2261 static int mtime_eq(const struct stat
*stbuf
, const struct timespec
*ts
)
2263 return stbuf
->st_mtime
== ts
->tv_sec
&&
2264 ST_MTIM_NSEC(stbuf
) == ts
->tv_nsec
;
2267 #ifndef CLOCK_MONOTONIC
2268 #define CLOCK_MONOTONIC CLOCK_REALTIME
2271 static void curr_time(struct timespec
*now
)
2273 static clockid_t clockid
= CLOCK_MONOTONIC
;
2274 int res
= clock_gettime(clockid
, now
);
2275 if (res
== -1 && errno
== EINVAL
) {
2276 clockid
= CLOCK_REALTIME
;
2277 res
= clock_gettime(clockid
, now
);
2280 perror("fuse: clock_gettime");
2285 static void update_stat(struct node
*node
, const struct stat
*stbuf
)
2287 if (node
->cache_valid
&& (!mtime_eq(stbuf
, &node
->mtime
) ||
2288 stbuf
->st_size
!= node
->size
))
2289 node
->cache_valid
= 0;
2290 node
->mtime
.tv_sec
= stbuf
->st_mtime
;
2291 node
->mtime
.tv_nsec
= ST_MTIM_NSEC(stbuf
);
2292 node
->size
= stbuf
->st_size
;
2293 curr_time(&node
->stat_updated
);
2296 static int lookup_path(struct fuse
*f
, fuse_ino_t nodeid
,
2297 const char *name
, const char *path
,
2298 struct fuse_entry_param
*e
, struct fuse_file_info
*fi
)
2302 memset(e
, 0, sizeof(struct fuse_entry_param
));
2304 res
= fuse_fs_fgetattr(f
->fs
, path
, &e
->attr
, fi
);
2306 res
= fuse_fs_getattr(f
->fs
, path
, &e
->attr
);
2310 node
= find_node(f
, nodeid
, name
);
2314 e
->ino
= node
->nodeid
;
2315 e
->generation
= node
->generation
;
2316 e
->entry_timeout
= f
->conf
.entry_timeout
;
2317 e
->attr_timeout
= f
->conf
.attr_timeout
;
2318 if (f
->conf
.auto_cache
) {
2319 pthread_mutex_lock(&f
->lock
);
2320 update_stat(node
, &e
->attr
);
2321 pthread_mutex_unlock(&f
->lock
);
2323 set_stat(f
, e
->ino
, &e
->attr
);
2325 fprintf(stderr
, " NODEID: %llu\n",
2326 (unsigned long long) e
->ino
);
2332 static struct fuse_context_i
*fuse_get_context_internal(void)
2334 return (struct fuse_context_i
*) pthread_getspecific(fuse_context_key
);
2337 static struct fuse_context_i
*fuse_create_context(struct fuse
*f
)
2339 struct fuse_context_i
*c
= fuse_get_context_internal();
2341 c
= (struct fuse_context_i
*)
2342 calloc(1, sizeof(struct fuse_context_i
));
2344 /* This is hard to deal with properly, so just
2345 abort. If memory is so low that the
2346 context cannot be allocated, there's not
2347 much hope for the filesystem anyway */
2348 fprintf(stderr
, "fuse: failed to allocate thread specific data\n");
2351 pthread_setspecific(fuse_context_key
, c
);
2353 memset(c
, 0, sizeof(*c
));
2360 static void fuse_freecontext(void *data
)
2365 static int fuse_create_context_key(void)
2368 pthread_mutex_lock(&fuse_context_lock
);
2369 if (!fuse_context_ref
) {
2370 err
= pthread_key_create(&fuse_context_key
, fuse_freecontext
);
2372 fprintf(stderr
, "fuse: failed to create thread specific key: %s\n",
2374 pthread_mutex_unlock(&fuse_context_lock
);
2379 pthread_mutex_unlock(&fuse_context_lock
);
2383 static void fuse_delete_context_key(void)
2385 pthread_mutex_lock(&fuse_context_lock
);
2387 if (!fuse_context_ref
) {
2388 free(pthread_getspecific(fuse_context_key
));
2389 pthread_key_delete(fuse_context_key
);
2391 pthread_mutex_unlock(&fuse_context_lock
);
2394 static struct fuse
*req_fuse_prepare(fuse_req_t req
)
2396 struct fuse_context_i
*c
= fuse_create_context(req_fuse(req
));
2397 const struct fuse_ctx
*ctx
= fuse_req_ctx(req
);
2399 c
->ctx
.uid
= ctx
->uid
;
2400 c
->ctx
.gid
= ctx
->gid
;
2401 c
->ctx
.pid
= ctx
->pid
;
2402 c
->ctx
.umask
= ctx
->umask
;
2406 static inline void reply_err(fuse_req_t req
, int err
)
2408 /* fuse_reply_err() uses non-negated errno values */
2409 fuse_reply_err(req
, -err
);
2412 static void reply_entry(fuse_req_t req
, const struct fuse_entry_param
*e
,
2416 struct fuse
*f
= req_fuse(req
);
2417 if (fuse_reply_entry(req
, e
) == -ENOENT
) {
2418 /* Skip forget for negative result */
2420 forget_node(f
, e
->ino
, 1);
2423 reply_err(req
, err
);
2426 void fuse_fs_init(struct fuse_fs
*fs
, struct fuse_conn_info
*conn
)
2428 fuse_get_context()->private_data
= fs
->user_data
;
2429 if (!fs
->op
.write_buf
)
2430 conn
->want
&= ~FUSE_CAP_SPLICE_READ
;
2432 conn
->want
&= ~FUSE_CAP_POSIX_LOCKS
;
2434 conn
->want
&= ~FUSE_CAP_FLOCK_LOCKS
;
2436 fs
->user_data
= fs
->op
.init(conn
);
2439 static void fuse_lib_init(void *data
, struct fuse_conn_info
*conn
)
2441 struct fuse
*f
= (struct fuse
*) data
;
2443 fuse_create_context(f
);
2444 conn
->want
|= FUSE_CAP_EXPORT_SUPPORT
;
2445 fuse_fs_init(f
->fs
, conn
);
2448 void fuse_fs_destroy(struct fuse_fs
*fs
)
2450 fuse_get_context()->private_data
= fs
->user_data
;
2452 fs
->op
.destroy(fs
->user_data
);
2454 fuse_put_module(fs
->m
);
2458 static void fuse_lib_destroy(void *data
)
2460 struct fuse
*f
= (struct fuse
*) data
;
2462 fuse_create_context(f
);
2463 fuse_fs_destroy(f
->fs
);
2467 static void fuse_lib_lookup(fuse_req_t req
, fuse_ino_t parent
,
2470 struct fuse
*f
= req_fuse_prepare(req
);
2471 struct fuse_entry_param e
;
2474 struct node
*dot
= NULL
;
2476 if (name
[0] == '.') {
2477 int len
= strlen(name
);
2479 if (len
== 1 || (name
[1] == '.' && len
== 2)) {
2480 pthread_mutex_lock(&f
->lock
);
2483 fprintf(stderr
, "LOOKUP-DOT\n");
2484 dot
= get_node_nocheck(f
, parent
);
2486 pthread_mutex_unlock(&f
->lock
);
2487 reply_entry(req
, &e
, -ESTALE
);
2493 fprintf(stderr
, "LOOKUP-DOTDOT\n");
2494 parent
= get_node(f
, parent
)->parent
->nodeid
;
2496 pthread_mutex_unlock(&f
->lock
);
2501 err
= get_path_name(f
, parent
, name
, &path
);
2503 struct fuse_intr_data d
;
2505 fprintf(stderr
, "LOOKUP %s\n", path
);
2506 fuse_prepare_interrupt(f
, req
, &d
);
2507 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2508 if (err
== -ENOENT
&& f
->conf
.negative_timeout
!= 0.0) {
2510 e
.entry_timeout
= f
->conf
.negative_timeout
;
2513 fuse_finish_interrupt(f
, req
, &d
);
2514 free_path(f
, parent
, path
);
2517 pthread_mutex_lock(&f
->lock
);
2519 pthread_mutex_unlock(&f
->lock
);
2521 reply_entry(req
, &e
, err
);
2524 static void do_forget(struct fuse
*f
, fuse_ino_t ino
, uint64_t nlookup
)
2527 fprintf(stderr
, "FORGET %llu/%llu\n", (unsigned long long)ino
,
2528 (unsigned long long) nlookup
);
2529 forget_node(f
, ino
, nlookup
);
2532 static void fuse_lib_forget(fuse_req_t req
, fuse_ino_t ino
,
2533 unsigned long nlookup
)
2535 do_forget(req_fuse(req
), ino
, nlookup
);
2536 fuse_reply_none(req
);
2539 static void fuse_lib_forget_multi(fuse_req_t req
, size_t count
,
2540 struct fuse_forget_data
*forgets
)
2542 struct fuse
*f
= req_fuse(req
);
2545 for (i
= 0; i
< count
; i
++)
2546 do_forget(f
, forgets
[i
].ino
, forgets
[i
].nlookup
);
2548 fuse_reply_none(req
);
2552 static void fuse_lib_getattr(fuse_req_t req
, fuse_ino_t ino
,
2553 struct fuse_file_info
*fi
)
2555 struct fuse
*f
= req_fuse_prepare(req
);
2560 memset(&buf
, 0, sizeof(buf
));
2562 if (fi
!= NULL
&& f
->fs
->op
.fgetattr
)
2563 err
= get_path_nullok(f
, ino
, &path
);
2565 err
= get_path(f
, ino
, &path
);
2567 struct fuse_intr_data d
;
2568 fuse_prepare_interrupt(f
, req
, &d
);
2570 err
= fuse_fs_fgetattr(f
->fs
, path
, &buf
, fi
);
2572 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
2573 fuse_finish_interrupt(f
, req
, &d
);
2574 free_path(f
, ino
, path
);
2579 pthread_mutex_lock(&f
->lock
);
2580 node
= get_node(f
, ino
);
2581 if (node
->is_hidden
&& buf
.st_nlink
> 0)
2583 if (f
->conf
.auto_cache
)
2584 update_stat(node
, &buf
);
2585 pthread_mutex_unlock(&f
->lock
);
2586 set_stat(f
, ino
, &buf
);
2587 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
2589 reply_err(req
, err
);
2592 int fuse_fs_chmod(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
2594 fuse_get_context()->private_data
= fs
->user_data
;
2596 return fs
->op
.chmod(path
, mode
);
2601 static void fuse_lib_setattr(fuse_req_t req
, fuse_ino_t ino
, struct stat
*attr
,
2602 int valid
, struct fuse_file_info
*fi
)
2604 struct fuse
*f
= req_fuse_prepare(req
);
2609 if (valid
== FUSE_SET_ATTR_SIZE
&& fi
!= NULL
&&
2610 f
->fs
->op
.ftruncate
&& f
->fs
->op
.fgetattr
)
2611 err
= get_path_nullok(f
, ino
, &path
);
2613 err
= get_path(f
, ino
, &path
);
2615 struct fuse_intr_data d
;
2616 fuse_prepare_interrupt(f
, req
, &d
);
2618 if (!err
&& (valid
& FUSE_SET_ATTR_MODE
))
2619 err
= fuse_fs_chmod(f
->fs
, path
, attr
->st_mode
);
2620 if (!err
&& (valid
& (FUSE_SET_ATTR_UID
| FUSE_SET_ATTR_GID
))) {
2621 uid_t uid
= (valid
& FUSE_SET_ATTR_UID
) ?
2622 attr
->st_uid
: (uid_t
) -1;
2623 gid_t gid
= (valid
& FUSE_SET_ATTR_GID
) ?
2624 attr
->st_gid
: (gid_t
) -1;
2625 err
= fuse_fs_chown(f
->fs
, path
, uid
, gid
);
2627 if (!err
&& (valid
& FUSE_SET_ATTR_SIZE
)) {
2629 err
= fuse_fs_ftruncate(f
->fs
, path
,
2632 err
= fuse_fs_truncate(f
->fs
, path
,
2635 #ifdef HAVE_UTIMENSAT
2637 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
))) {
2638 struct timespec tv
[2];
2642 tv
[0].tv_nsec
= UTIME_OMIT
;
2643 tv
[1].tv_nsec
= UTIME_OMIT
;
2645 if (valid
& FUSE_SET_ATTR_ATIME_NOW
)
2646 tv
[0].tv_nsec
= UTIME_NOW
;
2647 else if (valid
& FUSE_SET_ATTR_ATIME
)
2648 tv
[0] = attr
->st_atim
;
2650 if (valid
& FUSE_SET_ATTR_MTIME_NOW
)
2651 tv
[1].tv_nsec
= UTIME_NOW
;
2652 else if (valid
& FUSE_SET_ATTR_MTIME
)
2653 tv
[1] = attr
->st_mtim
;
2655 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
2659 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) ==
2660 (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) {
2661 struct timespec tv
[2];
2662 tv
[0].tv_sec
= attr
->st_atime
;
2663 tv
[0].tv_nsec
= ST_ATIM_NSEC(attr
);
2664 tv
[1].tv_sec
= attr
->st_mtime
;
2665 tv
[1].tv_nsec
= ST_MTIM_NSEC(attr
);
2666 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
2670 err
= fuse_fs_fgetattr(f
->fs
, path
, &buf
, fi
);
2672 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
2674 fuse_finish_interrupt(f
, req
, &d
);
2675 free_path(f
, ino
, path
);
2678 if (f
->conf
.auto_cache
) {
2679 pthread_mutex_lock(&f
->lock
);
2680 update_stat(get_node(f
, ino
), &buf
);
2681 pthread_mutex_unlock(&f
->lock
);
2683 set_stat(f
, ino
, &buf
);
2684 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
2686 reply_err(req
, err
);
2689 static void fuse_lib_access(fuse_req_t req
, fuse_ino_t ino
, int mask
)
2691 struct fuse
*f
= req_fuse_prepare(req
);
2695 err
= get_path(f
, ino
, &path
);
2697 struct fuse_intr_data d
;
2699 fuse_prepare_interrupt(f
, req
, &d
);
2700 err
= fuse_fs_access(f
->fs
, path
, mask
);
2701 fuse_finish_interrupt(f
, req
, &d
);
2702 free_path(f
, ino
, path
);
2704 reply_err(req
, err
);
2707 static void fuse_lib_readlink(fuse_req_t req
, fuse_ino_t ino
)
2709 struct fuse
*f
= req_fuse_prepare(req
);
2710 char linkname
[PATH_MAX
+ 1];
2714 err
= get_path(f
, ino
, &path
);
2716 struct fuse_intr_data d
;
2717 fuse_prepare_interrupt(f
, req
, &d
);
2718 err
= fuse_fs_readlink(f
->fs
, path
, linkname
, sizeof(linkname
));
2719 fuse_finish_interrupt(f
, req
, &d
);
2720 free_path(f
, ino
, path
);
2723 linkname
[PATH_MAX
] = '\0';
2724 fuse_reply_readlink(req
, linkname
);
2726 reply_err(req
, err
);
2729 static void fuse_lib_mknod(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
2730 mode_t mode
, dev_t rdev
)
2732 struct fuse
*f
= req_fuse_prepare(req
);
2733 struct fuse_entry_param e
;
2737 err
= get_path_name(f
, parent
, name
, &path
);
2739 struct fuse_intr_data d
;
2741 fuse_prepare_interrupt(f
, req
, &d
);
2743 if (S_ISREG(mode
)) {
2744 struct fuse_file_info fi
;
2746 memset(&fi
, 0, sizeof(fi
));
2747 fi
.flags
= O_CREAT
| O_EXCL
| O_WRONLY
;
2748 err
= fuse_fs_create(f
->fs
, path
, mode
, &fi
);
2750 err
= lookup_path(f
, parent
, name
, path
, &e
,
2752 fuse_fs_release(f
->fs
, path
, &fi
);
2755 if (err
== -ENOSYS
) {
2756 err
= fuse_fs_mknod(f
->fs
, path
, mode
, rdev
);
2758 err
= lookup_path(f
, parent
, name
, path
, &e
,
2761 fuse_finish_interrupt(f
, req
, &d
);
2762 free_path(f
, parent
, path
);
2764 reply_entry(req
, &e
, err
);
2767 static void fuse_lib_mkdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
2770 struct fuse
*f
= req_fuse_prepare(req
);
2771 struct fuse_entry_param e
;
2775 err
= get_path_name(f
, parent
, name
, &path
);
2777 struct fuse_intr_data d
;
2779 fuse_prepare_interrupt(f
, req
, &d
);
2780 err
= fuse_fs_mkdir(f
->fs
, path
, mode
);
2782 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2783 fuse_finish_interrupt(f
, req
, &d
);
2784 free_path(f
, parent
, path
);
2786 reply_entry(req
, &e
, err
);
2789 static void fuse_lib_unlink(fuse_req_t req
, fuse_ino_t parent
,
2792 struct fuse
*f
= req_fuse_prepare(req
);
2797 err
= get_path_wrlock(f
, parent
, name
, &path
, &wnode
);
2799 struct fuse_intr_data d
;
2801 fuse_prepare_interrupt(f
, req
, &d
);
2802 if (!f
->conf
.hard_remove
&& is_open(f
, parent
, name
)) {
2803 err
= hide_node(f
, path
, parent
, name
);
2805 err
= fuse_fs_unlink(f
->fs
, path
);
2807 remove_node(f
, parent
, name
);
2809 fuse_finish_interrupt(f
, req
, &d
);
2810 free_path_wrlock(f
, parent
, wnode
, path
);
2812 reply_err(req
, err
);
2815 static void fuse_lib_rmdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
2817 struct fuse
*f
= req_fuse_prepare(req
);
2822 err
= get_path_wrlock(f
, parent
, name
, &path
, &wnode
);
2824 struct fuse_intr_data d
;
2826 fuse_prepare_interrupt(f
, req
, &d
);
2827 err
= fuse_fs_rmdir(f
->fs
, path
);
2828 fuse_finish_interrupt(f
, req
, &d
);
2830 remove_node(f
, parent
, name
);
2831 free_path_wrlock(f
, parent
, wnode
, path
);
2833 reply_err(req
, err
);
2836 static void fuse_lib_symlink(fuse_req_t req
, const char *linkname
,
2837 fuse_ino_t parent
, const char *name
)
2839 struct fuse
*f
= req_fuse_prepare(req
);
2840 struct fuse_entry_param e
;
2844 err
= get_path_name(f
, parent
, name
, &path
);
2846 struct fuse_intr_data d
;
2848 fuse_prepare_interrupt(f
, req
, &d
);
2849 err
= fuse_fs_symlink(f
->fs
, linkname
, path
);
2851 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2852 fuse_finish_interrupt(f
, req
, &d
);
2853 free_path(f
, parent
, path
);
2855 reply_entry(req
, &e
, err
);
2858 static void fuse_lib_rename(fuse_req_t req
, fuse_ino_t olddir
,
2859 const char *oldname
, fuse_ino_t newdir
,
2860 const char *newname
)
2862 struct fuse
*f
= req_fuse_prepare(req
);
2865 struct node
*wnode1
;
2866 struct node
*wnode2
;
2869 err
= get_path2(f
, olddir
, oldname
, newdir
, newname
,
2870 &oldpath
, &newpath
, &wnode1
, &wnode2
);
2872 struct fuse_intr_data d
;
2874 fuse_prepare_interrupt(f
, req
, &d
);
2875 if (!f
->conf
.hard_remove
&& is_open(f
, newdir
, newname
))
2876 err
= hide_node(f
, newpath
, newdir
, newname
);
2878 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
2880 err
= rename_node(f
, olddir
, oldname
, newdir
,
2883 fuse_finish_interrupt(f
, req
, &d
);
2884 free_path2(f
, olddir
, newdir
, wnode1
, wnode2
, oldpath
, newpath
);
2886 reply_err(req
, err
);
2889 static void fuse_lib_link(fuse_req_t req
, fuse_ino_t ino
, fuse_ino_t newparent
,
2890 const char *newname
)
2892 struct fuse
*f
= req_fuse_prepare(req
);
2893 struct fuse_entry_param e
;
2898 err
= get_path2(f
, ino
, NULL
, newparent
, newname
,
2899 &oldpath
, &newpath
, NULL
, NULL
);
2901 struct fuse_intr_data d
;
2903 fuse_prepare_interrupt(f
, req
, &d
);
2904 err
= fuse_fs_link(f
->fs
, oldpath
, newpath
);
2906 err
= lookup_path(f
, newparent
, newname
, newpath
,
2908 fuse_finish_interrupt(f
, req
, &d
);
2909 free_path2(f
, ino
, newparent
, NULL
, NULL
, oldpath
, newpath
);
2911 reply_entry(req
, &e
, err
);
2914 static void fuse_do_release(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
2915 struct fuse_file_info
*fi
)
2918 int unlink_hidden
= 0;
2920 fuse_fs_release(f
->fs
, path
, fi
);
2922 pthread_mutex_lock(&f
->lock
);
2923 node
= get_node(f
, ino
);
2924 assert(node
->open_count
> 0);
2926 if (node
->is_hidden
&& !node
->open_count
) {
2928 node
->is_hidden
= 0;
2930 pthread_mutex_unlock(&f
->lock
);
2934 fuse_fs_unlink(f
->fs
, path
);
2935 } else if (f
->conf
.nopath
) {
2938 if (get_path(f
, ino
, &unlinkpath
) == 0)
2939 fuse_fs_unlink(f
->fs
, unlinkpath
);
2941 free_path(f
, ino
, unlinkpath
);
2946 static void fuse_lib_create(fuse_req_t req
, fuse_ino_t parent
,
2947 const char *name
, mode_t mode
,
2948 struct fuse_file_info
*fi
)
2950 struct fuse
*f
= req_fuse_prepare(req
);
2951 struct fuse_intr_data d
;
2952 struct fuse_entry_param e
;
2956 err
= get_path_name(f
, parent
, name
, &path
);
2958 fuse_prepare_interrupt(f
, req
, &d
);
2959 err
= fuse_fs_create(f
->fs
, path
, mode
, fi
);
2961 err
= lookup_path(f
, parent
, name
, path
, &e
, fi
);
2963 fuse_fs_release(f
->fs
, path
, fi
);
2964 else if (!S_ISREG(e
.attr
.st_mode
)) {
2966 fuse_fs_release(f
->fs
, path
, fi
);
2967 forget_node(f
, e
.ino
, 1);
2969 if (f
->conf
.direct_io
)
2971 if (f
->conf
.kernel_cache
)
2976 fuse_finish_interrupt(f
, req
, &d
);
2979 pthread_mutex_lock(&f
->lock
);
2980 get_node(f
, e
.ino
)->open_count
++;
2981 pthread_mutex_unlock(&f
->lock
);
2982 if (fuse_reply_create(req
, &e
, fi
) == -ENOENT
) {
2983 /* The open syscall was interrupted, so it
2984 must be cancelled */
2985 fuse_do_release(f
, e
.ino
, path
, fi
);
2986 forget_node(f
, e
.ino
, 1);
2989 reply_err(req
, err
);
2992 free_path(f
, parent
, path
);
2995 static double diff_timespec(const struct timespec
*t1
,
2996 const struct timespec
*t2
)
2998 return (t1
->tv_sec
- t2
->tv_sec
) +
2999 ((double) t1
->tv_nsec
- (double) t2
->tv_nsec
) / 1000000000.0;
3002 static void open_auto_cache(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
3003 struct fuse_file_info
*fi
)
3007 pthread_mutex_lock(&f
->lock
);
3008 node
= get_node(f
, ino
);
3009 if (node
->cache_valid
) {
3010 struct timespec now
;
3013 if (diff_timespec(&now
, &node
->stat_updated
) >
3014 f
->conf
.ac_attr_timeout
) {
3017 pthread_mutex_unlock(&f
->lock
);
3018 err
= fuse_fs_fgetattr(f
->fs
, path
, &stbuf
, fi
);
3019 pthread_mutex_lock(&f
->lock
);
3021 update_stat(node
, &stbuf
);
3023 node
->cache_valid
= 0;
3026 if (node
->cache_valid
)
3029 node
->cache_valid
= 1;
3030 pthread_mutex_unlock(&f
->lock
);
3033 static void fuse_lib_open(fuse_req_t req
, fuse_ino_t ino
,
3034 struct fuse_file_info
*fi
)
3036 struct fuse
*f
= req_fuse_prepare(req
);
3037 struct fuse_intr_data d
;
3041 err
= get_path(f
, ino
, &path
);
3043 fuse_prepare_interrupt(f
, req
, &d
);
3044 err
= fuse_fs_open(f
->fs
, path
, fi
);
3046 if (f
->conf
.direct_io
)
3048 if (f
->conf
.kernel_cache
)
3051 if (f
->conf
.auto_cache
)
3052 open_auto_cache(f
, ino
, path
, fi
);
3054 fuse_finish_interrupt(f
, req
, &d
);
3057 pthread_mutex_lock(&f
->lock
);
3058 get_node(f
, ino
)->open_count
++;
3059 pthread_mutex_unlock(&f
->lock
);
3060 if (fuse_reply_open(req
, fi
) == -ENOENT
) {
3061 /* The open syscall was interrupted, so it
3062 must be cancelled */
3063 fuse_do_release(f
, ino
, path
, fi
);
3066 reply_err(req
, err
);
3068 free_path(f
, ino
, path
);
3071 static void fuse_lib_read(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
3072 off_t off
, struct fuse_file_info
*fi
)
3074 struct fuse
*f
= req_fuse_prepare(req
);
3075 struct fuse_bufvec
*buf
= NULL
;
3079 res
= get_path_nullok(f
, ino
, &path
);
3081 struct fuse_intr_data d
;
3083 fuse_prepare_interrupt(f
, req
, &d
);
3084 res
= fuse_fs_read_buf(f
->fs
, path
, &buf
, size
, off
, fi
);
3085 fuse_finish_interrupt(f
, req
, &d
);
3086 free_path(f
, ino
, path
);
3090 fuse_reply_data(req
, buf
, FUSE_BUF_SPLICE_MOVE
);
3092 reply_err(req
, res
);
3097 static void fuse_lib_write_buf(fuse_req_t req
, fuse_ino_t ino
,
3098 struct fuse_bufvec
*buf
, off_t off
,
3099 struct fuse_file_info
*fi
)
3101 struct fuse
*f
= req_fuse_prepare(req
);
3105 res
= get_path_nullok(f
, ino
, &path
);
3107 struct fuse_intr_data d
;
3109 fuse_prepare_interrupt(f
, req
, &d
);
3110 res
= fuse_fs_write_buf(f
->fs
, path
, buf
, off
, fi
);
3111 fuse_finish_interrupt(f
, req
, &d
);
3112 free_path(f
, ino
, path
);
3116 fuse_reply_write(req
, res
);
3118 reply_err(req
, res
);
3121 static void fuse_lib_fsync(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
3122 struct fuse_file_info
*fi
)
3124 struct fuse
*f
= req_fuse_prepare(req
);
3128 err
= get_path_nullok(f
, ino
, &path
);
3130 struct fuse_intr_data d
;
3132 fuse_prepare_interrupt(f
, req
, &d
);
3133 err
= fuse_fs_fsync(f
->fs
, path
, datasync
, fi
);
3134 fuse_finish_interrupt(f
, req
, &d
);
3135 free_path(f
, ino
, path
);
3137 reply_err(req
, err
);
3140 static struct fuse_dh
*get_dirhandle(const struct fuse_file_info
*llfi
,
3141 struct fuse_file_info
*fi
)
3143 struct fuse_dh
*dh
= (struct fuse_dh
*) (uintptr_t) llfi
->fh
;
3144 memset(fi
, 0, sizeof(struct fuse_file_info
));
3146 fi
->fh_old
= dh
->fh
;
3150 static void fuse_lib_opendir(fuse_req_t req
, fuse_ino_t ino
,
3151 struct fuse_file_info
*llfi
)
3153 struct fuse
*f
= req_fuse_prepare(req
);
3154 struct fuse_intr_data d
;
3156 struct fuse_file_info fi
;
3160 dh
= (struct fuse_dh
*) malloc(sizeof(struct fuse_dh
));
3162 reply_err(req
, -ENOMEM
);
3165 memset(dh
, 0, sizeof(struct fuse_dh
));
3167 dh
->contents
= NULL
;
3171 fuse_mutex_init(&dh
->lock
);
3173 llfi
->fh
= (uintptr_t) dh
;
3175 memset(&fi
, 0, sizeof(fi
));
3176 fi
.flags
= llfi
->flags
;
3178 err
= get_path(f
, ino
, &path
);
3180 fuse_prepare_interrupt(f
, req
, &d
);
3181 err
= fuse_fs_opendir(f
->fs
, path
, &fi
);
3182 fuse_finish_interrupt(f
, req
, &d
);
3186 if (fuse_reply_open(req
, llfi
) == -ENOENT
) {
3187 /* The opendir syscall was interrupted, so it
3188 must be cancelled */
3189 fuse_fs_releasedir(f
->fs
, path
, &fi
);
3190 pthread_mutex_destroy(&dh
->lock
);
3194 reply_err(req
, err
);
3195 pthread_mutex_destroy(&dh
->lock
);
3198 free_path(f
, ino
, path
);
3201 static int extend_contents(struct fuse_dh
*dh
, unsigned minsize
)
3203 if (minsize
> dh
->size
) {
3205 unsigned newsize
= dh
->size
;
3208 while (newsize
< minsize
) {
3209 if (newsize
>= 0x80000000)
3210 newsize
= 0xffffffff;
3215 newptr
= (char *) realloc(dh
->contents
, newsize
);
3217 dh
->error
= -ENOMEM
;
3220 dh
->contents
= newptr
;
3226 static int fill_dir(void *dh_
, const char *name
, const struct stat
*statp
,
3229 struct fuse_dh
*dh
= (struct fuse_dh
*) dh_
;
3236 memset(&stbuf
, 0, sizeof(stbuf
));
3237 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
3240 if (!dh
->fuse
->conf
.use_ino
) {
3241 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
3242 if (dh
->fuse
->conf
.readdir_ino
) {
3244 pthread_mutex_lock(&dh
->fuse
->lock
);
3245 node
= lookup_node(dh
->fuse
, dh
->nodeid
, name
);
3247 stbuf
.st_ino
= (ino_t
) node
->nodeid
;
3248 pthread_mutex_unlock(&dh
->fuse
->lock
);
3253 if (extend_contents(dh
, dh
->needlen
) == -1)
3258 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
3259 dh
->needlen
- dh
->len
, name
,
3261 if (newlen
> dh
->needlen
)
3265 fuse_add_direntry(dh
->req
, NULL
, 0, name
, NULL
, 0);
3266 if (extend_contents(dh
, newlen
) == -1)
3269 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
3270 dh
->size
- dh
->len
, name
, &stbuf
, newlen
);
3276 static int readdir_fill(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3277 size_t size
, off_t off
, struct fuse_dh
*dh
,
3278 struct fuse_file_info
*fi
)
3283 if (f
->fs
->op
.readdir
)
3284 err
= get_path_nullok(f
, ino
, &path
);
3286 err
= get_path(f
, ino
, &path
);
3288 struct fuse_intr_data d
;
3295 fuse_prepare_interrupt(f
, req
, &d
);
3296 err
= fuse_fs_readdir(f
->fs
, path
, dh
, fill_dir
, off
, fi
);
3297 fuse_finish_interrupt(f
, req
, &d
);
3303 free_path(f
, ino
, path
);
3308 static void fuse_lib_readdir(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
3309 off_t off
, struct fuse_file_info
*llfi
)
3311 struct fuse
*f
= req_fuse_prepare(req
);
3312 struct fuse_file_info fi
;
3313 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
3315 pthread_mutex_lock(&dh
->lock
);
3316 /* According to SUS, directory contents need to be refreshed on
3322 int err
= readdir_fill(f
, req
, ino
, size
, off
, dh
, &fi
);
3324 reply_err(req
, err
);
3329 if (off
< dh
->len
) {
3330 if (off
+ size
> dh
->len
)
3331 size
= dh
->len
- off
;
3338 fuse_reply_buf(req
, dh
->contents
+ off
, size
);
3340 pthread_mutex_unlock(&dh
->lock
);
3343 static void fuse_lib_releasedir(fuse_req_t req
, fuse_ino_t ino
,
3344 struct fuse_file_info
*llfi
)
3346 struct fuse
*f
= req_fuse_prepare(req
);
3347 struct fuse_intr_data d
;
3348 struct fuse_file_info fi
;
3349 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
3352 get_path_nullok(f
, ino
, &path
);
3354 fuse_prepare_interrupt(f
, req
, &d
);
3355 fuse_fs_releasedir(f
->fs
, path
, &fi
);
3356 fuse_finish_interrupt(f
, req
, &d
);
3357 free_path(f
, ino
, path
);
3359 pthread_mutex_lock(&dh
->lock
);
3360 pthread_mutex_unlock(&dh
->lock
);
3361 pthread_mutex_destroy(&dh
->lock
);
3367 static void fuse_lib_fsyncdir(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
3368 struct fuse_file_info
*llfi
)
3370 struct fuse
*f
= req_fuse_prepare(req
);
3371 struct fuse_file_info fi
;
3375 get_dirhandle(llfi
, &fi
);
3377 err
= get_path_nullok(f
, ino
, &path
);
3379 struct fuse_intr_data d
;
3380 fuse_prepare_interrupt(f
, req
, &d
);
3381 err
= fuse_fs_fsyncdir(f
->fs
, path
, datasync
, &fi
);
3382 fuse_finish_interrupt(f
, req
, &d
);
3383 free_path(f
, ino
, path
);
3385 reply_err(req
, err
);
3388 static void fuse_lib_statfs(fuse_req_t req
, fuse_ino_t ino
)
3390 struct fuse
*f
= req_fuse_prepare(req
);
3395 memset(&buf
, 0, sizeof(buf
));
3397 err
= get_path(f
, ino
, &path
);
3400 struct fuse_intr_data d
;
3401 fuse_prepare_interrupt(f
, req
, &d
);
3402 err
= fuse_fs_statfs(f
->fs
, path
? path
: "/", &buf
);
3403 fuse_finish_interrupt(f
, req
, &d
);
3404 free_path(f
, ino
, path
);
3408 fuse_reply_statfs(req
, &buf
);
3410 reply_err(req
, err
);
3413 static void fuse_lib_setxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
3414 const char *value
, size_t size
, int flags
)
3416 struct fuse
*f
= req_fuse_prepare(req
);
3420 err
= get_path(f
, ino
, &path
);
3422 struct fuse_intr_data d
;
3423 fuse_prepare_interrupt(f
, req
, &d
);
3424 err
= fuse_fs_setxattr(f
->fs
, path
, name
, value
, size
, flags
);
3425 fuse_finish_interrupt(f
, req
, &d
);
3426 free_path(f
, ino
, path
);
3428 reply_err(req
, err
);
3431 static int common_getxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3432 const char *name
, char *value
, size_t size
)
3437 err
= get_path(f
, ino
, &path
);
3439 struct fuse_intr_data d
;
3440 fuse_prepare_interrupt(f
, req
, &d
);
3441 err
= fuse_fs_getxattr(f
->fs
, path
, name
, value
, size
);
3442 fuse_finish_interrupt(f
, req
, &d
);
3443 free_path(f
, ino
, path
);
3448 static void fuse_lib_getxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
3451 struct fuse
*f
= req_fuse_prepare(req
);
3455 char *value
= (char *) malloc(size
);
3456 if (value
== NULL
) {
3457 reply_err(req
, -ENOMEM
);
3460 res
= common_getxattr(f
, req
, ino
, name
, value
, size
);
3462 fuse_reply_buf(req
, value
, res
);
3464 reply_err(req
, res
);
3467 res
= common_getxattr(f
, req
, ino
, name
, NULL
, 0);
3469 fuse_reply_xattr(req
, res
);
3471 reply_err(req
, res
);
3475 static int common_listxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3476 char *list
, size_t size
)
3481 err
= get_path(f
, ino
, &path
);
3483 struct fuse_intr_data d
;
3484 fuse_prepare_interrupt(f
, req
, &d
);
3485 err
= fuse_fs_listxattr(f
->fs
, path
, list
, size
);
3486 fuse_finish_interrupt(f
, req
, &d
);
3487 free_path(f
, ino
, path
);
3492 static void fuse_lib_listxattr(fuse_req_t req
, fuse_ino_t ino
, size_t size
)
3494 struct fuse
*f
= req_fuse_prepare(req
);
3498 char *list
= (char *) malloc(size
);
3500 reply_err(req
, -ENOMEM
);
3503 res
= common_listxattr(f
, req
, ino
, list
, size
);
3505 fuse_reply_buf(req
, list
, res
);
3507 reply_err(req
, res
);
3510 res
= common_listxattr(f
, req
, ino
, NULL
, 0);
3512 fuse_reply_xattr(req
, res
);
3514 reply_err(req
, res
);
3518 static void fuse_lib_removexattr(fuse_req_t req
, fuse_ino_t ino
,
3521 struct fuse
*f
= req_fuse_prepare(req
);
3525 err
= get_path(f
, ino
, &path
);
3527 struct fuse_intr_data d
;
3528 fuse_prepare_interrupt(f
, req
, &d
);
3529 err
= fuse_fs_removexattr(f
->fs
, path
, name
);
3530 fuse_finish_interrupt(f
, req
, &d
);
3531 free_path(f
, ino
, path
);
3533 reply_err(req
, err
);
3536 static struct lock
*locks_conflict(struct node
*node
, const struct lock
*lock
)
3540 for (l
= node
->locks
; l
; l
= l
->next
)
3541 if (l
->owner
!= lock
->owner
&&
3542 lock
->start
<= l
->end
&& l
->start
<= lock
->end
&&
3543 (l
->type
== F_WRLCK
|| lock
->type
== F_WRLCK
))
3549 static void delete_lock(struct lock
**lockp
)
3551 struct lock
*l
= *lockp
;
3556 static void insert_lock(struct lock
**pos
, struct lock
*lock
)
3562 static int locks_insert(struct node
*node
, struct lock
*lock
)
3565 struct lock
*newl1
= NULL
;
3566 struct lock
*newl2
= NULL
;
3568 if (lock
->type
!= F_UNLCK
|| lock
->start
!= 0 ||
3569 lock
->end
!= OFFSET_MAX
) {
3570 newl1
= malloc(sizeof(struct lock
));
3571 newl2
= malloc(sizeof(struct lock
));
3573 if (!newl1
|| !newl2
) {
3580 for (lp
= &node
->locks
; *lp
;) {
3581 struct lock
*l
= *lp
;
3582 if (l
->owner
!= lock
->owner
)
3585 if (lock
->type
== l
->type
) {
3586 if (l
->end
< lock
->start
- 1)
3588 if (lock
->end
< l
->start
- 1)
3590 if (l
->start
<= lock
->start
&& lock
->end
<= l
->end
)
3592 if (l
->start
< lock
->start
)
3593 lock
->start
= l
->start
;
3594 if (lock
->end
< l
->end
)
3598 if (l
->end
< lock
->start
)
3600 if (lock
->end
< l
->start
)
3602 if (lock
->start
<= l
->start
&& l
->end
<= lock
->end
)
3604 if (l
->end
<= lock
->end
) {
3605 l
->end
= lock
->start
- 1;
3608 if (lock
->start
<= l
->start
) {
3609 l
->start
= lock
->end
+ 1;
3613 newl2
->start
= lock
->end
+ 1;
3614 l
->end
= lock
->start
- 1;
3615 insert_lock(&l
->next
, newl2
);
3625 if (lock
->type
!= F_UNLCK
) {
3627 insert_lock(lp
, newl1
);
3636 static void flock_to_lock(struct flock
*flock
, struct lock
*lock
)
3638 memset(lock
, 0, sizeof(struct lock
));
3639 lock
->type
= flock
->l_type
;
3640 lock
->start
= flock
->l_start
;
3642 flock
->l_len
? flock
->l_start
+ flock
->l_len
- 1 : OFFSET_MAX
;
3643 lock
->pid
= flock
->l_pid
;
3646 static void lock_to_flock(struct lock
*lock
, struct flock
*flock
)
3648 flock
->l_type
= lock
->type
;
3649 flock
->l_start
= lock
->start
;
3651 (lock
->end
== OFFSET_MAX
) ? 0 : lock
->end
- lock
->start
+ 1;
3652 flock
->l_pid
= lock
->pid
;
3655 static int fuse_flush_common(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3656 const char *path
, struct fuse_file_info
*fi
)
3658 struct fuse_intr_data d
;
3664 fuse_prepare_interrupt(f
, req
, &d
);
3665 memset(&lock
, 0, sizeof(lock
));
3666 lock
.l_type
= F_UNLCK
;
3667 lock
.l_whence
= SEEK_SET
;
3668 err
= fuse_fs_flush(f
->fs
, path
, fi
);
3669 errlock
= fuse_fs_lock(f
->fs
, path
, fi
, F_SETLK
, &lock
);
3670 fuse_finish_interrupt(f
, req
, &d
);
3672 if (errlock
!= -ENOSYS
) {
3673 flock_to_lock(&lock
, &l
);
3674 l
.owner
= fi
->lock_owner
;
3675 pthread_mutex_lock(&f
->lock
);
3676 locks_insert(get_node(f
, ino
), &l
);
3677 pthread_mutex_unlock(&f
->lock
);
3679 /* if op.lock() is defined FLUSH is needed regardless
3687 static void fuse_lib_release(fuse_req_t req
, fuse_ino_t ino
,
3688 struct fuse_file_info
*fi
)
3690 struct fuse
*f
= req_fuse_prepare(req
);
3691 struct fuse_intr_data d
;
3695 get_path_nullok(f
, ino
, &path
);
3697 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
3702 fuse_prepare_interrupt(f
, req
, &d
);
3703 fuse_do_release(f
, ino
, path
, fi
);
3704 fuse_finish_interrupt(f
, req
, &d
);
3705 free_path(f
, ino
, path
);
3707 reply_err(req
, err
);
3710 static void fuse_lib_flush(fuse_req_t req
, fuse_ino_t ino
,
3711 struct fuse_file_info
*fi
)
3713 struct fuse
*f
= req_fuse_prepare(req
);
3717 get_path_nullok(f
, ino
, &path
);
3718 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
3719 free_path(f
, ino
, path
);
3721 reply_err(req
, err
);
3724 static int fuse_lock_common(fuse_req_t req
, fuse_ino_t ino
,
3725 struct fuse_file_info
*fi
, struct flock
*lock
,
3728 struct fuse
*f
= req_fuse_prepare(req
);
3732 err
= get_path_nullok(f
, ino
, &path
);
3734 struct fuse_intr_data d
;
3735 fuse_prepare_interrupt(f
, req
, &d
);
3736 err
= fuse_fs_lock(f
->fs
, path
, fi
, cmd
, lock
);
3737 fuse_finish_interrupt(f
, req
, &d
);
3738 free_path(f
, ino
, path
);
3743 static void fuse_lib_getlk(fuse_req_t req
, fuse_ino_t ino
,
3744 struct fuse_file_info
*fi
, struct flock
*lock
)
3748 struct lock
*conflict
;
3749 struct fuse
*f
= req_fuse(req
);
3751 flock_to_lock(lock
, &l
);
3752 l
.owner
= fi
->lock_owner
;
3753 pthread_mutex_lock(&f
->lock
);
3754 conflict
= locks_conflict(get_node(f
, ino
), &l
);
3756 lock_to_flock(conflict
, lock
);
3757 pthread_mutex_unlock(&f
->lock
);
3759 err
= fuse_lock_common(req
, ino
, fi
, lock
, F_GETLK
);
3764 fuse_reply_lock(req
, lock
);
3766 reply_err(req
, err
);
3769 static void fuse_lib_setlk(fuse_req_t req
, fuse_ino_t ino
,
3770 struct fuse_file_info
*fi
, struct flock
*lock
,
3773 int err
= fuse_lock_common(req
, ino
, fi
, lock
,
3774 sleep
? F_SETLKW
: F_SETLK
);
3776 struct fuse
*f
= req_fuse(req
);
3778 flock_to_lock(lock
, &l
);
3779 l
.owner
= fi
->lock_owner
;
3780 pthread_mutex_lock(&f
->lock
);
3781 locks_insert(get_node(f
, ino
), &l
);
3782 pthread_mutex_unlock(&f
->lock
);
3784 reply_err(req
, err
);
3787 static void fuse_lib_flock(fuse_req_t req
, fuse_ino_t ino
,
3788 struct fuse_file_info
*fi
, int op
)
3790 struct fuse
*f
= req_fuse_prepare(req
);
3794 err
= get_path_nullok(f
, ino
, &path
);
3796 struct fuse_intr_data d
;
3797 fuse_prepare_interrupt(f
, req
, &d
);
3798 err
= fuse_fs_flock(f
->fs
, path
, fi
, op
);
3799 fuse_finish_interrupt(f
, req
, &d
);
3800 free_path(f
, ino
, path
);
3802 reply_err(req
, err
);
3805 static void fuse_lib_bmap(fuse_req_t req
, fuse_ino_t ino
, size_t blocksize
,
3808 struct fuse
*f
= req_fuse_prepare(req
);
3809 struct fuse_intr_data d
;
3813 err
= get_path(f
, ino
, &path
);
3815 fuse_prepare_interrupt(f
, req
, &d
);
3816 err
= fuse_fs_bmap(f
->fs
, path
, blocksize
, &idx
);
3817 fuse_finish_interrupt(f
, req
, &d
);
3818 free_path(f
, ino
, path
);
3821 fuse_reply_bmap(req
, idx
);
3823 reply_err(req
, err
);
3826 static void fuse_lib_ioctl(fuse_req_t req
, fuse_ino_t ino
, int cmd
, void *arg
,
3827 struct fuse_file_info
*fi
, unsigned int flags
,
3828 const void *in_buf
, size_t in_bufsz
,
3831 struct fuse
*f
= req_fuse_prepare(req
);
3832 struct fuse_intr_data d
;
3833 char *path
, *out_buf
= NULL
;
3837 if (flags
& FUSE_IOCTL_UNRESTRICTED
)
3842 out_buf
= malloc(out_bufsz
);
3847 assert(!in_bufsz
|| !out_bufsz
|| in_bufsz
== out_bufsz
);
3849 memcpy(out_buf
, in_buf
, in_bufsz
);
3851 err
= get_path_nullok(f
, ino
, &path
);
3855 fuse_prepare_interrupt(f
, req
, &d
);
3857 err
= fuse_fs_ioctl(f
->fs
, path
, cmd
, arg
, fi
, flags
,
3858 out_buf
?: (void *)in_buf
);
3860 fuse_finish_interrupt(f
, req
, &d
);
3861 free_path(f
, ino
, path
);
3863 fuse_reply_ioctl(req
, err
, out_buf
, out_bufsz
);
3866 reply_err(req
, err
);
3871 static void fuse_lib_poll(fuse_req_t req
, fuse_ino_t ino
,
3872 struct fuse_file_info
*fi
, struct fuse_pollhandle
*ph
)
3874 struct fuse
*f
= req_fuse_prepare(req
);
3875 struct fuse_intr_data d
;
3878 unsigned revents
= 0;
3880 err
= get_path_nullok(f
, ino
, &path
);
3882 fuse_prepare_interrupt(f
, req
, &d
);
3883 err
= fuse_fs_poll(f
->fs
, path
, fi
, ph
, &revents
);
3884 fuse_finish_interrupt(f
, req
, &d
);
3885 free_path(f
, ino
, path
);
3888 fuse_reply_poll(req
, revents
);
3890 reply_err(req
, err
);
3893 static void fuse_lib_fallocate(fuse_req_t req
, fuse_ino_t ino
, int mode
,
3894 off_t offset
, off_t length
, struct fuse_file_info
*fi
)
3896 struct fuse
*f
= req_fuse_prepare(req
);
3897 struct fuse_intr_data d
;
3901 err
= get_path_nullok(f
, ino
, &path
);
3903 fuse_prepare_interrupt(f
, req
, &d
);
3904 err
= fuse_fs_fallocate(f
->fs
, path
, mode
, offset
, length
, fi
);
3905 fuse_finish_interrupt(f
, req
, &d
);
3906 free_path(f
, ino
, path
);
3908 reply_err(req
, err
);
3911 static int clean_delay(struct fuse
*f
)
3914 * This is calculating the delay between clean runs. To
3915 * reduce the number of cleans we are doing them 10 times
3916 * within the remember window.
3919 int max_sleep
= 3600;
3920 int sleep_time
= f
->conf
.remember
/ 10;
3922 if (sleep_time
> max_sleep
)
3924 if (sleep_time
< min_sleep
)
3929 int fuse_clean_cache(struct fuse
*f
)
3931 struct node_lru
*lnode
;
3932 struct list_head
*curr
, *next
;
3934 struct timespec now
;
3936 pthread_mutex_lock(&f
->lock
);
3940 for (curr
= f
->lru_table
.next
; curr
!= &f
->lru_table
; curr
= next
) {
3944 lnode
= list_entry(curr
, struct node_lru
, lru
);
3945 node
= &lnode
->node
;
3947 age
= diff_timespec(&now
, &lnode
->forget_time
);
3948 if (age
<= f
->conf
.remember
)
3951 assert(node
->nlookup
== 1);
3953 /* Don't forget active directories */
3954 if (node
->refctr
> 1)
3958 unhash_name(f
, node
);
3959 unref_node(f
, node
);
3961 pthread_mutex_unlock(&f
->lock
);
3963 return clean_delay(f
);
3966 static struct fuse_lowlevel_ops fuse_path_ops
= {
3967 .init
= fuse_lib_init
,
3968 .destroy
= fuse_lib_destroy
,
3969 .lookup
= fuse_lib_lookup
,
3970 .forget
= fuse_lib_forget
,
3971 .forget_multi
= fuse_lib_forget_multi
,
3972 .getattr
= fuse_lib_getattr
,
3973 .setattr
= fuse_lib_setattr
,
3974 .access
= fuse_lib_access
,
3975 .readlink
= fuse_lib_readlink
,
3976 .mknod
= fuse_lib_mknod
,
3977 .mkdir
= fuse_lib_mkdir
,
3978 .unlink
= fuse_lib_unlink
,
3979 .rmdir
= fuse_lib_rmdir
,
3980 .symlink
= fuse_lib_symlink
,
3981 .rename
= fuse_lib_rename
,
3982 .link
= fuse_lib_link
,
3983 .create
= fuse_lib_create
,
3984 .open
= fuse_lib_open
,
3985 .read
= fuse_lib_read
,
3986 .write_buf
= fuse_lib_write_buf
,
3987 .flush
= fuse_lib_flush
,
3988 .release
= fuse_lib_release
,
3989 .fsync
= fuse_lib_fsync
,
3990 .opendir
= fuse_lib_opendir
,
3991 .readdir
= fuse_lib_readdir
,
3992 .releasedir
= fuse_lib_releasedir
,
3993 .fsyncdir
= fuse_lib_fsyncdir
,
3994 .statfs
= fuse_lib_statfs
,
3995 .setxattr
= fuse_lib_setxattr
,
3996 .getxattr
= fuse_lib_getxattr
,
3997 .listxattr
= fuse_lib_listxattr
,
3998 .removexattr
= fuse_lib_removexattr
,
3999 .getlk
= fuse_lib_getlk
,
4000 .setlk
= fuse_lib_setlk
,
4001 .flock
= fuse_lib_flock
,
4002 .bmap
= fuse_lib_bmap
,
4003 .ioctl
= fuse_lib_ioctl
,
4004 .poll
= fuse_lib_poll
,
4005 .fallocate
= fuse_lib_fallocate
,
4008 int fuse_notify_poll(struct fuse_pollhandle
*ph
)
4010 return fuse_lowlevel_notify_poll(ph
);
4013 struct fuse_session
*fuse_get_session(struct fuse
*f
)
4018 static int fuse_session_loop_remember(struct fuse
*f
)
4020 struct fuse_session
*se
= f
->se
;
4022 struct timespec now
;
4024 struct fuse_chan
*ch
= fuse_session_next_chan(se
, NULL
);
4025 size_t bufsize
= fuse_chan_bufsize(ch
);
4026 char *buf
= (char *) malloc(bufsize
);
4027 struct pollfd fds
= {
4028 .fd
= fuse_chan_fd(ch
),
4033 fprintf(stderr
, "fuse: failed to allocate read buffer\n");
4038 next_clean
= now
.tv_sec
;
4039 while (!fuse_session_exited(se
)) {
4040 struct fuse_chan
*tmpch
= ch
;
4041 struct fuse_buf fbuf
= {
4048 if (now
.tv_sec
< next_clean
)
4049 timeout
= next_clean
- now
.tv_sec
;
4053 res
= poll(&fds
, 1, timeout
* 1000);
4055 if (errno
== -EINTR
)
4059 } else if (res
> 0) {
4060 res
= fuse_session_receive_buf(se
, &fbuf
, &tmpch
);
4067 fuse_session_process_buf(se
, &fbuf
, tmpch
);
4069 timeout
= fuse_clean_cache(f
);
4071 next_clean
= now
.tv_sec
+ timeout
;
4076 fuse_session_reset(se
);
4077 return res
< 0 ? -1 : 0;
4080 int fuse_loop(struct fuse
*f
)
4086 return fuse_session_loop_remember(f
);
4088 return fuse_session_loop(f
->se
);
4091 void fuse_exit(struct fuse
*f
)
4093 fuse_session_exit(f
->se
);
4096 struct fuse_context
*fuse_get_context(void)
4098 struct fuse_context_i
*c
= fuse_get_context_internal();
4106 int fuse_getgroups(int size
, gid_t list
[])
4108 struct fuse_context_i
*c
= fuse_get_context_internal();
4112 return fuse_req_getgroups(c
->req
, size
, list
);
4115 int fuse_interrupted(void)
4117 struct fuse_context_i
*c
= fuse_get_context_internal();
4120 return fuse_req_interrupted(c
->req
);
4129 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4131 static const struct fuse_opt fuse_lib_opts
[] = {
4132 FUSE_OPT_KEY("-h", KEY_HELP
),
4133 FUSE_OPT_KEY("--help", KEY_HELP
),
4134 FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP
),
4135 FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP
),
4136 FUSE_LIB_OPT("debug", debug
, 1),
4137 FUSE_LIB_OPT("-d", debug
, 1),
4138 FUSE_LIB_OPT("hard_remove", hard_remove
, 1),
4139 FUSE_LIB_OPT("use_ino", use_ino
, 1),
4140 FUSE_LIB_OPT("readdir_ino", readdir_ino
, 1),
4141 FUSE_LIB_OPT("direct_io", direct_io
, 1),
4142 FUSE_LIB_OPT("kernel_cache", kernel_cache
, 1),
4143 FUSE_LIB_OPT("auto_cache", auto_cache
, 1),
4144 FUSE_LIB_OPT("noauto_cache", auto_cache
, 0),
4145 FUSE_LIB_OPT("umask=", set_mode
, 1),
4146 FUSE_LIB_OPT("umask=%o", umask
, 0),
4147 FUSE_LIB_OPT("uid=", set_uid
, 1),
4148 FUSE_LIB_OPT("uid=%d", uid
, 0),
4149 FUSE_LIB_OPT("gid=", set_gid
, 1),
4150 FUSE_LIB_OPT("gid=%d", gid
, 0),
4151 FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout
, 0),
4152 FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout
, 0),
4153 FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout
, 0),
4154 FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set
, 1),
4155 FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout
, 0),
4156 FUSE_LIB_OPT("noforget", remember
, -1),
4157 FUSE_LIB_OPT("remember=%u", remember
, 0),
4158 FUSE_LIB_OPT("nopath", nopath
, 1),
4159 FUSE_LIB_OPT("intr", intr
, 1),
4160 FUSE_LIB_OPT("intr_signal=%d", intr_signal
, 0),
4161 FUSE_LIB_OPT("modules=%s", modules
, 0),
4165 static void fuse_lib_help(void)
4168 " -o hard_remove immediate removal (don't hide files)\n"
4169 " -o use_ino let filesystem set inode numbers\n"
4170 " -o readdir_ino try to fill in d_ino in readdir\n"
4171 " -o direct_io use direct I/O\n"
4172 " -o kernel_cache cache files in kernel\n"
4173 " -o [no]auto_cache enable caching based on modification times (off)\n"
4174 " -o umask=M set file permissions (octal)\n"
4175 " -o uid=N set file owner\n"
4176 " -o gid=N set file group\n"
4177 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4178 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4179 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4180 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4181 " -o noforget never forget cached inodes\n"
4182 " -o remember=T remember cached inodes for T seconds (0s)\n"
4183 " -o intr allow requests to be interrupted\n"
4184 " -o intr_signal=NUM signal to send on interrupt (%i)\n"
4185 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
4186 "\n", FUSE_DEFAULT_INTR_SIGNAL
);
4189 static void fuse_lib_help_modules(void)
4191 struct fuse_module
*m
;
4192 fprintf(stderr
, "\nModule options:\n");
4193 pthread_mutex_lock(&fuse_context_lock
);
4194 for (m
= fuse_modules
; m
; m
= m
->next
) {
4195 struct fuse_fs
*fs
= NULL
;
4196 struct fuse_fs
*newfs
;
4197 struct fuse_args args
= FUSE_ARGS_INIT(0, NULL
);
4198 if (fuse_opt_add_arg(&args
, "") != -1 &&
4199 fuse_opt_add_arg(&args
, "-h") != -1) {
4200 fprintf(stderr
, "\n[%s]\n", m
->name
);
4201 newfs
= m
->factory(&args
, &fs
);
4202 assert(newfs
== NULL
);
4204 fuse_opt_free_args(&args
);
4206 pthread_mutex_unlock(&fuse_context_lock
);
4209 static int fuse_lib_opt_proc(void *data
, const char *arg
, int key
,
4210 struct fuse_args
*outargs
)
4212 (void) arg
; (void) outargs
;
4214 if (key
== KEY_HELP
) {
4215 struct fuse_config
*conf
= (struct fuse_config
*) data
;
4223 static int fuse_init_intr_signal(int signum
, int *installed
)
4225 struct sigaction old_sa
;
4227 if (sigaction(signum
, NULL
, &old_sa
) == -1) {
4228 perror("fuse: cannot get old signal handler");
4232 if (old_sa
.sa_handler
== SIG_DFL
) {
4233 struct sigaction sa
;
4235 memset(&sa
, 0, sizeof(struct sigaction
));
4236 sa
.sa_handler
= fuse_intr_sighandler
;
4237 sigemptyset(&sa
.sa_mask
);
4239 if (sigaction(signum
, &sa
, NULL
) == -1) {
4240 perror("fuse: cannot set interrupt signal handler");
4248 static void fuse_restore_intr_signal(int signum
)
4250 struct sigaction sa
;
4252 memset(&sa
, 0, sizeof(struct sigaction
));
4253 sa
.sa_handler
= SIG_DFL
;
4254 sigaction(signum
, &sa
, NULL
);
4258 static int fuse_push_module(struct fuse
*f
, const char *module
,
4259 struct fuse_args
*args
)
4261 struct fuse_fs
*fs
[2] = { f
->fs
, NULL
};
4262 struct fuse_fs
*newfs
;
4263 struct fuse_module
*m
= fuse_get_module(module
);
4268 newfs
= m
->factory(args
, fs
);
4275 f
->conf
.nopath
= newfs
->op
.flag_nopath
&& f
->conf
.nopath
;
4279 struct fuse_fs
*fuse_fs_new(const struct fuse_operations
*op
, size_t op_size
,
4284 if (sizeof(struct fuse_operations
) < op_size
) {
4285 fprintf(stderr
, "fuse: warning: library too old, some operations may not not work\n");
4286 op_size
= sizeof(struct fuse_operations
);
4289 fs
= (struct fuse_fs
*) calloc(1, sizeof(struct fuse_fs
));
4291 fprintf(stderr
, "fuse: failed to allocate fuse_fs object\n");
4295 fs
->user_data
= user_data
;
4297 memcpy(&fs
->op
, op
, op_size
);
4301 static int node_table_init(struct node_table
*t
)
4303 t
->size
= NODE_TABLE_MIN_SIZE
;
4304 t
->array
= (struct node
**) calloc(1, sizeof(struct node
*) * t
->size
);
4305 if (t
->array
== NULL
) {
4306 fprintf(stderr
, "fuse: memory allocation failed\n");
4315 static void *fuse_prune_nodes(void *fuse
)
4317 struct fuse
*f
= fuse
;
4321 sleep_time
= fuse_clean_cache(f
);
4327 int fuse_start_cleanup_thread(struct fuse
*f
)
4330 return fuse_start_thread(&f
->prune_thread
, fuse_prune_nodes
, f
);
4335 void fuse_stop_cleanup_thread(struct fuse
*f
)
4337 if (lru_enabled(f
)) {
4338 pthread_mutex_lock(&f
->lock
);
4339 pthread_cancel(f
->prune_thread
);
4340 pthread_mutex_unlock(&f
->lock
);
4341 pthread_join(f
->prune_thread
, NULL
);
4345 struct fuse
*fuse_new(struct fuse_chan
*ch
, struct fuse_args
*args
,
4346 const struct fuse_operations
*op
,
4347 size_t op_size
, void *user_data
)
4352 struct fuse_lowlevel_ops llop
= fuse_path_ops
;
4354 if (fuse_create_context_key() == -1)
4357 f
= (struct fuse
*) calloc(1, sizeof(struct fuse
));
4359 fprintf(stderr
, "fuse: failed to allocate fuse object\n");
4360 goto out_delete_context_key
;
4363 fs
= fuse_fs_new(op
, op_size
, user_data
);
4368 f
->conf
.nopath
= fs
->op
.flag_nopath
;
4370 /* Oh f**k, this is ugly! */
4376 f
->conf
.entry_timeout
= 1.0;
4377 f
->conf
.attr_timeout
= 1.0;
4378 f
->conf
.negative_timeout
= 0.0;
4379 f
->conf
.intr_signal
= FUSE_DEFAULT_INTR_SIGNAL
;
4381 f
->pagesize
= getpagesize();
4382 init_list_head(&f
->partial_slabs
);
4383 init_list_head(&f
->full_slabs
);
4384 init_list_head(&f
->lru_table
);
4386 if (fuse_opt_parse(args
, &f
->conf
, fuse_lib_opts
,
4387 fuse_lib_opt_proc
) == -1)
4390 if (f
->conf
.modules
) {
4394 for (module
= f
->conf
.modules
; module
; module
= next
) {
4396 for (p
= module
; *p
&& *p
!= ':'; p
++);
4397 next
= *p
? p
+ 1 : NULL
;
4400 fuse_push_module(f
, module
, args
) == -1)
4405 if (!f
->conf
.ac_attr_timeout_set
)
4406 f
->conf
.ac_attr_timeout
= f
->conf
.attr_timeout
;
4408 #if defined(__FreeBSD__) || defined(__NetBSD__)
4410 * In FreeBSD, we always use these settings as inode numbers
4411 * are needed to make getcwd(3) work.
4413 f
->conf
.readdir_ino
= 1;
4416 f
->se
= fuse_lowlevel_new(args
, &llop
, sizeof(llop
), f
);
4417 if (f
->se
== NULL
) {
4419 fuse_lib_help_modules();
4423 fuse_session_add_chan(f
->se
, ch
);
4425 if (f
->conf
.debug
) {
4426 fprintf(stderr
, "nopath: %i\n", f
->conf
.nopath
);
4429 /* Trace topmost layer by default */
4430 f
->fs
->debug
= f
->conf
.debug
;
4433 if (node_table_init(&f
->name_table
) == -1)
4434 goto out_free_session
;
4436 if (node_table_init(&f
->id_table
) == -1)
4437 goto out_free_name_table
;
4439 fuse_mutex_init(&f
->lock
);
4441 root
= alloc_node(f
);
4443 fprintf(stderr
, "fuse: memory allocation failed\n");
4444 goto out_free_id_table
;
4446 if (lru_enabled(f
)) {
4447 struct node_lru
*lnode
= node_lru(root
);
4448 init_list_head(&lnode
->lru
);
4451 strcpy(root
->inline_name
, "/");
4452 root
->name
= root
->inline_name
;
4455 fuse_init_intr_signal(f
->conf
.intr_signal
,
4456 &f
->intr_installed
) == -1)
4459 root
->parent
= NULL
;
4460 root
->nodeid
= FUSE_ROOT_ID
;
4469 free(f
->id_table
.array
);
4470 out_free_name_table
:
4471 free(f
->name_table
.array
);
4473 fuse_session_destroy(f
->se
);
4476 fuse_put_module(f
->fs
->m
);
4478 free(f
->conf
.modules
);
4481 out_delete_context_key
:
4482 fuse_delete_context_key();
4487 void fuse_destroy(struct fuse
*f
)
4491 if (f
->conf
.intr
&& f
->intr_installed
)
4492 fuse_restore_intr_signal(f
->conf
.intr_signal
);
4495 fuse_create_context(f
);
4497 for (i
= 0; i
< f
->id_table
.size
; i
++) {
4500 for (node
= f
->id_table
.array
[i
]; node
!= NULL
;
4501 node
= node
->id_next
) {
4502 if (node
->is_hidden
) {
4504 if (try_get_path(f
, node
->nodeid
, NULL
, &path
, NULL
, false) == 0) {
4505 fuse_fs_unlink(f
->fs
, path
);
4512 for (i
= 0; i
< f
->id_table
.size
; i
++) {
4516 for (node
= f
->id_table
.array
[i
]; node
!= NULL
; node
= next
) {
4517 next
= node
->id_next
;
4522 assert(list_empty(&f
->partial_slabs
));
4523 assert(list_empty(&f
->full_slabs
));
4525 free(f
->id_table
.array
);
4526 free(f
->name_table
.array
);
4527 pthread_mutex_destroy(&f
->lock
);
4528 fuse_session_destroy(f
->se
);
4529 free(f
->conf
.modules
);
4531 fuse_delete_context_key();
4534 /* called with fuse_context_lock held or during initialization (before
4535 main() has been called) */
4536 void fuse_register_module(struct fuse_module
*mod
)
4539 mod
->so
= fuse_current_so
;
4542 mod
->next
= fuse_modules
;