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_common_compat.h"
19 #include "fuse_compat.h"
20 #include "fuse_kernel.h"
35 #include <sys/param.h>
40 #define FUSE_NODE_SLAB 1
46 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
48 #define FUSE_UNKNOWN_INO 0xffffffff
49 #define OFFSET_MAX 0x7fffffffffffffffLL
51 #define NODE_TABLE_MIN_SIZE 8192
58 double negative_timeout
;
60 double ac_attr_timeout
;
61 int ac_attr_timeout_set
;
81 struct fuse_operations op
;
82 struct fuse_module
*m
;
93 struct lock_queue_element
{
94 struct lock_queue_element
*next
;
105 #define container_of(ptr, type, member) ({ \
106 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
107 (type *)( (char *)__mptr - offsetof(type,member) );})
109 #define list_entry(ptr, type, member) \
110 container_of(ptr, type, member)
113 struct list_head
*next
;
114 struct list_head
*prev
;
118 struct list_head list
; /* must be the first member */
119 struct list_head freelist
;
124 struct fuse_session
*se
;
125 struct node_table name_table
;
126 struct node_table id_table
;
127 struct list_head lru_table
;
129 unsigned int generation
;
130 unsigned int hidectr
;
131 pthread_mutex_t lock
;
132 struct fuse_config conf
;
138 struct lock_queue_element
*lockq
;
140 struct list_head partial_slabs
;
141 struct list_head full_slabs
;
142 pthread_t prune_thread
;
155 struct node
*name_next
;
156 struct node
*id_next
;
158 unsigned int generation
;
164 struct timespec stat_updated
;
165 struct timespec mtime
;
168 unsigned int is_hidden
: 1;
169 unsigned int cache_valid
: 1;
172 char inline_name
[32];
177 struct list_head lru
;
178 struct timespec forget_time
;
182 pthread_mutex_t lock
;
197 struct fuse_dirhandle
{
198 fuse_fill_dir_t filler
;
202 struct fuse_context_i
{
203 struct fuse_context ctx
;
207 static pthread_key_t fuse_context_key
;
208 static pthread_mutex_t fuse_context_lock
= PTHREAD_MUTEX_INITIALIZER
;
209 static int fuse_context_ref
;
210 static struct fusemod_so
*fuse_current_so
;
211 static struct fuse_module
*fuse_modules
;
213 static int fuse_load_so_name(const char *soname
)
215 struct fusemod_so
*so
;
217 so
= calloc(1, sizeof(struct fusemod_so
));
219 fprintf(stderr
, "fuse: memory allocation failed\n");
223 fuse_current_so
= so
;
224 so
->handle
= dlopen(soname
, RTLD_NOW
);
225 fuse_current_so
= NULL
;
227 fprintf(stderr
, "fuse: %s\n", dlerror());
231 fprintf(stderr
, "fuse: %s did not register any modules\n",
244 static int fuse_load_so_module(const char *module
)
247 char *soname
= malloc(strlen(module
) + 64);
249 fprintf(stderr
, "fuse: memory allocation failed\n");
252 sprintf(soname
, "libfusemod_%s.so", module
);
253 res
= fuse_load_so_name(soname
);
258 static struct fuse_module
*fuse_find_module(const char *module
)
260 struct fuse_module
*m
;
261 for (m
= fuse_modules
; m
; m
= m
->next
) {
262 if (strcmp(module
, m
->name
) == 0) {
270 static struct fuse_module
*fuse_get_module(const char *module
)
272 struct fuse_module
*m
;
274 pthread_mutex_lock(&fuse_context_lock
);
275 m
= fuse_find_module(module
);
277 int err
= fuse_load_so_module(module
);
279 m
= fuse_find_module(module
);
281 pthread_mutex_unlock(&fuse_context_lock
);
285 static void fuse_put_module(struct fuse_module
*m
)
287 pthread_mutex_lock(&fuse_context_lock
);
290 if (!m
->ctr
&& m
->so
) {
291 struct fusemod_so
*so
= m
->so
;
295 struct fuse_module
**mp
;
296 for (mp
= &fuse_modules
; *mp
;) {
306 pthread_mutex_unlock(&fuse_context_lock
);
309 static void init_list_head(struct list_head
*list
)
315 static int list_empty(const struct list_head
*head
)
317 return head
->next
== head
;
320 static void list_add(struct list_head
*new, struct list_head
*prev
,
321 struct list_head
*next
)
329 static inline void list_add_head(struct list_head
*new, struct list_head
*head
)
331 list_add(new, head
, head
->next
);
334 static inline void list_add_tail(struct list_head
*new, struct list_head
*head
)
336 list_add(new, head
->prev
, head
);
339 static inline void list_del(struct list_head
*entry
)
341 struct list_head
*prev
= entry
->prev
;
342 struct list_head
*next
= entry
->next
;
348 static inline int lru_enabled(struct fuse
*f
)
350 return f
->conf
.remember
> 0;
353 static struct node_lru
*node_lru(struct node
*node
)
355 return (struct node_lru
*) node
;
358 static size_t get_node_size(struct fuse
*f
)
361 return sizeof(struct node_lru
);
363 return sizeof(struct node
);
366 #ifdef FUSE_NODE_SLAB
367 static struct node_slab
*list_to_slab(struct list_head
*head
)
369 return (struct node_slab
*) head
;
372 static struct node_slab
*node_to_slab(struct fuse
*f
, struct node
*node
)
374 return (struct node_slab
*) (((uintptr_t) node
) & ~((uintptr_t) f
->pagesize
- 1));
377 static int alloc_slab(struct fuse
*f
)
380 struct node_slab
*slab
;
384 size_t node_size
= get_node_size(f
);
386 mem
= mmap(NULL
, f
->pagesize
, PROT_READ
| PROT_WRITE
,
387 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
389 if (mem
== MAP_FAILED
)
393 init_list_head(&slab
->freelist
);
395 num
= (f
->pagesize
- sizeof(struct node_slab
)) / node_size
;
397 start
= (char *) mem
+ f
->pagesize
- num
* node_size
;
398 for (i
= 0; i
< num
; i
++) {
401 n
= (struct list_head
*) (start
+ i
* node_size
);
402 list_add_tail(n
, &slab
->freelist
);
404 list_add_tail(&slab
->list
, &f
->partial_slabs
);
409 static struct node
*alloc_node(struct fuse
*f
)
411 struct node_slab
*slab
;
412 struct list_head
*node
;
414 if (list_empty(&f
->partial_slabs
)) {
415 int res
= alloc_slab(f
);
419 slab
= list_to_slab(f
->partial_slabs
.next
);
421 node
= slab
->freelist
.next
;
423 if (list_empty(&slab
->freelist
)) {
424 list_del(&slab
->list
);
425 list_add_tail(&slab
->list
, &f
->full_slabs
);
427 memset(node
, 0, sizeof(struct node
));
429 return (struct node
*) node
;
432 static void free_slab(struct fuse
*f
, struct node_slab
*slab
)
436 list_del(&slab
->list
);
437 res
= munmap(slab
, f
->pagesize
);
439 fprintf(stderr
, "fuse warning: munmap(%p) failed\n", slab
);
442 static void free_node_mem(struct fuse
*f
, struct node
*node
)
444 struct node_slab
*slab
= node_to_slab(f
, node
);
445 struct list_head
*n
= (struct list_head
*) node
;
449 if (list_empty(&slab
->freelist
)) {
450 list_del(&slab
->list
);
451 list_add_tail(&slab
->list
, &f
->partial_slabs
);
453 list_add_head(n
, &slab
->freelist
);
459 static struct node
*alloc_node(struct fuse
*f
)
461 return (struct node
*) calloc(1, get_node_size(f
));
464 static void free_node_mem(struct fuse
*f
, struct node
*node
)
471 static size_t id_hash(struct fuse
*f
, fuse_ino_t ino
)
473 uint64_t hash
= ((uint32_t) ino
* 2654435761U) % f
->id_table
.size
;
474 uint64_t oldhash
= hash
% (f
->id_table
.size
/ 2);
476 if (oldhash
>= f
->id_table
.split
)
482 static struct node
*get_node_nocheck(struct fuse
*f
, fuse_ino_t nodeid
)
484 size_t hash
= id_hash(f
, nodeid
);
487 for (node
= f
->id_table
.array
[hash
]; node
!= NULL
; node
= node
->id_next
)
488 if (node
->nodeid
== nodeid
)
494 static struct node
*get_node(struct fuse
*f
, fuse_ino_t nodeid
)
496 struct node
*node
= get_node_nocheck(f
, nodeid
);
498 fprintf(stderr
, "fuse internal error: node %llu not found\n",
499 (unsigned long long) nodeid
);
505 static void curr_time(struct timespec
*now
);
506 static double diff_timespec(const struct timespec
*t1
,
507 const struct timespec
*t2
);
509 static void remove_node_lru(struct node
*node
)
511 struct node_lru
*lnode
= node_lru(node
);
512 list_del(&lnode
->lru
);
513 init_list_head(&lnode
->lru
);
516 static void set_forget_time(struct fuse
*f
, struct node
*node
)
518 struct node_lru
*lnode
= node_lru(node
);
520 list_del(&lnode
->lru
);
521 list_add_tail(&lnode
->lru
, &f
->lru_table
);
522 curr_time(&lnode
->forget_time
);
525 static void free_node(struct fuse
*f
, struct node
*node
)
527 if (node
->name
!= node
->inline_name
)
529 free_node_mem(f
, node
);
532 static void node_table_reduce(struct node_table
*t
)
534 size_t newsize
= t
->size
/ 2;
537 if (newsize
< NODE_TABLE_MIN_SIZE
)
540 newarray
= realloc(t
->array
, sizeof(struct node
*) * newsize
);
541 if (newarray
!= NULL
)
545 t
->split
= t
->size
/ 2;
548 static void remerge_id(struct fuse
*f
)
550 struct node_table
*t
= &f
->id_table
;
554 node_table_reduce(t
);
556 for (iter
= 8; t
->split
> 0 && iter
; iter
--) {
560 upper
= &t
->array
[t
->split
+ t
->size
/ 2];
564 for (nodep
= &t
->array
[t
->split
]; *nodep
;
565 nodep
= &(*nodep
)->id_next
);
574 static void unhash_id(struct fuse
*f
, struct node
*node
)
576 struct node
**nodep
= &f
->id_table
.array
[id_hash(f
, node
->nodeid
)];
578 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->id_next
)
579 if (*nodep
== node
) {
580 *nodep
= node
->id_next
;
583 if(f
->id_table
.use
< f
->id_table
.size
/ 4)
589 static int node_table_resize(struct node_table
*t
)
591 size_t newsize
= t
->size
* 2;
594 newarray
= realloc(t
->array
, sizeof(struct node
*) * newsize
);
595 if (newarray
== NULL
)
599 memset(t
->array
+ t
->size
, 0, t
->size
* sizeof(struct node
*));
606 static void rehash_id(struct fuse
*f
)
608 struct node_table
*t
= &f
->id_table
;
613 if (t
->split
== t
->size
/ 2)
618 for (nodep
= &t
->array
[hash
]; *nodep
!= NULL
; nodep
= next
) {
619 struct node
*node
= *nodep
;
620 size_t newhash
= id_hash(f
, node
->nodeid
);
622 if (newhash
!= hash
) {
624 *nodep
= node
->id_next
;
625 node
->id_next
= t
->array
[newhash
];
626 t
->array
[newhash
] = node
;
628 next
= &node
->id_next
;
631 if (t
->split
== t
->size
/ 2)
632 node_table_resize(t
);
635 static void hash_id(struct fuse
*f
, struct node
*node
)
637 size_t hash
= id_hash(f
, node
->nodeid
);
638 node
->id_next
= f
->id_table
.array
[hash
];
639 f
->id_table
.array
[hash
] = node
;
642 if (f
->id_table
.use
>= f
->id_table
.size
/ 2)
646 static size_t name_hash(struct fuse
*f
, fuse_ino_t parent
,
649 uint64_t hash
= parent
;
652 for (; *name
; name
++)
653 hash
= hash
* 31 + (unsigned char) *name
;
655 hash
%= f
->name_table
.size
;
656 oldhash
= hash
% (f
->name_table
.size
/ 2);
657 if (oldhash
>= f
->name_table
.split
)
663 static void unref_node(struct fuse
*f
, struct node
*node
);
665 static void remerge_name(struct fuse
*f
)
667 struct node_table
*t
= &f
->name_table
;
671 node_table_reduce(t
);
673 for (iter
= 8; t
->split
> 0 && iter
; iter
--) {
677 upper
= &t
->array
[t
->split
+ t
->size
/ 2];
681 for (nodep
= &t
->array
[t
->split
]; *nodep
;
682 nodep
= &(*nodep
)->name_next
);
691 static void unhash_name(struct fuse
*f
, struct node
*node
)
694 size_t hash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
695 struct node
**nodep
= &f
->name_table
.array
[hash
];
697 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->name_next
)
698 if (*nodep
== node
) {
699 *nodep
= node
->name_next
;
700 node
->name_next
= NULL
;
701 unref_node(f
, node
->parent
);
702 if (node
->name
!= node
->inline_name
)
708 if (f
->name_table
.use
< f
->name_table
.size
/ 4)
713 "fuse internal error: unable to unhash node: %llu\n",
714 (unsigned long long) node
->nodeid
);
719 static void rehash_name(struct fuse
*f
)
721 struct node_table
*t
= &f
->name_table
;
726 if (t
->split
== t
->size
/ 2)
731 for (nodep
= &t
->array
[hash
]; *nodep
!= NULL
; nodep
= next
) {
732 struct node
*node
= *nodep
;
733 size_t newhash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
735 if (newhash
!= hash
) {
737 *nodep
= node
->name_next
;
738 node
->name_next
= t
->array
[newhash
];
739 t
->array
[newhash
] = node
;
741 next
= &node
->name_next
;
744 if (t
->split
== t
->size
/ 2)
745 node_table_resize(t
);
748 static int hash_name(struct fuse
*f
, struct node
*node
, fuse_ino_t parentid
,
751 size_t hash
= name_hash(f
, parentid
, name
);
752 struct node
*parent
= get_node(f
, parentid
);
753 if (strlen(name
) < sizeof(node
->inline_name
)) {
754 strcpy(node
->inline_name
, name
);
755 node
->name
= node
->inline_name
;
757 node
->name
= strdup(name
);
758 if (node
->name
== NULL
)
763 node
->parent
= parent
;
764 node
->name_next
= f
->name_table
.array
[hash
];
765 f
->name_table
.array
[hash
] = node
;
768 if (f
->name_table
.use
>= f
->name_table
.size
/ 2)
774 static void delete_node(struct fuse
*f
, struct node
*node
)
777 fprintf(stderr
, "DELETE: %llu\n",
778 (unsigned long long) node
->nodeid
);
780 assert(node
->treelock
== 0);
781 unhash_name(f
, node
);
783 remove_node_lru(node
);
788 static void unref_node(struct fuse
*f
, struct node
*node
)
790 assert(node
->refctr
> 0);
793 delete_node(f
, node
);
796 static fuse_ino_t
next_id(struct fuse
*f
)
799 f
->ctr
= (f
->ctr
+ 1) & 0xffffffff;
802 } while (f
->ctr
== 0 || f
->ctr
== FUSE_UNKNOWN_INO
||
803 get_node_nocheck(f
, f
->ctr
) != NULL
);
807 static struct node
*lookup_node(struct fuse
*f
, fuse_ino_t parent
,
810 size_t hash
= name_hash(f
, parent
, name
);
813 for (node
= f
->name_table
.array
[hash
]; node
!= NULL
; node
= node
->name_next
)
814 if (node
->parent
->nodeid
== parent
&&
815 strcmp(node
->name
, name
) == 0)
821 static void inc_nlookup(struct node
*node
)
828 static struct node
*find_node(struct fuse
*f
, fuse_ino_t parent
,
833 pthread_mutex_lock(&f
->lock
);
835 node
= get_node(f
, parent
);
837 node
= lookup_node(f
, parent
, name
);
839 node
= alloc_node(f
);
843 node
->nodeid
= next_id(f
);
844 node
->generation
= f
->generation
;
845 if (f
->conf
.remember
)
848 if (hash_name(f
, node
, parent
, name
) == -1) {
854 if (lru_enabled(f
)) {
855 struct node_lru
*lnode
= node_lru(node
);
856 init_list_head(&lnode
->lru
);
858 } else if (lru_enabled(f
) && node
->nlookup
== 1) {
859 remove_node_lru(node
);
863 pthread_mutex_unlock(&f
->lock
);
867 static char *add_name(char **buf
, unsigned *bufsize
, char *s
, const char *name
)
869 size_t len
= strlen(name
);
871 if (s
- len
<= *buf
) {
872 unsigned pathlen
= *bufsize
- (s
- *buf
);
873 unsigned newbufsize
= *bufsize
;
876 while (newbufsize
< pathlen
+ len
+ 1) {
877 if (newbufsize
>= 0x80000000)
878 newbufsize
= 0xffffffff;
883 newbuf
= realloc(*buf
, newbufsize
);
888 s
= newbuf
+ newbufsize
- pathlen
;
889 memmove(s
, newbuf
+ *bufsize
- pathlen
, pathlen
);
890 *bufsize
= newbufsize
;
893 strncpy(s
, name
, len
);
900 static void unlock_path(struct fuse
*f
, fuse_ino_t nodeid
, struct node
*wnode
,
901 struct node
*end
, int ticket
)
906 assert(wnode
->treelock
== -1);
909 wnode
->ticket
= ticket
;
912 for (node
= get_node(f
, nodeid
);
913 node
!= end
&& node
->nodeid
!= FUSE_ROOT_ID
; node
= node
->parent
) {
914 assert(node
->treelock
> 0);
917 node
->ticket
= ticket
;
921 static void release_tickets(struct fuse
*f
, fuse_ino_t nodeid
,
922 struct node
*wnode
, int ticket
)
927 if (wnode
->ticket
!= ticket
)
933 for (node
= get_node(f
, nodeid
);
934 node
->nodeid
!= FUSE_ROOT_ID
; node
= node
->parent
) {
935 if (node
->ticket
!= ticket
)
941 static int try_get_path(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
942 char **path
, struct node
**wnodep
, int ticket
)
944 unsigned bufsize
= 256;
948 struct node
*wnode
= NULL
;
954 buf
= malloc(bufsize
);
958 s
= buf
+ bufsize
- 1;
962 s
= add_name(&buf
, &bufsize
, s
, name
);
970 wnode
= lookup_node(f
, nodeid
, name
);
972 if (wnode
->treelock
!= 0 ||
973 (wnode
->ticket
&& wnode
->ticket
!= ticket
)) {
975 wnode
->ticket
= ticket
;
979 wnode
->treelock
= -1;
984 for (node
= get_node(f
, nodeid
); node
->nodeid
!= FUSE_ROOT_ID
;
985 node
= node
->parent
) {
987 if (node
->name
== NULL
|| node
->parent
== NULL
)
991 s
= add_name(&buf
, &bufsize
, s
, node
->name
);
997 if (node
->treelock
== -1 ||
998 (node
->ticket
&& node
->ticket
!= ticket
))
1007 memmove(buf
, s
, bufsize
- (s
- buf
));
1019 unlock_path(f
, nodeid
, wnode
, node
, ticket
);
1024 if (ticket
&& err
!= -EAGAIN
)
1025 release_tickets(f
, nodeid
, wnode
, ticket
);
1030 static void wake_up_first(struct fuse
*f
)
1033 pthread_cond_signal(&f
->lockq
->cond
);
1036 static void wake_up_next(struct lock_queue_element
*qe
)
1039 pthread_cond_signal(&qe
->next
->cond
);
1042 static int get_ticket(struct fuse
*f
)
1044 do f
->curr_ticket
++;
1045 while (f
->curr_ticket
== 0);
1047 return f
->curr_ticket
;
1050 static void debug_path(struct fuse
*f
, const char *msg
, fuse_ino_t nodeid
,
1051 const char *name
, int wr
)
1053 if (f
->conf
.debug
) {
1054 struct node
*wnode
= NULL
;
1057 wnode
= lookup_node(f
, nodeid
, name
);
1060 fprintf(stderr
, "%s %li (w)\n", msg
, wnode
->nodeid
);
1062 fprintf(stderr
, "%s %li\n", msg
, nodeid
);
1066 static void queue_path(struct fuse
*f
, struct lock_queue_element
*qe
,
1067 fuse_ino_t nodeid
, const char *name
, int wr
)
1069 struct lock_queue_element
**qp
;
1071 debug_path(f
, "QUEUE PATH", nodeid
, name
, wr
);
1072 pthread_cond_init(&qe
->cond
, NULL
);
1074 for (qp
= &f
->lockq
; *qp
!= NULL
; qp
= &(*qp
)->next
);
1078 static void dequeue_path(struct fuse
*f
, struct lock_queue_element
*qe
,
1079 fuse_ino_t nodeid
, const char *name
, int wr
)
1081 struct lock_queue_element
**qp
;
1083 debug_path(f
, "DEQUEUE PATH", nodeid
, name
, wr
);
1084 pthread_cond_destroy(&qe
->cond
);
1085 for (qp
= &f
->lockq
; *qp
!= qe
; qp
= &(*qp
)->next
);
1089 static void wait_on_path(struct fuse
*f
, struct lock_queue_element
*qe
,
1090 fuse_ino_t nodeid
, const char *name
, int wr
)
1092 debug_path(f
, "WAIT ON PATH", nodeid
, name
, wr
);
1093 pthread_cond_wait(&qe
->cond
, &f
->lock
);
1096 static int get_path_common(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1097 char **path
, struct node
**wnode
)
1102 pthread_mutex_lock(&f
->lock
);
1103 ticket
= get_ticket(f
);
1104 err
= try_get_path(f
, nodeid
, name
, path
, wnode
, ticket
);
1105 if (err
== -EAGAIN
) {
1106 struct lock_queue_element qe
;
1108 queue_path(f
, &qe
, nodeid
, name
, !!wnode
);
1110 wait_on_path(f
, &qe
, nodeid
, name
, !!wnode
);
1111 err
= try_get_path(f
, nodeid
, name
, path
, wnode
,
1114 } while (err
== -EAGAIN
);
1115 dequeue_path(f
, &qe
, nodeid
, name
, !!wnode
);
1117 pthread_mutex_unlock(&f
->lock
);
1122 static int get_path(struct fuse
*f
, fuse_ino_t nodeid
, char **path
)
1124 return get_path_common(f
, nodeid
, NULL
, path
, NULL
);
1127 static int get_path_nullok(struct fuse
*f
, fuse_ino_t nodeid
, char **path
)
1131 if (f
->conf
.nopath
) {
1134 err
= get_path_common(f
, nodeid
, NULL
, path
, NULL
);
1135 if (err
== -ENOENT
&& f
->nullpath_ok
)
1142 static int get_path_name(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1145 return get_path_common(f
, nodeid
, name
, path
, NULL
);
1148 static int get_path_wrlock(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1149 char **path
, struct node
**wnode
)
1151 return get_path_common(f
, nodeid
, name
, path
, wnode
);
1154 static int try_get_path2(struct fuse
*f
, fuse_ino_t nodeid1
, const char *name1
,
1155 fuse_ino_t nodeid2
, const char *name2
,
1156 char **path1
, char **path2
,
1157 struct node
**wnode1
, struct node
**wnode2
,
1162 /* FIXME: locking two paths needs deadlock checking */
1163 err
= try_get_path(f
, nodeid1
, name1
, path1
, wnode1
, ticket
);
1165 err
= try_get_path(f
, nodeid2
, name2
, path2
, wnode2
, ticket
);
1167 struct node
*wn1
= wnode1
? *wnode1
: NULL
;
1169 unlock_path(f
, nodeid1
, wn1
, NULL
, ticket
);
1171 if (ticket
&& err
!= -EAGAIN
)
1172 release_tickets(f
, nodeid1
, wn1
, ticket
);
1178 static int get_path2(struct fuse
*f
, fuse_ino_t nodeid1
, const char *name1
,
1179 fuse_ino_t nodeid2
, const char *name2
,
1180 char **path1
, char **path2
,
1181 struct node
**wnode1
, struct node
**wnode2
)
1186 pthread_mutex_lock(&f
->lock
);
1187 ticket
= get_ticket(f
);
1188 err
= try_get_path2(f
, nodeid1
, name1
, nodeid2
, name2
,
1189 path1
, path2
, wnode1
, wnode2
, ticket
);
1190 if (err
== -EAGAIN
) {
1191 struct lock_queue_element qe
;
1193 queue_path(f
, &qe
, nodeid1
, name1
, !!wnode1
);
1194 debug_path(f
, " path2", nodeid2
, name2
, !!wnode2
);
1196 wait_on_path(f
, &qe
, nodeid1
, name1
, !!wnode1
);
1197 debug_path(f
, " path2", nodeid2
, name2
, !!wnode2
);
1198 err
= try_get_path2(f
, nodeid1
, name1
, nodeid2
, name2
,
1199 path1
, path2
, wnode1
, wnode2
,
1202 } while (err
== -EAGAIN
);
1203 dequeue_path(f
, &qe
, nodeid1
, name1
, !!wnode1
);
1204 debug_path(f
, " path2", nodeid2
, name2
, !!wnode2
);
1206 pthread_mutex_unlock(&f
->lock
);
1211 static void free_path_wrlock(struct fuse
*f
, fuse_ino_t nodeid
,
1212 struct node
*wnode
, char *path
)
1214 pthread_mutex_lock(&f
->lock
);
1215 unlock_path(f
, nodeid
, wnode
, NULL
, 0);
1217 pthread_mutex_unlock(&f
->lock
);
1221 static void free_path(struct fuse
*f
, fuse_ino_t nodeid
, char *path
)
1224 free_path_wrlock(f
, nodeid
, NULL
, path
);
1227 static void free_path2(struct fuse
*f
, fuse_ino_t nodeid1
, fuse_ino_t nodeid2
,
1228 struct node
*wnode1
, struct node
*wnode2
,
1229 char *path1
, char *path2
)
1231 pthread_mutex_lock(&f
->lock
);
1232 unlock_path(f
, nodeid1
, wnode1
, NULL
, 0);
1233 unlock_path(f
, nodeid2
, wnode2
, NULL
, 0);
1235 pthread_mutex_unlock(&f
->lock
);
1240 static void forget_node(struct fuse
*f
, fuse_ino_t nodeid
, uint64_t nlookup
)
1243 if (nodeid
== FUSE_ROOT_ID
)
1245 pthread_mutex_lock(&f
->lock
);
1246 node
= get_node(f
, nodeid
);
1249 * Node may still be locked due to interrupt idiocy in open,
1250 * create and opendir
1252 while (node
->nlookup
== nlookup
&& node
->treelock
) {
1253 struct lock_queue_element qe
;
1255 queue_path(f
, &qe
, node
->nodeid
, NULL
, 0);
1257 wait_on_path(f
, &qe
, node
->nodeid
, NULL
, 0);
1260 } while (node
->nlookup
== nlookup
&& node
->treelock
);
1261 dequeue_path(f
, &qe
, node
->nodeid
, NULL
, 0);
1264 assert(node
->nlookup
>= nlookup
);
1265 node
->nlookup
-= nlookup
;
1266 if (!node
->nlookup
) {
1267 unref_node(f
, node
);
1268 } else if (lru_enabled(f
) && node
->nlookup
== 1) {
1269 set_forget_time(f
, node
);
1271 pthread_mutex_unlock(&f
->lock
);
1274 static void unlink_node(struct fuse
*f
, struct node
*node
)
1276 if (f
->conf
.remember
) {
1277 assert(node
->nlookup
> 1);
1280 unhash_name(f
, node
);
1283 static void remove_node(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
1287 pthread_mutex_lock(&f
->lock
);
1288 node
= lookup_node(f
, dir
, name
);
1290 unlink_node(f
, node
);
1291 pthread_mutex_unlock(&f
->lock
);
1294 static int rename_node(struct fuse
*f
, fuse_ino_t olddir
, const char *oldname
,
1295 fuse_ino_t newdir
, const char *newname
, int hide
)
1298 struct node
*newnode
;
1301 pthread_mutex_lock(&f
->lock
);
1302 node
= lookup_node(f
, olddir
, oldname
);
1303 newnode
= lookup_node(f
, newdir
, newname
);
1307 if (newnode
!= NULL
) {
1309 fprintf(stderr
, "fuse: hidden file got created during hiding\n");
1313 unlink_node(f
, newnode
);
1316 unhash_name(f
, node
);
1317 if (hash_name(f
, node
, newdir
, newname
) == -1) {
1323 node
->is_hidden
= 1;
1326 pthread_mutex_unlock(&f
->lock
);
1330 static void set_stat(struct fuse
*f
, fuse_ino_t nodeid
, struct stat
*stbuf
)
1332 if (!f
->conf
.use_ino
)
1333 stbuf
->st_ino
= nodeid
;
1334 if (f
->conf
.set_mode
)
1335 stbuf
->st_mode
= (stbuf
->st_mode
& S_IFMT
) |
1336 (0777 & ~f
->conf
.umask
);
1337 if (f
->conf
.set_uid
)
1338 stbuf
->st_uid
= f
->conf
.uid
;
1339 if (f
->conf
.set_gid
)
1340 stbuf
->st_gid
= f
->conf
.gid
;
1343 static struct fuse
*req_fuse(fuse_req_t req
)
1345 return (struct fuse
*) fuse_req_userdata(req
);
1348 static void fuse_intr_sighandler(int sig
)
1354 struct fuse_intr_data
{
1356 pthread_cond_t cond
;
1360 static void fuse_interrupt(fuse_req_t req
, void *d_
)
1362 struct fuse_intr_data
*d
= d_
;
1363 struct fuse
*f
= req_fuse(req
);
1365 if (d
->id
== pthread_self())
1368 pthread_mutex_lock(&f
->lock
);
1369 while (!d
->finished
) {
1371 struct timespec timeout
;
1373 pthread_kill(d
->id
, f
->conf
.intr_signal
);
1374 gettimeofday(&now
, NULL
);
1375 timeout
.tv_sec
= now
.tv_sec
+ 1;
1376 timeout
.tv_nsec
= now
.tv_usec
* 1000;
1377 pthread_cond_timedwait(&d
->cond
, &f
->lock
, &timeout
);
1379 pthread_mutex_unlock(&f
->lock
);
1382 static void fuse_do_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
1383 struct fuse_intr_data
*d
)
1385 pthread_mutex_lock(&f
->lock
);
1387 pthread_cond_broadcast(&d
->cond
);
1388 pthread_mutex_unlock(&f
->lock
);
1389 fuse_req_interrupt_func(req
, NULL
, NULL
);
1390 pthread_cond_destroy(&d
->cond
);
1393 static void fuse_do_prepare_interrupt(fuse_req_t req
, struct fuse_intr_data
*d
)
1395 d
->id
= pthread_self();
1396 pthread_cond_init(&d
->cond
, NULL
);
1398 fuse_req_interrupt_func(req
, fuse_interrupt
, d
);
1401 static inline void fuse_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
1402 struct fuse_intr_data
*d
)
1405 fuse_do_finish_interrupt(f
, req
, d
);
1408 static inline void fuse_prepare_interrupt(struct fuse
*f
, fuse_req_t req
,
1409 struct fuse_intr_data
*d
)
1412 fuse_do_prepare_interrupt(req
, d
);
1415 #if !defined(__FreeBSD__) && !defined(__NetBSD__)
1417 static int fuse_compat_open(struct fuse_fs
*fs
, const char *path
,
1418 struct fuse_file_info
*fi
)
1421 if (!fs
->compat
|| fs
->compat
>= 25)
1422 err
= fs
->op
.open(path
, fi
);
1423 else if (fs
->compat
== 22) {
1424 struct fuse_file_info_compat tmp
;
1425 memcpy(&tmp
, fi
, sizeof(tmp
));
1426 err
= ((struct fuse_operations_compat22
*) &fs
->op
)->open(path
,
1428 memcpy(fi
, &tmp
, sizeof(tmp
));
1431 err
= ((struct fuse_operations_compat2
*) &fs
->op
)
1432 ->open(path
, fi
->flags
);
1436 static int fuse_compat_release(struct fuse_fs
*fs
, const char *path
,
1437 struct fuse_file_info
*fi
)
1439 if (!fs
->compat
|| fs
->compat
>= 22)
1440 return fs
->op
.release(path
, fi
);
1442 return ((struct fuse_operations_compat2
*) &fs
->op
)
1443 ->release(path
, fi
->flags
);
1446 static int fuse_compat_opendir(struct fuse_fs
*fs
, const char *path
,
1447 struct fuse_file_info
*fi
)
1449 if (!fs
->compat
|| fs
->compat
>= 25)
1450 return fs
->op
.opendir(path
, fi
);
1453 struct fuse_file_info_compat tmp
;
1454 memcpy(&tmp
, fi
, sizeof(tmp
));
1455 err
= ((struct fuse_operations_compat22
*) &fs
->op
)
1456 ->opendir(path
, &tmp
);
1457 memcpy(fi
, &tmp
, sizeof(tmp
));
1463 static void convert_statfs_compat(struct fuse_statfs_compat1
*compatbuf
,
1464 struct statvfs
*stbuf
)
1466 stbuf
->f_bsize
= compatbuf
->block_size
;
1467 stbuf
->f_blocks
= compatbuf
->blocks
;
1468 stbuf
->f_bfree
= compatbuf
->blocks_free
;
1469 stbuf
->f_bavail
= compatbuf
->blocks_free
;
1470 stbuf
->f_files
= compatbuf
->files
;
1471 stbuf
->f_ffree
= compatbuf
->files_free
;
1472 stbuf
->f_namemax
= compatbuf
->namelen
;
1475 static void convert_statfs_old(struct statfs
*oldbuf
, struct statvfs
*stbuf
)
1477 stbuf
->f_bsize
= oldbuf
->f_bsize
;
1478 stbuf
->f_blocks
= oldbuf
->f_blocks
;
1479 stbuf
->f_bfree
= oldbuf
->f_bfree
;
1480 stbuf
->f_bavail
= oldbuf
->f_bavail
;
1481 stbuf
->f_files
= oldbuf
->f_files
;
1482 stbuf
->f_ffree
= oldbuf
->f_ffree
;
1483 stbuf
->f_namemax
= oldbuf
->f_namelen
;
1486 static int fuse_compat_statfs(struct fuse_fs
*fs
, const char *path
,
1487 struct statvfs
*buf
)
1491 if (!fs
->compat
|| fs
->compat
>= 25) {
1492 err
= fs
->op
.statfs(fs
->compat
== 25 ? "/" : path
, buf
);
1493 } else if (fs
->compat
> 11) {
1494 struct statfs oldbuf
;
1495 err
= ((struct fuse_operations_compat22
*) &fs
->op
)
1496 ->statfs("/", &oldbuf
);
1498 convert_statfs_old(&oldbuf
, buf
);
1500 struct fuse_statfs_compat1 compatbuf
;
1501 memset(&compatbuf
, 0, sizeof(struct fuse_statfs_compat1
));
1502 err
= ((struct fuse_operations_compat1
*) &fs
->op
)
1503 ->statfs(&compatbuf
);
1505 convert_statfs_compat(&compatbuf
, buf
);
1510 #else /* __FreeBSD__ || __NetBSD__ */
1512 static inline int fuse_compat_open(struct fuse_fs
*fs
, char *path
,
1513 struct fuse_file_info
*fi
)
1515 return fs
->op
.open(path
, fi
);
1518 static inline int fuse_compat_release(struct fuse_fs
*fs
, const char *path
,
1519 struct fuse_file_info
*fi
)
1521 return fs
->op
.release(path
, fi
);
1524 static inline int fuse_compat_opendir(struct fuse_fs
*fs
, const char *path
,
1525 struct fuse_file_info
*fi
)
1527 return fs
->op
.opendir(path
, fi
);
1530 static inline int fuse_compat_statfs(struct fuse_fs
*fs
, const char *path
,
1531 struct statvfs
*buf
)
1533 return fs
->op
.statfs(fs
->compat
== 25 ? "/" : path
, buf
);
1536 #endif /* __FreeBSD__ || __NetBSD__ */
1538 int fuse_fs_getattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
)
1540 fuse_get_context()->private_data
= fs
->user_data
;
1541 if (fs
->op
.getattr
) {
1543 fprintf(stderr
, "getattr %s\n", path
);
1545 return fs
->op
.getattr(path
, buf
);
1551 int fuse_fs_fgetattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
,
1552 struct fuse_file_info
*fi
)
1554 fuse_get_context()->private_data
= fs
->user_data
;
1555 if (fs
->op
.fgetattr
) {
1557 fprintf(stderr
, "fgetattr[%llu] %s\n",
1558 (unsigned long long) fi
->fh
, path
);
1560 return fs
->op
.fgetattr(path
, buf
, fi
);
1561 } else if (path
&& fs
->op
.getattr
) {
1563 fprintf(stderr
, "getattr %s\n", path
);
1565 return fs
->op
.getattr(path
, buf
);
1571 int fuse_fs_rename(struct fuse_fs
*fs
, const char *oldpath
,
1572 const char *newpath
)
1574 fuse_get_context()->private_data
= fs
->user_data
;
1575 if (fs
->op
.rename
) {
1577 fprintf(stderr
, "rename %s %s\n", oldpath
, newpath
);
1579 return fs
->op
.rename(oldpath
, newpath
);
1585 int fuse_fs_unlink(struct fuse_fs
*fs
, const char *path
)
1587 fuse_get_context()->private_data
= fs
->user_data
;
1588 if (fs
->op
.unlink
) {
1590 fprintf(stderr
, "unlink %s\n", path
);
1592 return fs
->op
.unlink(path
);
1598 int fuse_fs_rmdir(struct fuse_fs
*fs
, const char *path
)
1600 fuse_get_context()->private_data
= fs
->user_data
;
1603 fprintf(stderr
, "rmdir %s\n", path
);
1605 return fs
->op
.rmdir(path
);
1611 int fuse_fs_symlink(struct fuse_fs
*fs
, const char *linkname
, const char *path
)
1613 fuse_get_context()->private_data
= fs
->user_data
;
1614 if (fs
->op
.symlink
) {
1616 fprintf(stderr
, "symlink %s %s\n", linkname
, path
);
1618 return fs
->op
.symlink(linkname
, path
);
1624 int fuse_fs_link(struct fuse_fs
*fs
, const char *oldpath
, const char *newpath
)
1626 fuse_get_context()->private_data
= fs
->user_data
;
1629 fprintf(stderr
, "link %s %s\n", oldpath
, newpath
);
1631 return fs
->op
.link(oldpath
, newpath
);
1637 int fuse_fs_release(struct fuse_fs
*fs
, const char *path
,
1638 struct fuse_file_info
*fi
)
1640 fuse_get_context()->private_data
= fs
->user_data
;
1641 if (fs
->op
.release
) {
1643 fprintf(stderr
, "release%s[%llu] flags: 0x%x\n",
1644 fi
->flush
? "+flush" : "",
1645 (unsigned long long) fi
->fh
, fi
->flags
);
1647 return fuse_compat_release(fs
, path
, fi
);
1653 int fuse_fs_opendir(struct fuse_fs
*fs
, const char *path
,
1654 struct fuse_file_info
*fi
)
1656 fuse_get_context()->private_data
= fs
->user_data
;
1657 if (fs
->op
.opendir
) {
1661 fprintf(stderr
, "opendir flags: 0x%x %s\n", fi
->flags
,
1664 err
= fuse_compat_opendir(fs
, path
, fi
);
1666 if (fs
->debug
&& !err
)
1667 fprintf(stderr
, " opendir[%lli] flags: 0x%x %s\n",
1668 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1676 int fuse_fs_open(struct fuse_fs
*fs
, const char *path
,
1677 struct fuse_file_info
*fi
)
1679 fuse_get_context()->private_data
= fs
->user_data
;
1684 fprintf(stderr
, "open flags: 0x%x %s\n", fi
->flags
,
1687 err
= fuse_compat_open(fs
, path
, fi
);
1689 if (fs
->debug
&& !err
)
1690 fprintf(stderr
, " open[%lli] flags: 0x%x %s\n",
1691 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1699 static void fuse_free_buf(struct fuse_bufvec
*buf
)
1704 for (i
= 0; i
< buf
->count
; i
++)
1705 free(buf
->buf
[i
].mem
);
1710 int fuse_fs_read_buf(struct fuse_fs
*fs
, const char *path
,
1711 struct fuse_bufvec
**bufp
, size_t size
, off_t off
,
1712 struct fuse_file_info
*fi
)
1714 fuse_get_context()->private_data
= fs
->user_data
;
1715 if (fs
->op
.read
|| fs
->op
.read_buf
) {
1720 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1721 (unsigned long long) fi
->fh
,
1722 size
, (unsigned long long) off
, fi
->flags
);
1724 if (fs
->op
.read_buf
) {
1725 res
= fs
->op
.read_buf(path
, bufp
, size
, off
, fi
);
1727 struct fuse_bufvec
*buf
;
1730 buf
= malloc(sizeof(struct fuse_bufvec
));
1739 *buf
= FUSE_BUFVEC_INIT(size
);
1740 buf
->buf
[0].mem
= mem
;
1743 res
= fs
->op
.read(path
, mem
, size
, off
, fi
);
1745 buf
->buf
[0].size
= res
;
1748 if (fs
->debug
&& res
>= 0)
1749 fprintf(stderr
, " read[%llu] %zu bytes from %llu\n",
1750 (unsigned long long) fi
->fh
,
1751 fuse_buf_size(*bufp
),
1752 (unsigned long long) off
);
1753 if (res
>= 0 && fuse_buf_size(*bufp
) > (int) size
)
1754 fprintf(stderr
, "fuse: read too many bytes\n");
1765 int fuse_fs_read(struct fuse_fs
*fs
, const char *path
, char *mem
, size_t size
,
1766 off_t off
, struct fuse_file_info
*fi
)
1769 struct fuse_bufvec
*buf
= NULL
;
1771 res
= fuse_fs_read_buf(fs
, path
, &buf
, size
, off
, fi
);
1773 struct fuse_bufvec dst
= FUSE_BUFVEC_INIT(size
);
1775 dst
.buf
[0].mem
= mem
;
1776 res
= fuse_buf_copy(&dst
, buf
, 0);
1783 int fuse_fs_write_buf(struct fuse_fs
*fs
, const char *path
,
1784 struct fuse_bufvec
*buf
, off_t off
,
1785 struct fuse_file_info
*fi
)
1787 fuse_get_context()->private_data
= fs
->user_data
;
1788 if (fs
->op
.write_buf
|| fs
->op
.write
) {
1790 size_t size
= fuse_buf_size(buf
);
1792 assert(buf
->idx
== 0 && buf
->off
== 0);
1795 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1796 fi
->writepage
? "page" : "",
1797 (unsigned long long) fi
->fh
,
1799 (unsigned long long) off
,
1802 if (fs
->op
.write_buf
) {
1803 res
= fs
->op
.write_buf(path
, buf
, off
, fi
);
1806 struct fuse_buf
*flatbuf
;
1807 struct fuse_bufvec tmp
= FUSE_BUFVEC_INIT(size
);
1809 if (buf
->count
== 1 &&
1810 !(buf
->buf
[0].flags
& FUSE_BUF_IS_FD
)) {
1811 flatbuf
= &buf
->buf
[0];
1818 tmp
.buf
[0].mem
= mem
;
1819 res
= fuse_buf_copy(&tmp
, buf
, 0);
1823 tmp
.buf
[0].size
= res
;
1824 flatbuf
= &tmp
.buf
[0];
1827 res
= fs
->op
.write(path
, flatbuf
->mem
, flatbuf
->size
,
1833 if (fs
->debug
&& res
>= 0)
1834 fprintf(stderr
, " write%s[%llu] %u bytes to %llu\n",
1835 fi
->writepage
? "page" : "",
1836 (unsigned long long) fi
->fh
, res
,
1837 (unsigned long long) off
);
1838 if (res
> (int) size
)
1839 fprintf(stderr
, "fuse: wrote too many bytes\n");
1847 int fuse_fs_write(struct fuse_fs
*fs
, const char *path
, const char *mem
,
1848 size_t size
, off_t off
, struct fuse_file_info
*fi
)
1850 struct fuse_bufvec bufv
= FUSE_BUFVEC_INIT(size
);
1852 bufv
.buf
[0].mem
= (void *) mem
;
1854 return fuse_fs_write_buf(fs
, path
, &bufv
, off
, fi
);
1857 int fuse_fs_fsync(struct fuse_fs
*fs
, const char *path
, int datasync
,
1858 struct fuse_file_info
*fi
)
1860 fuse_get_context()->private_data
= fs
->user_data
;
1863 fprintf(stderr
, "fsync[%llu] datasync: %i\n",
1864 (unsigned long long) fi
->fh
, datasync
);
1866 return fs
->op
.fsync(path
, datasync
, fi
);
1872 int fuse_fs_fsyncdir(struct fuse_fs
*fs
, const char *path
, int datasync
,
1873 struct fuse_file_info
*fi
)
1875 fuse_get_context()->private_data
= fs
->user_data
;
1876 if (fs
->op
.fsyncdir
) {
1878 fprintf(stderr
, "fsyncdir[%llu] datasync: %i\n",
1879 (unsigned long long) fi
->fh
, datasync
);
1881 return fs
->op
.fsyncdir(path
, datasync
, fi
);
1887 int fuse_fs_flush(struct fuse_fs
*fs
, const char *path
,
1888 struct fuse_file_info
*fi
)
1890 fuse_get_context()->private_data
= fs
->user_data
;
1893 fprintf(stderr
, "flush[%llu]\n",
1894 (unsigned long long) fi
->fh
);
1896 return fs
->op
.flush(path
, fi
);
1902 int fuse_fs_statfs(struct fuse_fs
*fs
, const char *path
, struct statvfs
*buf
)
1904 fuse_get_context()->private_data
= fs
->user_data
;
1905 if (fs
->op
.statfs
) {
1907 fprintf(stderr
, "statfs %s\n", path
);
1909 return fuse_compat_statfs(fs
, path
, buf
);
1911 buf
->f_namemax
= 255;
1917 int fuse_fs_releasedir(struct fuse_fs
*fs
, const char *path
,
1918 struct fuse_file_info
*fi
)
1920 fuse_get_context()->private_data
= fs
->user_data
;
1921 if (fs
->op
.releasedir
) {
1923 fprintf(stderr
, "releasedir[%llu] flags: 0x%x\n",
1924 (unsigned long long) fi
->fh
, fi
->flags
);
1926 return fs
->op
.releasedir(path
, fi
);
1932 static int fill_dir_old(struct fuse_dirhandle
*dh
, const char *name
, int type
,
1938 memset(&stbuf
, 0, sizeof(stbuf
));
1939 stbuf
.st_mode
= type
<< 12;
1942 res
= dh
->filler(dh
->buf
, name
, &stbuf
, 0);
1943 return res
? -ENOMEM
: 0;
1946 int fuse_fs_readdir(struct fuse_fs
*fs
, const char *path
, void *buf
,
1947 fuse_fill_dir_t filler
, off_t off
,
1948 struct fuse_file_info
*fi
)
1950 fuse_get_context()->private_data
= fs
->user_data
;
1951 if (fs
->op
.readdir
) {
1953 fprintf(stderr
, "readdir[%llu] from %llu\n",
1954 (unsigned long long) fi
->fh
,
1955 (unsigned long long) off
);
1957 return fs
->op
.readdir(path
, buf
, filler
, off
, fi
);
1958 } else if (fs
->op
.getdir
) {
1959 struct fuse_dirhandle dh
;
1962 fprintf(stderr
, "getdir[%llu]\n",
1963 (unsigned long long) fi
->fh
);
1967 return fs
->op
.getdir(path
, &dh
, fill_dir_old
);
1973 int fuse_fs_create(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
1974 struct fuse_file_info
*fi
)
1976 fuse_get_context()->private_data
= fs
->user_data
;
1977 if (fs
->op
.create
) {
1982 "create flags: 0x%x %s 0%o umask=0%03o\n",
1983 fi
->flags
, path
, mode
,
1984 fuse_get_context()->umask
);
1986 err
= fs
->op
.create(path
, mode
, fi
);
1988 if (fs
->debug
&& !err
)
1989 fprintf(stderr
, " create[%llu] flags: 0x%x %s\n",
1990 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1998 int fuse_fs_lock(struct fuse_fs
*fs
, const char *path
,
1999 struct fuse_file_info
*fi
, int cmd
, struct flock
*lock
)
2001 fuse_get_context()->private_data
= fs
->user_data
;
2004 fprintf(stderr
, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2005 (unsigned long long) fi
->fh
,
2006 (cmd
== F_GETLK
? "F_GETLK" :
2007 (cmd
== F_SETLK
? "F_SETLK" :
2008 (cmd
== F_SETLKW
? "F_SETLKW" : "???"))),
2009 (lock
->l_type
== F_RDLCK
? "F_RDLCK" :
2010 (lock
->l_type
== F_WRLCK
? "F_WRLCK" :
2011 (lock
->l_type
== F_UNLCK
? "F_UNLCK" :
2013 (unsigned long long) lock
->l_start
,
2014 (unsigned long long) lock
->l_len
,
2015 (unsigned long long) lock
->l_pid
);
2017 return fs
->op
.lock(path
, fi
, cmd
, lock
);
2023 int fuse_fs_flock(struct fuse_fs
*fs
, const char *path
,
2024 struct fuse_file_info
*fi
, int op
)
2026 fuse_get_context()->private_data
= fs
->user_data
;
2029 int xop
= op
& ~LOCK_NB
;
2031 fprintf(stderr
, "lock[%llu] %s%s\n",
2032 (unsigned long long) fi
->fh
,
2033 xop
== LOCK_SH
? "LOCK_SH" :
2034 (xop
== LOCK_EX
? "LOCK_EX" :
2035 (xop
== LOCK_UN
? "LOCK_UN" : "???")),
2036 (op
& LOCK_NB
) ? "|LOCK_NB" : "");
2038 return fs
->op
.flock(path
, fi
, op
);
2044 int fuse_fs_chown(struct fuse_fs
*fs
, const char *path
, uid_t uid
, gid_t gid
)
2046 fuse_get_context()->private_data
= fs
->user_data
;
2049 fprintf(stderr
, "chown %s %lu %lu\n", path
,
2050 (unsigned long) uid
, (unsigned long) gid
);
2052 return fs
->op
.chown(path
, uid
, gid
);
2058 int fuse_fs_truncate(struct fuse_fs
*fs
, const char *path
, off_t size
)
2060 fuse_get_context()->private_data
= fs
->user_data
;
2061 if (fs
->op
.truncate
) {
2063 fprintf(stderr
, "truncate %s %llu\n", path
,
2064 (unsigned long long) size
);
2066 return fs
->op
.truncate(path
, size
);
2072 int fuse_fs_ftruncate(struct fuse_fs
*fs
, const char *path
, off_t size
,
2073 struct fuse_file_info
*fi
)
2075 fuse_get_context()->private_data
= fs
->user_data
;
2076 if (fs
->op
.ftruncate
) {
2078 fprintf(stderr
, "ftruncate[%llu] %llu\n",
2079 (unsigned long long) fi
->fh
,
2080 (unsigned long long) size
);
2082 return fs
->op
.ftruncate(path
, size
, fi
);
2083 } else if (path
&& fs
->op
.truncate
) {
2085 fprintf(stderr
, "truncate %s %llu\n", path
,
2086 (unsigned long long) size
);
2088 return fs
->op
.truncate(path
, size
);
2094 int fuse_fs_utimens(struct fuse_fs
*fs
, const char *path
,
2095 const struct timespec tv
[2])
2097 fuse_get_context()->private_data
= fs
->user_data
;
2098 if (fs
->op
.utimens
) {
2100 fprintf(stderr
, "utimens %s %li.%09lu %li.%09lu\n",
2101 path
, tv
[0].tv_sec
, tv
[0].tv_nsec
,
2102 tv
[1].tv_sec
, tv
[1].tv_nsec
);
2104 return fs
->op
.utimens(path
, tv
);
2105 } else if(fs
->op
.utime
) {
2109 fprintf(stderr
, "utime %s %li %li\n", path
,
2110 tv
[0].tv_sec
, tv
[1].tv_sec
);
2112 buf
.actime
= tv
[0].tv_sec
;
2113 buf
.modtime
= tv
[1].tv_sec
;
2114 return fs
->op
.utime(path
, &buf
);
2120 int fuse_fs_access(struct fuse_fs
*fs
, const char *path
, int mask
)
2122 fuse_get_context()->private_data
= fs
->user_data
;
2123 if (fs
->op
.access
) {
2125 fprintf(stderr
, "access %s 0%o\n", path
, mask
);
2127 return fs
->op
.access(path
, mask
);
2133 int fuse_fs_readlink(struct fuse_fs
*fs
, const char *path
, char *buf
,
2136 fuse_get_context()->private_data
= fs
->user_data
;
2137 if (fs
->op
.readlink
) {
2139 fprintf(stderr
, "readlink %s %lu\n", path
,
2140 (unsigned long) len
);
2142 return fs
->op
.readlink(path
, buf
, len
);
2148 int fuse_fs_mknod(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
2151 fuse_get_context()->private_data
= fs
->user_data
;
2154 fprintf(stderr
, "mknod %s 0%o 0x%llx umask=0%03o\n",
2155 path
, mode
, (unsigned long long) rdev
,
2156 fuse_get_context()->umask
);
2158 return fs
->op
.mknod(path
, mode
, rdev
);
2164 int fuse_fs_mkdir(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
2166 fuse_get_context()->private_data
= fs
->user_data
;
2169 fprintf(stderr
, "mkdir %s 0%o umask=0%03o\n",
2170 path
, mode
, fuse_get_context()->umask
);
2172 return fs
->op
.mkdir(path
, mode
);
2178 int fuse_fs_setxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
2179 const char *value
, size_t size
, int flags
)
2181 fuse_get_context()->private_data
= fs
->user_data
;
2182 if (fs
->op
.setxattr
) {
2184 fprintf(stderr
, "setxattr %s %s %lu 0x%x\n",
2185 path
, name
, (unsigned long) size
, flags
);
2187 return fs
->op
.setxattr(path
, name
, value
, size
, flags
);
2193 int fuse_fs_getxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
2194 char *value
, size_t size
)
2196 fuse_get_context()->private_data
= fs
->user_data
;
2197 if (fs
->op
.getxattr
) {
2199 fprintf(stderr
, "getxattr %s %s %lu\n",
2200 path
, name
, (unsigned long) size
);
2202 return fs
->op
.getxattr(path
, name
, value
, size
);
2208 int fuse_fs_listxattr(struct fuse_fs
*fs
, const char *path
, char *list
,
2211 fuse_get_context()->private_data
= fs
->user_data
;
2212 if (fs
->op
.listxattr
) {
2214 fprintf(stderr
, "listxattr %s %lu\n",
2215 path
, (unsigned long) size
);
2217 return fs
->op
.listxattr(path
, list
, size
);
2223 int fuse_fs_bmap(struct fuse_fs
*fs
, const char *path
, size_t blocksize
,
2226 fuse_get_context()->private_data
= fs
->user_data
;
2229 fprintf(stderr
, "bmap %s blocksize: %lu index: %llu\n",
2230 path
, (unsigned long) blocksize
,
2231 (unsigned long long) *idx
);
2233 return fs
->op
.bmap(path
, blocksize
, idx
);
2239 int fuse_fs_removexattr(struct fuse_fs
*fs
, const char *path
, const char *name
)
2241 fuse_get_context()->private_data
= fs
->user_data
;
2242 if (fs
->op
.removexattr
) {
2244 fprintf(stderr
, "removexattr %s %s\n", path
, name
);
2246 return fs
->op
.removexattr(path
, name
);
2252 int fuse_fs_ioctl(struct fuse_fs
*fs
, const char *path
, int cmd
, void *arg
,
2253 struct fuse_file_info
*fi
, unsigned int flags
, void *data
)
2255 fuse_get_context()->private_data
= fs
->user_data
;
2258 fprintf(stderr
, "ioctl[%llu] 0x%x flags: 0x%x\n",
2259 (unsigned long long) fi
->fh
, cmd
, flags
);
2261 return fs
->op
.ioctl(path
, cmd
, arg
, fi
, flags
, data
);
2266 int fuse_fs_poll(struct fuse_fs
*fs
, const char *path
,
2267 struct fuse_file_info
*fi
, struct fuse_pollhandle
*ph
,
2270 fuse_get_context()->private_data
= fs
->user_data
;
2275 fprintf(stderr
, "poll[%llu] ph: %p\n",
2276 (unsigned long long) fi
->fh
, ph
);
2278 res
= fs
->op
.poll(path
, fi
, ph
, reventsp
);
2280 if (fs
->debug
&& !res
)
2281 fprintf(stderr
, " poll[%llu] revents: 0x%x\n",
2282 (unsigned long long) fi
->fh
, *reventsp
);
2289 int fuse_fs_fallocate(struct fuse_fs
*fs
, const char *path
, int mode
,
2290 off_t offset
, off_t length
, struct fuse_file_info
*fi
)
2292 fuse_get_context()->private_data
= fs
->user_data
;
2293 if (fs
->op
.fallocate
) {
2295 fprintf(stderr
, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2298 (unsigned long long) offset
,
2299 (unsigned long long) length
);
2301 return fs
->op
.fallocate(path
, mode
, offset
, length
, fi
);
2306 static int is_open(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
2310 pthread_mutex_lock(&f
->lock
);
2311 node
= lookup_node(f
, dir
, name
);
2312 if (node
&& node
->open_count
> 0)
2314 pthread_mutex_unlock(&f
->lock
);
2318 static char *hidden_name(struct fuse
*f
, fuse_ino_t dir
, const char *oldname
,
2319 char *newname
, size_t bufsize
)
2323 struct node
*newnode
;
2329 pthread_mutex_lock(&f
->lock
);
2330 node
= lookup_node(f
, dir
, oldname
);
2332 pthread_mutex_unlock(&f
->lock
);
2337 snprintf(newname
, bufsize
, ".fuse_hidden%08x%08x",
2338 (unsigned int) node
->nodeid
, f
->hidectr
);
2339 newnode
= lookup_node(f
, dir
, newname
);
2342 res
= try_get_path(f
, dir
, newname
, &newpath
, NULL
, 0);
2343 pthread_mutex_unlock(&f
->lock
);
2347 res
= fuse_fs_getattr(f
->fs
, newpath
, &buf
);
2352 } while(res
== 0 && --failctr
);
2357 static int hide_node(struct fuse
*f
, const char *oldpath
,
2358 fuse_ino_t dir
, const char *oldname
)
2364 newpath
= hidden_name(f
, dir
, oldname
, newname
, sizeof(newname
));
2366 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
2368 err
= rename_node(f
, dir
, oldname
, dir
, newname
, 1);
2374 static int mtime_eq(const struct stat
*stbuf
, const struct timespec
*ts
)
2376 return stbuf
->st_mtime
== ts
->tv_sec
&&
2377 ST_MTIM_NSEC(stbuf
) == ts
->tv_nsec
;
2380 #ifndef CLOCK_MONOTONIC
2381 #define CLOCK_MONOTONIC CLOCK_REALTIME
2384 static void curr_time(struct timespec
*now
)
2386 static clockid_t clockid
= CLOCK_MONOTONIC
;
2387 int res
= clock_gettime(clockid
, now
);
2388 if (res
== -1 && errno
== EINVAL
) {
2389 clockid
= CLOCK_REALTIME
;
2390 res
= clock_gettime(clockid
, now
);
2393 perror("fuse: clock_gettime");
2398 static void update_stat(struct node
*node
, const struct stat
*stbuf
)
2400 if (node
->cache_valid
&& (!mtime_eq(stbuf
, &node
->mtime
) ||
2401 stbuf
->st_size
!= node
->size
))
2402 node
->cache_valid
= 0;
2403 node
->mtime
.tv_sec
= stbuf
->st_mtime
;
2404 node
->mtime
.tv_nsec
= ST_MTIM_NSEC(stbuf
);
2405 node
->size
= stbuf
->st_size
;
2406 curr_time(&node
->stat_updated
);
2409 static int lookup_path(struct fuse
*f
, fuse_ino_t nodeid
,
2410 const char *name
, const char *path
,
2411 struct fuse_entry_param
*e
, struct fuse_file_info
*fi
)
2415 memset(e
, 0, sizeof(struct fuse_entry_param
));
2417 res
= fuse_fs_fgetattr(f
->fs
, path
, &e
->attr
, fi
);
2419 res
= fuse_fs_getattr(f
->fs
, path
, &e
->attr
);
2423 node
= find_node(f
, nodeid
, name
);
2427 e
->ino
= node
->nodeid
;
2428 e
->generation
= node
->generation
;
2429 e
->entry_timeout
= f
->conf
.entry_timeout
;
2430 e
->attr_timeout
= f
->conf
.attr_timeout
;
2431 if (f
->conf
.auto_cache
) {
2432 pthread_mutex_lock(&f
->lock
);
2433 update_stat(node
, &e
->attr
);
2434 pthread_mutex_unlock(&f
->lock
);
2436 set_stat(f
, e
->ino
, &e
->attr
);
2438 fprintf(stderr
, " NODEID: %lu\n",
2439 (unsigned long) e
->ino
);
2445 static struct fuse_context_i
*fuse_get_context_internal(void)
2447 struct fuse_context_i
*c
;
2449 c
= (struct fuse_context_i
*) pthread_getspecific(fuse_context_key
);
2451 c
= (struct fuse_context_i
*)
2452 calloc(1, sizeof(struct fuse_context_i
));
2454 /* This is hard to deal with properly, so just
2455 abort. If memory is so low that the
2456 context cannot be allocated, there's not
2457 much hope for the filesystem anyway */
2458 fprintf(stderr
, "fuse: failed to allocate thread specific data\n");
2461 pthread_setspecific(fuse_context_key
, c
);
2466 static void fuse_freecontext(void *data
)
2471 static int fuse_create_context_key(void)
2474 pthread_mutex_lock(&fuse_context_lock
);
2475 if (!fuse_context_ref
) {
2476 err
= pthread_key_create(&fuse_context_key
, fuse_freecontext
);
2478 fprintf(stderr
, "fuse: failed to create thread specific key: %s\n",
2480 pthread_mutex_unlock(&fuse_context_lock
);
2485 pthread_mutex_unlock(&fuse_context_lock
);
2489 static void fuse_delete_context_key(void)
2491 pthread_mutex_lock(&fuse_context_lock
);
2493 if (!fuse_context_ref
) {
2494 free(pthread_getspecific(fuse_context_key
));
2495 pthread_key_delete(fuse_context_key
);
2497 pthread_mutex_unlock(&fuse_context_lock
);
2500 static struct fuse
*req_fuse_prepare(fuse_req_t req
)
2502 struct fuse_context_i
*c
= fuse_get_context_internal();
2503 const struct fuse_ctx
*ctx
= fuse_req_ctx(req
);
2505 c
->ctx
.fuse
= req_fuse(req
);
2506 c
->ctx
.uid
= ctx
->uid
;
2507 c
->ctx
.gid
= ctx
->gid
;
2508 c
->ctx
.pid
= ctx
->pid
;
2509 c
->ctx
.umask
= ctx
->umask
;
2513 static inline void reply_err(fuse_req_t req
, int err
)
2515 /* fuse_reply_err() uses non-negated errno values */
2516 fuse_reply_err(req
, -err
);
2519 static void reply_entry(fuse_req_t req
, const struct fuse_entry_param
*e
,
2523 struct fuse
*f
= req_fuse(req
);
2524 if (fuse_reply_entry(req
, e
) == -ENOENT
) {
2525 /* Skip forget for negative result */
2527 forget_node(f
, e
->ino
, 1);
2530 reply_err(req
, err
);
2533 void fuse_fs_init(struct fuse_fs
*fs
, struct fuse_conn_info
*conn
)
2535 fuse_get_context()->private_data
= fs
->user_data
;
2536 if (!fs
->op
.write_buf
)
2537 conn
->want
&= ~FUSE_CAP_SPLICE_READ
;
2539 conn
->want
&= ~FUSE_CAP_POSIX_LOCKS
;
2541 conn
->want
&= ~FUSE_CAP_FLOCK_LOCKS
;
2543 fs
->user_data
= fs
->op
.init(conn
);
2546 static void fuse_lib_init(void *data
, struct fuse_conn_info
*conn
)
2548 struct fuse
*f
= (struct fuse
*) data
;
2549 struct fuse_context_i
*c
= fuse_get_context_internal();
2551 memset(c
, 0, sizeof(*c
));
2553 conn
->want
|= FUSE_CAP_EXPORT_SUPPORT
;
2554 fuse_fs_init(f
->fs
, conn
);
2557 void fuse_fs_destroy(struct fuse_fs
*fs
)
2559 fuse_get_context()->private_data
= fs
->user_data
;
2561 fs
->op
.destroy(fs
->user_data
);
2563 fuse_put_module(fs
->m
);
2567 static void fuse_lib_destroy(void *data
)
2569 struct fuse
*f
= (struct fuse
*) data
;
2570 struct fuse_context_i
*c
= fuse_get_context_internal();
2572 memset(c
, 0, sizeof(*c
));
2574 fuse_fs_destroy(f
->fs
);
2578 static void fuse_lib_lookup(fuse_req_t req
, fuse_ino_t parent
,
2581 struct fuse
*f
= req_fuse_prepare(req
);
2582 struct fuse_entry_param e
;
2585 struct node
*dot
= NULL
;
2587 if (name
[0] == '.') {
2588 int len
= strlen(name
);
2590 if (len
== 1 || (name
[1] == '.' && len
== 2)) {
2591 pthread_mutex_lock(&f
->lock
);
2594 fprintf(stderr
, "LOOKUP-DOT\n");
2595 dot
= get_node_nocheck(f
, parent
);
2597 pthread_mutex_unlock(&f
->lock
);
2598 reply_entry(req
, &e
, -ESTALE
);
2604 fprintf(stderr
, "LOOKUP-DOTDOT\n");
2605 parent
= get_node(f
, parent
)->parent
->nodeid
;
2607 pthread_mutex_unlock(&f
->lock
);
2612 err
= get_path_name(f
, parent
, name
, &path
);
2614 struct fuse_intr_data d
;
2616 fprintf(stderr
, "LOOKUP %s\n", path
);
2617 fuse_prepare_interrupt(f
, req
, &d
);
2618 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2619 if (err
== -ENOENT
&& f
->conf
.negative_timeout
!= 0.0) {
2621 e
.entry_timeout
= f
->conf
.negative_timeout
;
2624 fuse_finish_interrupt(f
, req
, &d
);
2625 free_path(f
, parent
, path
);
2628 pthread_mutex_lock(&f
->lock
);
2630 pthread_mutex_unlock(&f
->lock
);
2632 reply_entry(req
, &e
, err
);
2635 static void do_forget(struct fuse
*f
, fuse_ino_t ino
, uint64_t nlookup
)
2638 fprintf(stderr
, "FORGET %llu/%llu\n", (unsigned long long)ino
,
2639 (unsigned long long) nlookup
);
2640 forget_node(f
, ino
, nlookup
);
2643 static void fuse_lib_forget(fuse_req_t req
, fuse_ino_t ino
,
2644 unsigned long nlookup
)
2646 do_forget(req_fuse(req
), ino
, nlookup
);
2647 fuse_reply_none(req
);
2650 static void fuse_lib_forget_multi(fuse_req_t req
, size_t count
,
2651 struct fuse_forget_data
*forgets
)
2653 struct fuse
*f
= req_fuse(req
);
2656 for (i
= 0; i
< count
; i
++)
2657 do_forget(f
, forgets
[i
].ino
, forgets
[i
].nlookup
);
2659 fuse_reply_none(req
);
2663 static void fuse_lib_getattr(fuse_req_t req
, fuse_ino_t ino
,
2664 struct fuse_file_info
*fi
)
2666 struct fuse
*f
= req_fuse_prepare(req
);
2671 memset(&buf
, 0, sizeof(buf
));
2673 if (fi
!= NULL
&& f
->fs
->op
.fgetattr
)
2674 err
= get_path_nullok(f
, ino
, &path
);
2676 err
= get_path(f
, ino
, &path
);
2678 struct fuse_intr_data d
;
2679 fuse_prepare_interrupt(f
, req
, &d
);
2681 err
= fuse_fs_fgetattr(f
->fs
, path
, &buf
, fi
);
2683 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
2684 fuse_finish_interrupt(f
, req
, &d
);
2685 free_path(f
, ino
, path
);
2690 pthread_mutex_lock(&f
->lock
);
2691 node
= get_node(f
, ino
);
2692 if (node
->is_hidden
&& buf
.st_nlink
> 0)
2694 if (f
->conf
.auto_cache
)
2695 update_stat(node
, &buf
);
2696 pthread_mutex_unlock(&f
->lock
);
2697 set_stat(f
, ino
, &buf
);
2698 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
2700 reply_err(req
, err
);
2703 int fuse_fs_chmod(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
2705 fuse_get_context()->private_data
= fs
->user_data
;
2707 return fs
->op
.chmod(path
, mode
);
2712 static void fuse_lib_setattr(fuse_req_t req
, fuse_ino_t ino
, struct stat
*attr
,
2713 int valid
, struct fuse_file_info
*fi
)
2715 struct fuse
*f
= req_fuse_prepare(req
);
2720 if (valid
== FUSE_SET_ATTR_SIZE
&& fi
!= NULL
&&
2721 f
->fs
->op
.ftruncate
&& f
->fs
->op
.fgetattr
)
2722 err
= get_path_nullok(f
, ino
, &path
);
2724 err
= get_path(f
, ino
, &path
);
2726 struct fuse_intr_data d
;
2727 fuse_prepare_interrupt(f
, req
, &d
);
2729 if (!err
&& (valid
& FUSE_SET_ATTR_MODE
))
2730 err
= fuse_fs_chmod(f
->fs
, path
, attr
->st_mode
);
2731 if (!err
&& (valid
& (FUSE_SET_ATTR_UID
| FUSE_SET_ATTR_GID
))) {
2732 uid_t uid
= (valid
& FUSE_SET_ATTR_UID
) ?
2733 attr
->st_uid
: (uid_t
) -1;
2734 gid_t gid
= (valid
& FUSE_SET_ATTR_GID
) ?
2735 attr
->st_gid
: (gid_t
) -1;
2736 err
= fuse_fs_chown(f
->fs
, path
, uid
, gid
);
2738 if (!err
&& (valid
& FUSE_SET_ATTR_SIZE
)) {
2740 err
= fuse_fs_ftruncate(f
->fs
, path
,
2743 err
= fuse_fs_truncate(f
->fs
, path
,
2746 #ifdef HAVE_UTIMENSAT
2747 if (!err
&& f
->utime_omit_ok
&&
2748 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
))) {
2749 struct timespec tv
[2];
2753 tv
[0].tv_nsec
= UTIME_OMIT
;
2754 tv
[1].tv_nsec
= UTIME_OMIT
;
2756 if (valid
& FUSE_SET_ATTR_ATIME_NOW
)
2757 tv
[0].tv_nsec
= UTIME_NOW
;
2758 else if (valid
& FUSE_SET_ATTR_ATIME
)
2759 tv
[0] = attr
->st_atim
;
2761 if (valid
& FUSE_SET_ATTR_MTIME_NOW
)
2762 tv
[1].tv_nsec
= UTIME_NOW
;
2763 else if (valid
& FUSE_SET_ATTR_MTIME
)
2764 tv
[1] = attr
->st_mtim
;
2766 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
2770 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) ==
2771 (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) {
2772 struct timespec tv
[2];
2773 tv
[0].tv_sec
= attr
->st_atime
;
2774 tv
[0].tv_nsec
= ST_ATIM_NSEC(attr
);
2775 tv
[1].tv_sec
= attr
->st_mtime
;
2776 tv
[1].tv_nsec
= ST_MTIM_NSEC(attr
);
2777 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
2781 err
= fuse_fs_fgetattr(f
->fs
, path
, &buf
, fi
);
2783 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
2785 fuse_finish_interrupt(f
, req
, &d
);
2786 free_path(f
, ino
, path
);
2789 if (f
->conf
.auto_cache
) {
2790 pthread_mutex_lock(&f
->lock
);
2791 update_stat(get_node(f
, ino
), &buf
);
2792 pthread_mutex_unlock(&f
->lock
);
2794 set_stat(f
, ino
, &buf
);
2795 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
2797 reply_err(req
, err
);
2800 static void fuse_lib_access(fuse_req_t req
, fuse_ino_t ino
, int mask
)
2802 struct fuse
*f
= req_fuse_prepare(req
);
2806 err
= get_path(f
, ino
, &path
);
2808 struct fuse_intr_data d
;
2810 fuse_prepare_interrupt(f
, req
, &d
);
2811 err
= fuse_fs_access(f
->fs
, path
, mask
);
2812 fuse_finish_interrupt(f
, req
, &d
);
2813 free_path(f
, ino
, path
);
2815 reply_err(req
, err
);
2818 static void fuse_lib_readlink(fuse_req_t req
, fuse_ino_t ino
)
2820 struct fuse
*f
= req_fuse_prepare(req
);
2821 char linkname
[PATH_MAX
+ 1];
2825 err
= get_path(f
, ino
, &path
);
2827 struct fuse_intr_data d
;
2828 fuse_prepare_interrupt(f
, req
, &d
);
2829 err
= fuse_fs_readlink(f
->fs
, path
, linkname
, sizeof(linkname
));
2830 fuse_finish_interrupt(f
, req
, &d
);
2831 free_path(f
, ino
, path
);
2834 linkname
[PATH_MAX
] = '\0';
2835 fuse_reply_readlink(req
, linkname
);
2837 reply_err(req
, err
);
2840 static void fuse_lib_mknod(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
2841 mode_t mode
, dev_t rdev
)
2843 struct fuse
*f
= req_fuse_prepare(req
);
2844 struct fuse_entry_param e
;
2848 err
= get_path_name(f
, parent
, name
, &path
);
2850 struct fuse_intr_data d
;
2852 fuse_prepare_interrupt(f
, req
, &d
);
2854 if (S_ISREG(mode
)) {
2855 struct fuse_file_info fi
;
2857 memset(&fi
, 0, sizeof(fi
));
2858 fi
.flags
= O_CREAT
| O_EXCL
| O_WRONLY
;
2859 err
= fuse_fs_create(f
->fs
, path
, mode
, &fi
);
2861 err
= lookup_path(f
, parent
, name
, path
, &e
,
2863 fuse_fs_release(f
->fs
, path
, &fi
);
2866 if (err
== -ENOSYS
) {
2867 err
= fuse_fs_mknod(f
->fs
, path
, mode
, rdev
);
2869 err
= lookup_path(f
, parent
, name
, path
, &e
,
2872 fuse_finish_interrupt(f
, req
, &d
);
2873 free_path(f
, parent
, path
);
2875 reply_entry(req
, &e
, err
);
2878 static void fuse_lib_mkdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
2881 struct fuse
*f
= req_fuse_prepare(req
);
2882 struct fuse_entry_param e
;
2886 err
= get_path_name(f
, parent
, name
, &path
);
2888 struct fuse_intr_data d
;
2890 fuse_prepare_interrupt(f
, req
, &d
);
2891 err
= fuse_fs_mkdir(f
->fs
, path
, mode
);
2893 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2894 fuse_finish_interrupt(f
, req
, &d
);
2895 free_path(f
, parent
, path
);
2897 reply_entry(req
, &e
, err
);
2900 static void fuse_lib_unlink(fuse_req_t req
, fuse_ino_t parent
,
2903 struct fuse
*f
= req_fuse_prepare(req
);
2908 err
= get_path_wrlock(f
, parent
, name
, &path
, &wnode
);
2910 struct fuse_intr_data d
;
2912 fuse_prepare_interrupt(f
, req
, &d
);
2913 if (!f
->conf
.hard_remove
&& is_open(f
, parent
, name
)) {
2914 err
= hide_node(f
, path
, parent
, name
);
2916 err
= fuse_fs_unlink(f
->fs
, path
);
2918 remove_node(f
, parent
, name
);
2920 fuse_finish_interrupt(f
, req
, &d
);
2921 free_path_wrlock(f
, parent
, wnode
, path
);
2923 reply_err(req
, err
);
2926 static void fuse_lib_rmdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
2928 struct fuse
*f
= req_fuse_prepare(req
);
2933 err
= get_path_wrlock(f
, parent
, name
, &path
, &wnode
);
2935 struct fuse_intr_data d
;
2937 fuse_prepare_interrupt(f
, req
, &d
);
2938 err
= fuse_fs_rmdir(f
->fs
, path
);
2939 fuse_finish_interrupt(f
, req
, &d
);
2941 remove_node(f
, parent
, name
);
2942 free_path_wrlock(f
, parent
, wnode
, path
);
2944 reply_err(req
, err
);
2947 static void fuse_lib_symlink(fuse_req_t req
, const char *linkname
,
2948 fuse_ino_t parent
, const char *name
)
2950 struct fuse
*f
= req_fuse_prepare(req
);
2951 struct fuse_entry_param e
;
2955 err
= get_path_name(f
, parent
, name
, &path
);
2957 struct fuse_intr_data d
;
2959 fuse_prepare_interrupt(f
, req
, &d
);
2960 err
= fuse_fs_symlink(f
->fs
, linkname
, path
);
2962 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2963 fuse_finish_interrupt(f
, req
, &d
);
2964 free_path(f
, parent
, path
);
2966 reply_entry(req
, &e
, err
);
2969 static void fuse_lib_rename(fuse_req_t req
, fuse_ino_t olddir
,
2970 const char *oldname
, fuse_ino_t newdir
,
2971 const char *newname
)
2973 struct fuse
*f
= req_fuse_prepare(req
);
2976 struct node
*wnode1
;
2977 struct node
*wnode2
;
2980 err
= get_path2(f
, olddir
, oldname
, newdir
, newname
,
2981 &oldpath
, &newpath
, &wnode1
, &wnode2
);
2983 struct fuse_intr_data d
;
2985 fuse_prepare_interrupt(f
, req
, &d
);
2986 if (!f
->conf
.hard_remove
&& is_open(f
, newdir
, newname
))
2987 err
= hide_node(f
, newpath
, newdir
, newname
);
2989 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
2991 err
= rename_node(f
, olddir
, oldname
, newdir
,
2994 fuse_finish_interrupt(f
, req
, &d
);
2995 free_path2(f
, olddir
, newdir
, wnode1
, wnode2
, oldpath
, newpath
);
2997 reply_err(req
, err
);
3000 static void fuse_lib_link(fuse_req_t req
, fuse_ino_t ino
, fuse_ino_t newparent
,
3001 const char *newname
)
3003 struct fuse
*f
= req_fuse_prepare(req
);
3004 struct fuse_entry_param e
;
3009 err
= get_path2(f
, ino
, NULL
, newparent
, newname
,
3010 &oldpath
, &newpath
, NULL
, NULL
);
3012 struct fuse_intr_data d
;
3014 fuse_prepare_interrupt(f
, req
, &d
);
3015 err
= fuse_fs_link(f
->fs
, oldpath
, newpath
);
3017 err
= lookup_path(f
, newparent
, newname
, newpath
,
3019 fuse_finish_interrupt(f
, req
, &d
);
3020 free_path2(f
, ino
, newparent
, NULL
, NULL
, oldpath
, newpath
);
3022 reply_entry(req
, &e
, err
);
3025 static void fuse_do_release(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
3026 struct fuse_file_info
*fi
)
3029 int unlink_hidden
= 0;
3030 const char *compatpath
;
3032 if (path
!= NULL
|| f
->nullpath_ok
|| f
->conf
.nopath
)
3037 fuse_fs_release(f
->fs
, compatpath
, fi
);
3039 pthread_mutex_lock(&f
->lock
);
3040 node
= get_node(f
, ino
);
3041 assert(node
->open_count
> 0);
3043 if (node
->is_hidden
&& !node
->open_count
) {
3045 node
->is_hidden
= 0;
3047 pthread_mutex_unlock(&f
->lock
);
3051 fuse_fs_unlink(f
->fs
, path
);
3052 } else if (f
->conf
.nopath
) {
3055 if (get_path(f
, ino
, &unlinkpath
) == 0)
3056 fuse_fs_unlink(f
->fs
, unlinkpath
);
3058 free_path(f
, ino
, unlinkpath
);
3063 static void fuse_lib_create(fuse_req_t req
, fuse_ino_t parent
,
3064 const char *name
, mode_t mode
,
3065 struct fuse_file_info
*fi
)
3067 struct fuse
*f
= req_fuse_prepare(req
);
3068 struct fuse_intr_data d
;
3069 struct fuse_entry_param e
;
3073 err
= get_path_name(f
, parent
, name
, &path
);
3075 fuse_prepare_interrupt(f
, req
, &d
);
3076 err
= fuse_fs_create(f
->fs
, path
, mode
, fi
);
3078 err
= lookup_path(f
, parent
, name
, path
, &e
, fi
);
3080 fuse_fs_release(f
->fs
, path
, fi
);
3081 else if (!S_ISREG(e
.attr
.st_mode
)) {
3083 fuse_fs_release(f
->fs
, path
, fi
);
3084 forget_node(f
, e
.ino
, 1);
3086 if (f
->conf
.direct_io
)
3088 if (f
->conf
.kernel_cache
)
3093 fuse_finish_interrupt(f
, req
, &d
);
3096 pthread_mutex_lock(&f
->lock
);
3097 get_node(f
, e
.ino
)->open_count
++;
3098 pthread_mutex_unlock(&f
->lock
);
3099 if (fuse_reply_create(req
, &e
, fi
) == -ENOENT
) {
3100 /* The open syscall was interrupted, so it
3101 must be cancelled */
3102 fuse_do_release(f
, e
.ino
, path
, fi
);
3103 forget_node(f
, e
.ino
, 1);
3106 reply_err(req
, err
);
3109 free_path(f
, parent
, path
);
3112 static double diff_timespec(const struct timespec
*t1
,
3113 const struct timespec
*t2
)
3115 return (t1
->tv_sec
- t2
->tv_sec
) +
3116 ((double) t1
->tv_nsec
- (double) t2
->tv_nsec
) / 1000000000.0;
3119 static void open_auto_cache(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
3120 struct fuse_file_info
*fi
)
3124 pthread_mutex_lock(&f
->lock
);
3125 node
= get_node(f
, ino
);
3126 if (node
->cache_valid
) {
3127 struct timespec now
;
3130 if (diff_timespec(&now
, &node
->stat_updated
) >
3131 f
->conf
.ac_attr_timeout
) {
3134 pthread_mutex_unlock(&f
->lock
);
3135 err
= fuse_fs_fgetattr(f
->fs
, path
, &stbuf
, fi
);
3136 pthread_mutex_lock(&f
->lock
);
3138 update_stat(node
, &stbuf
);
3140 node
->cache_valid
= 0;
3143 if (node
->cache_valid
)
3146 node
->cache_valid
= 1;
3147 pthread_mutex_unlock(&f
->lock
);
3150 static void fuse_lib_open(fuse_req_t req
, fuse_ino_t ino
,
3151 struct fuse_file_info
*fi
)
3153 struct fuse
*f
= req_fuse_prepare(req
);
3154 struct fuse_intr_data d
;
3158 err
= get_path(f
, ino
, &path
);
3160 fuse_prepare_interrupt(f
, req
, &d
);
3161 err
= fuse_fs_open(f
->fs
, path
, fi
);
3163 if (f
->conf
.direct_io
)
3165 if (f
->conf
.kernel_cache
)
3168 if (f
->conf
.auto_cache
)
3169 open_auto_cache(f
, ino
, path
, fi
);
3171 fuse_finish_interrupt(f
, req
, &d
);
3174 pthread_mutex_lock(&f
->lock
);
3175 get_node(f
, ino
)->open_count
++;
3176 pthread_mutex_unlock(&f
->lock
);
3177 if (fuse_reply_open(req
, fi
) == -ENOENT
) {
3178 /* The open syscall was interrupted, so it
3179 must be cancelled */
3180 fuse_do_release(f
, ino
, path
, fi
);
3183 reply_err(req
, err
);
3185 free_path(f
, ino
, path
);
3188 static void fuse_lib_read(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
3189 off_t off
, struct fuse_file_info
*fi
)
3191 struct fuse
*f
= req_fuse_prepare(req
);
3192 struct fuse_bufvec
*buf
= NULL
;
3196 res
= get_path_nullok(f
, ino
, &path
);
3198 struct fuse_intr_data d
;
3200 fuse_prepare_interrupt(f
, req
, &d
);
3201 res
= fuse_fs_read_buf(f
->fs
, path
, &buf
, size
, off
, fi
);
3202 fuse_finish_interrupt(f
, req
, &d
);
3203 free_path(f
, ino
, path
);
3207 fuse_reply_data(req
, buf
, FUSE_BUF_SPLICE_MOVE
);
3209 reply_err(req
, res
);
3214 static void fuse_lib_write_buf(fuse_req_t req
, fuse_ino_t ino
,
3215 struct fuse_bufvec
*buf
, off_t off
,
3216 struct fuse_file_info
*fi
)
3218 struct fuse
*f
= req_fuse_prepare(req
);
3222 res
= get_path_nullok(f
, ino
, &path
);
3224 struct fuse_intr_data d
;
3226 fuse_prepare_interrupt(f
, req
, &d
);
3227 res
= fuse_fs_write_buf(f
->fs
, path
, buf
, off
, fi
);
3228 fuse_finish_interrupt(f
, req
, &d
);
3229 free_path(f
, ino
, path
);
3233 fuse_reply_write(req
, res
);
3235 reply_err(req
, res
);
3238 static void fuse_lib_fsync(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
3239 struct fuse_file_info
*fi
)
3241 struct fuse
*f
= req_fuse_prepare(req
);
3245 err
= get_path_nullok(f
, ino
, &path
);
3247 struct fuse_intr_data d
;
3249 fuse_prepare_interrupt(f
, req
, &d
);
3250 err
= fuse_fs_fsync(f
->fs
, path
, datasync
, fi
);
3251 fuse_finish_interrupt(f
, req
, &d
);
3252 free_path(f
, ino
, path
);
3254 reply_err(req
, err
);
3257 static struct fuse_dh
*get_dirhandle(const struct fuse_file_info
*llfi
,
3258 struct fuse_file_info
*fi
)
3260 struct fuse_dh
*dh
= (struct fuse_dh
*) (uintptr_t) llfi
->fh
;
3261 memset(fi
, 0, sizeof(struct fuse_file_info
));
3263 fi
->fh_old
= dh
->fh
;
3267 static void fuse_lib_opendir(fuse_req_t req
, fuse_ino_t ino
,
3268 struct fuse_file_info
*llfi
)
3270 struct fuse
*f
= req_fuse_prepare(req
);
3271 struct fuse_intr_data d
;
3273 struct fuse_file_info fi
;
3277 dh
= (struct fuse_dh
*) malloc(sizeof(struct fuse_dh
));
3279 reply_err(req
, -ENOMEM
);
3282 memset(dh
, 0, sizeof(struct fuse_dh
));
3284 dh
->contents
= NULL
;
3288 fuse_mutex_init(&dh
->lock
);
3290 llfi
->fh
= (uintptr_t) dh
;
3292 memset(&fi
, 0, sizeof(fi
));
3293 fi
.flags
= llfi
->flags
;
3295 err
= get_path(f
, ino
, &path
);
3297 fuse_prepare_interrupt(f
, req
, &d
);
3298 err
= fuse_fs_opendir(f
->fs
, path
, &fi
);
3299 fuse_finish_interrupt(f
, req
, &d
);
3303 if (fuse_reply_open(req
, llfi
) == -ENOENT
) {
3304 /* The opendir syscall was interrupted, so it
3305 must be cancelled */
3306 fuse_fs_releasedir(f
->fs
, path
, &fi
);
3307 pthread_mutex_destroy(&dh
->lock
);
3311 reply_err(req
, err
);
3312 pthread_mutex_destroy(&dh
->lock
);
3315 free_path(f
, ino
, path
);
3318 static int extend_contents(struct fuse_dh
*dh
, unsigned minsize
)
3320 if (minsize
> dh
->size
) {
3322 unsigned newsize
= dh
->size
;
3325 while (newsize
< minsize
) {
3326 if (newsize
>= 0x80000000)
3327 newsize
= 0xffffffff;
3332 newptr
= (char *) realloc(dh
->contents
, newsize
);
3334 dh
->error
= -ENOMEM
;
3337 dh
->contents
= newptr
;
3343 static int fill_dir(void *dh_
, const char *name
, const struct stat
*statp
,
3346 struct fuse_dh
*dh
= (struct fuse_dh
*) dh_
;
3353 memset(&stbuf
, 0, sizeof(stbuf
));
3354 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
3357 if (!dh
->fuse
->conf
.use_ino
) {
3358 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
3359 if (dh
->fuse
->conf
.readdir_ino
) {
3361 pthread_mutex_lock(&dh
->fuse
->lock
);
3362 node
= lookup_node(dh
->fuse
, dh
->nodeid
, name
);
3364 stbuf
.st_ino
= (ino_t
) node
->nodeid
;
3365 pthread_mutex_unlock(&dh
->fuse
->lock
);
3370 if (extend_contents(dh
, dh
->needlen
) == -1)
3375 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
3376 dh
->needlen
- dh
->len
, name
,
3378 if (newlen
> dh
->needlen
)
3382 fuse_add_direntry(dh
->req
, NULL
, 0, name
, NULL
, 0);
3383 if (extend_contents(dh
, newlen
) == -1)
3386 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
3387 dh
->size
- dh
->len
, name
, &stbuf
, newlen
);
3393 static int readdir_fill(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3394 size_t size
, off_t off
, struct fuse_dh
*dh
,
3395 struct fuse_file_info
*fi
)
3400 if (f
->fs
->op
.readdir
)
3401 err
= get_path_nullok(f
, ino
, &path
);
3403 err
= get_path(f
, ino
, &path
);
3405 struct fuse_intr_data d
;
3412 fuse_prepare_interrupt(f
, req
, &d
);
3413 err
= fuse_fs_readdir(f
->fs
, path
, dh
, fill_dir
, off
, fi
);
3414 fuse_finish_interrupt(f
, req
, &d
);
3420 free_path(f
, ino
, path
);
3425 static void fuse_lib_readdir(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
3426 off_t off
, struct fuse_file_info
*llfi
)
3428 struct fuse
*f
= req_fuse_prepare(req
);
3429 struct fuse_file_info fi
;
3430 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
3432 pthread_mutex_lock(&dh
->lock
);
3433 /* According to SUS, directory contents need to be refreshed on
3439 int err
= readdir_fill(f
, req
, ino
, size
, off
, dh
, &fi
);
3441 reply_err(req
, err
);
3446 if (off
< dh
->len
) {
3447 if (off
+ size
> dh
->len
)
3448 size
= dh
->len
- off
;
3455 fuse_reply_buf(req
, dh
->contents
+ off
, size
);
3457 pthread_mutex_unlock(&dh
->lock
);
3460 static void fuse_lib_releasedir(fuse_req_t req
, fuse_ino_t ino
,
3461 struct fuse_file_info
*llfi
)
3463 struct fuse
*f
= req_fuse_prepare(req
);
3464 struct fuse_intr_data d
;
3465 struct fuse_file_info fi
;
3466 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
3468 const char *compatpath
;
3470 get_path_nullok(f
, ino
, &path
);
3471 if (path
!= NULL
|| f
->nullpath_ok
|| f
->conf
.nopath
)
3476 fuse_prepare_interrupt(f
, req
, &d
);
3477 fuse_fs_releasedir(f
->fs
, compatpath
, &fi
);
3478 fuse_finish_interrupt(f
, req
, &d
);
3479 free_path(f
, ino
, path
);
3481 pthread_mutex_lock(&dh
->lock
);
3482 pthread_mutex_unlock(&dh
->lock
);
3483 pthread_mutex_destroy(&dh
->lock
);
3489 static void fuse_lib_fsyncdir(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
3490 struct fuse_file_info
*llfi
)
3492 struct fuse
*f
= req_fuse_prepare(req
);
3493 struct fuse_file_info fi
;
3497 get_dirhandle(llfi
, &fi
);
3499 err
= get_path_nullok(f
, ino
, &path
);
3501 struct fuse_intr_data d
;
3502 fuse_prepare_interrupt(f
, req
, &d
);
3503 err
= fuse_fs_fsyncdir(f
->fs
, path
, datasync
, &fi
);
3504 fuse_finish_interrupt(f
, req
, &d
);
3505 free_path(f
, ino
, path
);
3507 reply_err(req
, err
);
3510 static void fuse_lib_statfs(fuse_req_t req
, fuse_ino_t ino
)
3512 struct fuse
*f
= req_fuse_prepare(req
);
3517 memset(&buf
, 0, sizeof(buf
));
3519 err
= get_path(f
, ino
, &path
);
3522 struct fuse_intr_data d
;
3523 fuse_prepare_interrupt(f
, req
, &d
);
3524 err
= fuse_fs_statfs(f
->fs
, path
? path
: "/", &buf
);
3525 fuse_finish_interrupt(f
, req
, &d
);
3526 free_path(f
, ino
, path
);
3530 fuse_reply_statfs(req
, &buf
);
3532 reply_err(req
, err
);
3535 static void fuse_lib_setxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
3536 const char *value
, size_t size
, int flags
)
3538 struct fuse
*f
= req_fuse_prepare(req
);
3542 err
= get_path(f
, ino
, &path
);
3544 struct fuse_intr_data d
;
3545 fuse_prepare_interrupt(f
, req
, &d
);
3546 err
= fuse_fs_setxattr(f
->fs
, path
, name
, value
, size
, flags
);
3547 fuse_finish_interrupt(f
, req
, &d
);
3548 free_path(f
, ino
, path
);
3550 reply_err(req
, err
);
3553 static int common_getxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3554 const char *name
, char *value
, size_t size
)
3559 err
= get_path(f
, ino
, &path
);
3561 struct fuse_intr_data d
;
3562 fuse_prepare_interrupt(f
, req
, &d
);
3563 err
= fuse_fs_getxattr(f
->fs
, path
, name
, value
, size
);
3564 fuse_finish_interrupt(f
, req
, &d
);
3565 free_path(f
, ino
, path
);
3570 static void fuse_lib_getxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
3573 struct fuse
*f
= req_fuse_prepare(req
);
3577 char *value
= (char *) malloc(size
);
3578 if (value
== NULL
) {
3579 reply_err(req
, -ENOMEM
);
3582 res
= common_getxattr(f
, req
, ino
, name
, value
, size
);
3584 fuse_reply_buf(req
, value
, res
);
3586 reply_err(req
, res
);
3589 res
= common_getxattr(f
, req
, ino
, name
, NULL
, 0);
3591 fuse_reply_xattr(req
, res
);
3593 reply_err(req
, res
);
3597 static int common_listxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3598 char *list
, size_t size
)
3603 err
= get_path(f
, ino
, &path
);
3605 struct fuse_intr_data d
;
3606 fuse_prepare_interrupt(f
, req
, &d
);
3607 err
= fuse_fs_listxattr(f
->fs
, path
, list
, size
);
3608 fuse_finish_interrupt(f
, req
, &d
);
3609 free_path(f
, ino
, path
);
3614 static void fuse_lib_listxattr(fuse_req_t req
, fuse_ino_t ino
, size_t size
)
3616 struct fuse
*f
= req_fuse_prepare(req
);
3620 char *list
= (char *) malloc(size
);
3622 reply_err(req
, -ENOMEM
);
3625 res
= common_listxattr(f
, req
, ino
, list
, size
);
3627 fuse_reply_buf(req
, list
, res
);
3629 reply_err(req
, res
);
3632 res
= common_listxattr(f
, req
, ino
, NULL
, 0);
3634 fuse_reply_xattr(req
, res
);
3636 reply_err(req
, res
);
3640 static void fuse_lib_removexattr(fuse_req_t req
, fuse_ino_t ino
,
3643 struct fuse
*f
= req_fuse_prepare(req
);
3647 err
= get_path(f
, ino
, &path
);
3649 struct fuse_intr_data d
;
3650 fuse_prepare_interrupt(f
, req
, &d
);
3651 err
= fuse_fs_removexattr(f
->fs
, path
, name
);
3652 fuse_finish_interrupt(f
, req
, &d
);
3653 free_path(f
, ino
, path
);
3655 reply_err(req
, err
);
3658 static struct lock
*locks_conflict(struct node
*node
, const struct lock
*lock
)
3662 for (l
= node
->locks
; l
; l
= l
->next
)
3663 if (l
->owner
!= lock
->owner
&&
3664 lock
->start
<= l
->end
&& l
->start
<= lock
->end
&&
3665 (l
->type
== F_WRLCK
|| lock
->type
== F_WRLCK
))
3671 static void delete_lock(struct lock
**lockp
)
3673 struct lock
*l
= *lockp
;
3678 static void insert_lock(struct lock
**pos
, struct lock
*lock
)
3684 static int locks_insert(struct node
*node
, struct lock
*lock
)
3687 struct lock
*newl1
= NULL
;
3688 struct lock
*newl2
= NULL
;
3690 if (lock
->type
!= F_UNLCK
|| lock
->start
!= 0 ||
3691 lock
->end
!= OFFSET_MAX
) {
3692 newl1
= malloc(sizeof(struct lock
));
3693 newl2
= malloc(sizeof(struct lock
));
3695 if (!newl1
|| !newl2
) {
3702 for (lp
= &node
->locks
; *lp
;) {
3703 struct lock
*l
= *lp
;
3704 if (l
->owner
!= lock
->owner
)
3707 if (lock
->type
== l
->type
) {
3708 if (l
->end
< lock
->start
- 1)
3710 if (lock
->end
< l
->start
- 1)
3712 if (l
->start
<= lock
->start
&& lock
->end
<= l
->end
)
3714 if (l
->start
< lock
->start
)
3715 lock
->start
= l
->start
;
3716 if (lock
->end
< l
->end
)
3720 if (l
->end
< lock
->start
)
3722 if (lock
->end
< l
->start
)
3724 if (lock
->start
<= l
->start
&& l
->end
<= lock
->end
)
3726 if (l
->end
<= lock
->end
) {
3727 l
->end
= lock
->start
- 1;
3730 if (lock
->start
<= l
->start
) {
3731 l
->start
= lock
->end
+ 1;
3735 newl2
->start
= lock
->end
+ 1;
3736 l
->end
= lock
->start
- 1;
3737 insert_lock(&l
->next
, newl2
);
3747 if (lock
->type
!= F_UNLCK
) {
3749 insert_lock(lp
, newl1
);
3758 static void flock_to_lock(struct flock
*flock
, struct lock
*lock
)
3760 memset(lock
, 0, sizeof(struct lock
));
3761 lock
->type
= flock
->l_type
;
3762 lock
->start
= flock
->l_start
;
3764 flock
->l_len
? flock
->l_start
+ flock
->l_len
- 1 : OFFSET_MAX
;
3765 lock
->pid
= flock
->l_pid
;
3768 static void lock_to_flock(struct lock
*lock
, struct flock
*flock
)
3770 flock
->l_type
= lock
->type
;
3771 flock
->l_start
= lock
->start
;
3773 (lock
->end
== OFFSET_MAX
) ? 0 : lock
->end
- lock
->start
+ 1;
3774 flock
->l_pid
= lock
->pid
;
3777 static int fuse_flush_common(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3778 const char *path
, struct fuse_file_info
*fi
)
3780 struct fuse_intr_data d
;
3786 fuse_prepare_interrupt(f
, req
, &d
);
3787 memset(&lock
, 0, sizeof(lock
));
3788 lock
.l_type
= F_UNLCK
;
3789 lock
.l_whence
= SEEK_SET
;
3790 err
= fuse_fs_flush(f
->fs
, path
, fi
);
3791 errlock
= fuse_fs_lock(f
->fs
, path
, fi
, F_SETLK
, &lock
);
3792 fuse_finish_interrupt(f
, req
, &d
);
3794 if (errlock
!= -ENOSYS
) {
3795 flock_to_lock(&lock
, &l
);
3796 l
.owner
= fi
->lock_owner
;
3797 pthread_mutex_lock(&f
->lock
);
3798 locks_insert(get_node(f
, ino
), &l
);
3799 pthread_mutex_unlock(&f
->lock
);
3801 /* if op.lock() is defined FLUSH is needed regardless
3809 static void fuse_lib_release(fuse_req_t req
, fuse_ino_t ino
,
3810 struct fuse_file_info
*fi
)
3812 struct fuse
*f
= req_fuse_prepare(req
);
3813 struct fuse_intr_data d
;
3817 get_path_nullok(f
, ino
, &path
);
3819 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
3824 fuse_prepare_interrupt(f
, req
, &d
);
3825 fuse_do_release(f
, ino
, path
, fi
);
3826 fuse_finish_interrupt(f
, req
, &d
);
3827 free_path(f
, ino
, path
);
3829 reply_err(req
, err
);
3832 static void fuse_lib_flush(fuse_req_t req
, fuse_ino_t ino
,
3833 struct fuse_file_info
*fi
)
3835 struct fuse
*f
= req_fuse_prepare(req
);
3839 get_path_nullok(f
, ino
, &path
);
3840 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
3841 free_path(f
, ino
, path
);
3843 reply_err(req
, err
);
3846 static int fuse_lock_common(fuse_req_t req
, fuse_ino_t ino
,
3847 struct fuse_file_info
*fi
, struct flock
*lock
,
3850 struct fuse
*f
= req_fuse_prepare(req
);
3854 err
= get_path_nullok(f
, ino
, &path
);
3856 struct fuse_intr_data d
;
3857 fuse_prepare_interrupt(f
, req
, &d
);
3858 err
= fuse_fs_lock(f
->fs
, path
, fi
, cmd
, lock
);
3859 fuse_finish_interrupt(f
, req
, &d
);
3860 free_path(f
, ino
, path
);
3865 static void fuse_lib_getlk(fuse_req_t req
, fuse_ino_t ino
,
3866 struct fuse_file_info
*fi
, struct flock
*lock
)
3870 struct lock
*conflict
;
3871 struct fuse
*f
= req_fuse(req
);
3873 flock_to_lock(lock
, &l
);
3874 l
.owner
= fi
->lock_owner
;
3875 pthread_mutex_lock(&f
->lock
);
3876 conflict
= locks_conflict(get_node(f
, ino
), &l
);
3878 lock_to_flock(conflict
, lock
);
3879 pthread_mutex_unlock(&f
->lock
);
3881 err
= fuse_lock_common(req
, ino
, fi
, lock
, F_GETLK
);
3886 fuse_reply_lock(req
, lock
);
3888 reply_err(req
, err
);
3891 static void fuse_lib_setlk(fuse_req_t req
, fuse_ino_t ino
,
3892 struct fuse_file_info
*fi
, struct flock
*lock
,
3895 int err
= fuse_lock_common(req
, ino
, fi
, lock
,
3896 sleep
? F_SETLKW
: F_SETLK
);
3898 struct fuse
*f
= req_fuse(req
);
3900 flock_to_lock(lock
, &l
);
3901 l
.owner
= fi
->lock_owner
;
3902 pthread_mutex_lock(&f
->lock
);
3903 locks_insert(get_node(f
, ino
), &l
);
3904 pthread_mutex_unlock(&f
->lock
);
3906 reply_err(req
, err
);
3909 static void fuse_lib_flock(fuse_req_t req
, fuse_ino_t ino
,
3910 struct fuse_file_info
*fi
, int op
)
3912 struct fuse
*f
= req_fuse_prepare(req
);
3916 err
= get_path_nullok(f
, ino
, &path
);
3918 struct fuse_intr_data d
;
3919 fuse_prepare_interrupt(f
, req
, &d
);
3920 err
= fuse_fs_flock(f
->fs
, path
, fi
, op
);
3921 fuse_finish_interrupt(f
, req
, &d
);
3922 free_path(f
, ino
, path
);
3924 reply_err(req
, err
);
3927 static void fuse_lib_bmap(fuse_req_t req
, fuse_ino_t ino
, size_t blocksize
,
3930 struct fuse
*f
= req_fuse_prepare(req
);
3931 struct fuse_intr_data d
;
3935 err
= get_path(f
, ino
, &path
);
3937 fuse_prepare_interrupt(f
, req
, &d
);
3938 err
= fuse_fs_bmap(f
->fs
, path
, blocksize
, &idx
);
3939 fuse_finish_interrupt(f
, req
, &d
);
3940 free_path(f
, ino
, path
);
3943 fuse_reply_bmap(req
, idx
);
3945 reply_err(req
, err
);
3948 static void fuse_lib_ioctl(fuse_req_t req
, fuse_ino_t ino
, int cmd
, void *arg
,
3949 struct fuse_file_info
*fi
, unsigned int flags
,
3950 const void *in_buf
, size_t in_bufsz
,
3953 struct fuse
*f
= req_fuse_prepare(req
);
3954 struct fuse_intr_data d
;
3955 char *path
, *out_buf
= NULL
;
3959 if (flags
& FUSE_IOCTL_UNRESTRICTED
)
3964 out_buf
= malloc(out_bufsz
);
3969 assert(!in_bufsz
|| !out_bufsz
|| in_bufsz
== out_bufsz
);
3971 memcpy(out_buf
, in_buf
, in_bufsz
);
3973 err
= get_path_nullok(f
, ino
, &path
);
3977 fuse_prepare_interrupt(f
, req
, &d
);
3979 err
= fuse_fs_ioctl(f
->fs
, path
, cmd
, arg
, fi
, flags
,
3980 out_buf
?: (void *)in_buf
);
3982 fuse_finish_interrupt(f
, req
, &d
);
3983 free_path(f
, ino
, path
);
3985 fuse_reply_ioctl(req
, err
, out_buf
, out_bufsz
);
3988 reply_err(req
, err
);
3993 static void fuse_lib_poll(fuse_req_t req
, fuse_ino_t ino
,
3994 struct fuse_file_info
*fi
, struct fuse_pollhandle
*ph
)
3996 struct fuse
*f
= req_fuse_prepare(req
);
3997 struct fuse_intr_data d
;
4000 unsigned revents
= 0;
4002 err
= get_path_nullok(f
, ino
, &path
);
4004 fuse_prepare_interrupt(f
, req
, &d
);
4005 err
= fuse_fs_poll(f
->fs
, path
, fi
, ph
, &revents
);
4006 fuse_finish_interrupt(f
, req
, &d
);
4007 free_path(f
, ino
, path
);
4010 fuse_reply_poll(req
, revents
);
4012 reply_err(req
, err
);
4015 static void fuse_lib_fallocate(fuse_req_t req
, fuse_ino_t ino
, int mode
,
4016 off_t offset
, off_t length
, struct fuse_file_info
*fi
)
4018 struct fuse
*f
= req_fuse_prepare(req
);
4019 struct fuse_intr_data d
;
4023 err
= get_path_nullok(f
, ino
, &path
);
4025 fuse_prepare_interrupt(f
, req
, &d
);
4026 err
= fuse_fs_fallocate(f
->fs
, path
, mode
, offset
, length
, fi
);
4027 fuse_finish_interrupt(f
, req
, &d
);
4028 free_path(f
, ino
, path
);
4030 reply_err(req
, err
);
4033 static int clean_delay(struct fuse
*f
)
4036 * This is calculating the delay between clean runs. To
4037 * reduce the number of cleans we are doing them 10 times
4038 * within the remember window.
4041 int max_sleep
= 3600;
4042 int sleep_time
= f
->conf
.remember
/ 10;
4044 if (sleep_time
> max_sleep
)
4046 if (sleep_time
< min_sleep
)
4051 int fuse_clean_cache(struct fuse
*f
)
4053 struct node_lru
*lnode
;
4054 struct list_head
*curr
, *next
;
4056 struct timespec now
;
4058 pthread_mutex_lock(&f
->lock
);
4062 for (curr
= f
->lru_table
.next
; curr
!= &f
->lru_table
; curr
= next
) {
4066 lnode
= list_entry(curr
, struct node_lru
, lru
);
4067 node
= &lnode
->node
;
4069 age
= diff_timespec(&now
, &lnode
->forget_time
);
4070 if (age
<= f
->conf
.remember
)
4073 assert(node
->nlookup
== 1);
4075 /* Don't forget active directories */
4076 if (node
->refctr
> 1)
4080 unhash_name(f
, node
);
4081 unref_node(f
, node
);
4083 pthread_mutex_unlock(&f
->lock
);
4085 return clean_delay(f
);
4088 static struct fuse_lowlevel_ops fuse_path_ops
= {
4089 .init
= fuse_lib_init
,
4090 .destroy
= fuse_lib_destroy
,
4091 .lookup
= fuse_lib_lookup
,
4092 .forget
= fuse_lib_forget
,
4093 .forget_multi
= fuse_lib_forget_multi
,
4094 .getattr
= fuse_lib_getattr
,
4095 .setattr
= fuse_lib_setattr
,
4096 .access
= fuse_lib_access
,
4097 .readlink
= fuse_lib_readlink
,
4098 .mknod
= fuse_lib_mknod
,
4099 .mkdir
= fuse_lib_mkdir
,
4100 .unlink
= fuse_lib_unlink
,
4101 .rmdir
= fuse_lib_rmdir
,
4102 .symlink
= fuse_lib_symlink
,
4103 .rename
= fuse_lib_rename
,
4104 .link
= fuse_lib_link
,
4105 .create
= fuse_lib_create
,
4106 .open
= fuse_lib_open
,
4107 .read
= fuse_lib_read
,
4108 .write_buf
= fuse_lib_write_buf
,
4109 .flush
= fuse_lib_flush
,
4110 .release
= fuse_lib_release
,
4111 .fsync
= fuse_lib_fsync
,
4112 .opendir
= fuse_lib_opendir
,
4113 .readdir
= fuse_lib_readdir
,
4114 .releasedir
= fuse_lib_releasedir
,
4115 .fsyncdir
= fuse_lib_fsyncdir
,
4116 .statfs
= fuse_lib_statfs
,
4117 .setxattr
= fuse_lib_setxattr
,
4118 .getxattr
= fuse_lib_getxattr
,
4119 .listxattr
= fuse_lib_listxattr
,
4120 .removexattr
= fuse_lib_removexattr
,
4121 .getlk
= fuse_lib_getlk
,
4122 .setlk
= fuse_lib_setlk
,
4123 .flock
= fuse_lib_flock
,
4124 .bmap
= fuse_lib_bmap
,
4125 .ioctl
= fuse_lib_ioctl
,
4126 .poll
= fuse_lib_poll
,
4127 .fallocate
= fuse_lib_fallocate
,
4130 int fuse_notify_poll(struct fuse_pollhandle
*ph
)
4132 return fuse_lowlevel_notify_poll(ph
);
4135 static void free_cmd(struct fuse_cmd
*cmd
)
4141 void fuse_process_cmd(struct fuse
*f
, struct fuse_cmd
*cmd
)
4143 fuse_session_process(f
->se
, cmd
->buf
, cmd
->buflen
, cmd
->ch
);
4147 int fuse_exited(struct fuse
*f
)
4149 return fuse_session_exited(f
->se
);
4152 struct fuse_session
*fuse_get_session(struct fuse
*f
)
4157 static struct fuse_cmd
*fuse_alloc_cmd(size_t bufsize
)
4159 struct fuse_cmd
*cmd
= (struct fuse_cmd
*) malloc(sizeof(*cmd
));
4161 fprintf(stderr
, "fuse: failed to allocate cmd\n");
4164 cmd
->buf
= (char *) malloc(bufsize
);
4165 if (cmd
->buf
== NULL
) {
4166 fprintf(stderr
, "fuse: failed to allocate read buffer\n");
4173 struct fuse_cmd
*fuse_read_cmd(struct fuse
*f
)
4175 struct fuse_chan
*ch
= fuse_session_next_chan(f
->se
, NULL
);
4176 size_t bufsize
= fuse_chan_bufsize(ch
);
4177 struct fuse_cmd
*cmd
= fuse_alloc_cmd(bufsize
);
4179 int res
= fuse_chan_recv(&ch
, cmd
->buf
, bufsize
);
4182 if (res
< 0 && res
!= -EINTR
&& res
!= -EAGAIN
)
4192 static int fuse_session_loop_remember(struct fuse
*f
)
4194 struct fuse_session
*se
= f
->se
;
4196 struct timespec now
;
4198 struct fuse_chan
*ch
= fuse_session_next_chan(se
, NULL
);
4199 size_t bufsize
= fuse_chan_bufsize(ch
);
4200 char *buf
= (char *) malloc(bufsize
);
4201 struct pollfd fds
= {
4202 .fd
= fuse_chan_fd(ch
),
4207 fprintf(stderr
, "fuse: failed to allocate read buffer\n");
4212 next_clean
= now
.tv_sec
;
4213 while (!fuse_session_exited(se
)) {
4214 struct fuse_chan
*tmpch
= ch
;
4215 struct fuse_buf fbuf
= {
4222 if (now
.tv_sec
< next_clean
)
4223 timeout
= next_clean
- now
.tv_sec
;
4227 res
= poll(&fds
, 1, timeout
* 1000);
4229 if (errno
== -EINTR
)
4233 } else if (res
> 0) {
4234 res
= fuse_session_receive_buf(se
, &fbuf
, &tmpch
);
4241 fuse_session_process_buf(se
, &fbuf
, tmpch
);
4243 timeout
= fuse_clean_cache(f
);
4245 next_clean
= now
.tv_sec
+ timeout
;
4250 fuse_session_reset(se
);
4251 return res
< 0 ? -1 : 0;
4254 int fuse_loop(struct fuse
*f
)
4260 return fuse_session_loop_remember(f
);
4262 return fuse_session_loop(f
->se
);
4265 int fuse_invalidate(struct fuse
*f
, const char *path
)
4272 void fuse_exit(struct fuse
*f
)
4274 fuse_session_exit(f
->se
);
4277 struct fuse_context
*fuse_get_context(void)
4279 return &fuse_get_context_internal()->ctx
;
4283 * The size of fuse_context got extended, so need to be careful about
4284 * incompatibility (i.e. a new binary cannot work with an old
4287 struct fuse_context
*fuse_get_context_compat22(void);
4288 struct fuse_context
*fuse_get_context_compat22(void)
4290 return &fuse_get_context_internal()->ctx
;
4292 FUSE_SYMVER(".symver fuse_get_context_compat22,fuse_get_context@FUSE_2.2");
4294 int fuse_getgroups(int size
, gid_t list
[])
4296 fuse_req_t req
= fuse_get_context_internal()->req
;
4297 return fuse_req_getgroups(req
, size
, list
);
4300 int fuse_interrupted(void)
4302 return fuse_req_interrupted(fuse_get_context_internal()->req
);
4305 void fuse_set_getcontext_func(struct fuse_context
*(*func
)(void))
4315 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4317 static const struct fuse_opt fuse_lib_opts
[] = {
4318 FUSE_OPT_KEY("-h", KEY_HELP
),
4319 FUSE_OPT_KEY("--help", KEY_HELP
),
4320 FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP
),
4321 FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP
),
4322 FUSE_LIB_OPT("debug", debug
, 1),
4323 FUSE_LIB_OPT("-d", debug
, 1),
4324 FUSE_LIB_OPT("hard_remove", hard_remove
, 1),
4325 FUSE_LIB_OPT("use_ino", use_ino
, 1),
4326 FUSE_LIB_OPT("readdir_ino", readdir_ino
, 1),
4327 FUSE_LIB_OPT("direct_io", direct_io
, 1),
4328 FUSE_LIB_OPT("kernel_cache", kernel_cache
, 1),
4329 FUSE_LIB_OPT("auto_cache", auto_cache
, 1),
4330 FUSE_LIB_OPT("noauto_cache", auto_cache
, 0),
4331 FUSE_LIB_OPT("umask=", set_mode
, 1),
4332 FUSE_LIB_OPT("umask=%o", umask
, 0),
4333 FUSE_LIB_OPT("uid=", set_uid
, 1),
4334 FUSE_LIB_OPT("uid=%d", uid
, 0),
4335 FUSE_LIB_OPT("gid=", set_gid
, 1),
4336 FUSE_LIB_OPT("gid=%d", gid
, 0),
4337 FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout
, 0),
4338 FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout
, 0),
4339 FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout
, 0),
4340 FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set
, 1),
4341 FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout
, 0),
4342 FUSE_LIB_OPT("noforget", remember
, -1),
4343 FUSE_LIB_OPT("remember=%u", remember
, 0),
4344 FUSE_LIB_OPT("nopath", nopath
, 1),
4345 FUSE_LIB_OPT("intr", intr
, 1),
4346 FUSE_LIB_OPT("intr_signal=%d", intr_signal
, 0),
4347 FUSE_LIB_OPT("modules=%s", modules
, 0),
4351 static void fuse_lib_help(void)
4354 " -o hard_remove immediate removal (don't hide files)\n"
4355 " -o use_ino let filesystem set inode numbers\n"
4356 " -o readdir_ino try to fill in d_ino in readdir\n"
4357 " -o direct_io use direct I/O\n"
4358 " -o kernel_cache cache files in kernel\n"
4359 " -o [no]auto_cache enable caching based on modification times (off)\n"
4360 " -o umask=M set file permissions (octal)\n"
4361 " -o uid=N set file owner\n"
4362 " -o gid=N set file group\n"
4363 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4364 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4365 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4366 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4367 " -o noforget never forget cached inodes\n"
4368 " -o remember=T remember cached inodes for T seconds (0s)\n"
4369 " -o intr allow requests to be interrupted\n"
4370 " -o intr_signal=NUM signal to send on interrupt (%i)\n"
4371 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
4372 "\n", FUSE_DEFAULT_INTR_SIGNAL
);
4375 static void fuse_lib_help_modules(void)
4377 struct fuse_module
*m
;
4378 fprintf(stderr
, "\nModule options:\n");
4379 pthread_mutex_lock(&fuse_context_lock
);
4380 for (m
= fuse_modules
; m
; m
= m
->next
) {
4381 struct fuse_fs
*fs
= NULL
;
4382 struct fuse_fs
*newfs
;
4383 struct fuse_args args
= FUSE_ARGS_INIT(0, NULL
);
4384 if (fuse_opt_add_arg(&args
, "") != -1 &&
4385 fuse_opt_add_arg(&args
, "-h") != -1) {
4386 fprintf(stderr
, "\n[%s]\n", m
->name
);
4387 newfs
= m
->factory(&args
, &fs
);
4388 assert(newfs
== NULL
);
4390 fuse_opt_free_args(&args
);
4392 pthread_mutex_unlock(&fuse_context_lock
);
4395 static int fuse_lib_opt_proc(void *data
, const char *arg
, int key
,
4396 struct fuse_args
*outargs
)
4398 (void) arg
; (void) outargs
;
4400 if (key
== KEY_HELP
) {
4401 struct fuse_config
*conf
= (struct fuse_config
*) data
;
4409 int fuse_is_lib_option(const char *opt
)
4411 return fuse_lowlevel_is_lib_option(opt
) ||
4412 fuse_opt_match(fuse_lib_opts
, opt
);
4415 static int fuse_init_intr_signal(int signum
, int *installed
)
4417 struct sigaction old_sa
;
4419 if (sigaction(signum
, NULL
, &old_sa
) == -1) {
4420 perror("fuse: cannot get old signal handler");
4424 if (old_sa
.sa_handler
== SIG_DFL
) {
4425 struct sigaction sa
;
4427 memset(&sa
, 0, sizeof(struct sigaction
));
4428 sa
.sa_handler
= fuse_intr_sighandler
;
4429 sigemptyset(&sa
.sa_mask
);
4431 if (sigaction(signum
, &sa
, NULL
) == -1) {
4432 perror("fuse: cannot set interrupt signal handler");
4440 static void fuse_restore_intr_signal(int signum
)
4442 struct sigaction sa
;
4444 memset(&sa
, 0, sizeof(struct sigaction
));
4445 sa
.sa_handler
= SIG_DFL
;
4446 sigaction(signum
, &sa
, NULL
);
4450 static int fuse_push_module(struct fuse
*f
, const char *module
,
4451 struct fuse_args
*args
)
4453 struct fuse_fs
*fs
[2] = { f
->fs
, NULL
};
4454 struct fuse_fs
*newfs
;
4455 struct fuse_module
*m
= fuse_get_module(module
);
4460 newfs
= m
->factory(args
, fs
);
4467 f
->nullpath_ok
= newfs
->op
.flag_nullpath_ok
&& f
->nullpath_ok
;
4468 f
->conf
.nopath
= newfs
->op
.flag_nopath
&& f
->conf
.nopath
;
4469 f
->utime_omit_ok
= newfs
->op
.flag_utime_omit_ok
&& f
->utime_omit_ok
;
4473 struct fuse_fs
*fuse_fs_new(const struct fuse_operations
*op
, size_t op_size
,
4478 if (sizeof(struct fuse_operations
) < op_size
) {
4479 fprintf(stderr
, "fuse: warning: library too old, some operations may not not work\n");
4480 op_size
= sizeof(struct fuse_operations
);
4483 fs
= (struct fuse_fs
*) calloc(1, sizeof(struct fuse_fs
));
4485 fprintf(stderr
, "fuse: failed to allocate fuse_fs object\n");
4489 fs
->user_data
= user_data
;
4491 memcpy(&fs
->op
, op
, op_size
);
4495 static int node_table_init(struct node_table
*t
)
4497 t
->size
= NODE_TABLE_MIN_SIZE
;
4498 t
->array
= (struct node
**) calloc(1, sizeof(struct node
*) * t
->size
);
4499 if (t
->array
== NULL
) {
4500 fprintf(stderr
, "fuse: memory allocation failed\n");
4509 static void *fuse_prune_nodes(void *fuse
)
4511 struct fuse
*f
= fuse
;
4515 sleep_time
= fuse_clean_cache(f
);
4521 int fuse_start_cleanup_thread(struct fuse
*f
)
4524 return fuse_start_thread(&f
->prune_thread
, fuse_prune_nodes
, f
);
4529 void fuse_stop_cleanup_thread(struct fuse
*f
)
4531 if (lru_enabled(f
)) {
4532 pthread_mutex_lock(&f
->lock
);
4533 pthread_cancel(f
->prune_thread
);
4534 pthread_mutex_unlock(&f
->lock
);
4535 pthread_join(f
->prune_thread
, NULL
);
4539 struct fuse
*fuse_new_common(struct fuse_chan
*ch
, struct fuse_args
*args
,
4540 const struct fuse_operations
*op
,
4541 size_t op_size
, void *user_data
, int compat
)
4546 struct fuse_lowlevel_ops llop
= fuse_path_ops
;
4548 if (fuse_create_context_key() == -1)
4551 f
= (struct fuse
*) calloc(1, sizeof(struct fuse
));
4553 fprintf(stderr
, "fuse: failed to allocate fuse object\n");
4554 goto out_delete_context_key
;
4557 fs
= fuse_fs_new(op
, op_size
, user_data
);
4561 fs
->compat
= compat
;
4563 f
->nullpath_ok
= fs
->op
.flag_nullpath_ok
;
4564 f
->conf
.nopath
= fs
->op
.flag_nopath
;
4565 f
->utime_omit_ok
= fs
->op
.flag_utime_omit_ok
;
4567 /* Oh f**k, this is ugly! */
4573 f
->conf
.entry_timeout
= 1.0;
4574 f
->conf
.attr_timeout
= 1.0;
4575 f
->conf
.negative_timeout
= 0.0;
4576 f
->conf
.intr_signal
= FUSE_DEFAULT_INTR_SIGNAL
;
4578 f
->pagesize
= getpagesize();
4579 init_list_head(&f
->partial_slabs
);
4580 init_list_head(&f
->full_slabs
);
4581 init_list_head(&f
->lru_table
);
4583 if (fuse_opt_parse(args
, &f
->conf
, fuse_lib_opts
,
4584 fuse_lib_opt_proc
) == -1)
4587 if (f
->conf
.modules
) {
4591 for (module
= f
->conf
.modules
; module
; module
= next
) {
4593 for (p
= module
; *p
&& *p
!= ':'; p
++);
4594 next
= *p
? p
+ 1 : NULL
;
4597 fuse_push_module(f
, module
, args
) == -1)
4602 if (!f
->conf
.ac_attr_timeout_set
)
4603 f
->conf
.ac_attr_timeout
= f
->conf
.attr_timeout
;
4605 #if defined(__FreeBSD__) || defined(__NetBSD__)
4607 * In FreeBSD, we always use these settings as inode numbers
4608 * are needed to make getcwd(3) work.
4610 f
->conf
.readdir_ino
= 1;
4613 if (compat
&& compat
<= 25) {
4614 if (fuse_sync_compat_args(args
) == -1)
4618 f
->se
= fuse_lowlevel_new_common(args
, &llop
, sizeof(llop
), f
);
4619 if (f
->se
== NULL
) {
4621 fuse_lib_help_modules();
4625 fuse_session_add_chan(f
->se
, ch
);
4627 if (f
->conf
.debug
) {
4628 fprintf(stderr
, "nullpath_ok: %i\n", f
->nullpath_ok
);
4629 fprintf(stderr
, "nopath: %i\n", f
->conf
.nopath
);
4630 fprintf(stderr
, "utime_omit_ok: %i\n", f
->utime_omit_ok
);
4633 /* Trace topmost layer by default */
4634 f
->fs
->debug
= f
->conf
.debug
;
4637 if (node_table_init(&f
->name_table
) == -1)
4638 goto out_free_session
;
4640 if (node_table_init(&f
->id_table
) == -1)
4641 goto out_free_name_table
;
4643 fuse_mutex_init(&f
->lock
);
4645 root
= alloc_node(f
);
4647 fprintf(stderr
, "fuse: memory allocation failed\n");
4648 goto out_free_id_table
;
4651 strcpy(root
->inline_name
, "/");
4652 root
->name
= root
->inline_name
;
4655 fuse_init_intr_signal(f
->conf
.intr_signal
,
4656 &f
->intr_installed
) == -1)
4659 root
->parent
= NULL
;
4660 root
->nodeid
= FUSE_ROOT_ID
;
4669 free(f
->id_table
.array
);
4670 out_free_name_table
:
4671 free(f
->name_table
.array
);
4673 fuse_session_destroy(f
->se
);
4675 /* Horrible compatibility hack to stop the destructor from being
4676 called on the filesystem without init being called first */
4677 fs
->op
.destroy
= NULL
;
4678 fuse_fs_destroy(f
->fs
);
4679 free(f
->conf
.modules
);
4682 out_delete_context_key
:
4683 fuse_delete_context_key();
4688 struct fuse
*fuse_new(struct fuse_chan
*ch
, struct fuse_args
*args
,
4689 const struct fuse_operations
*op
, size_t op_size
,
4692 return fuse_new_common(ch
, args
, op
, op_size
, user_data
, 0);
4695 void fuse_destroy(struct fuse
*f
)
4699 if (f
->conf
.intr
&& f
->intr_installed
)
4700 fuse_restore_intr_signal(f
->conf
.intr_signal
);
4703 struct fuse_context_i
*c
= fuse_get_context_internal();
4705 memset(c
, 0, sizeof(*c
));
4708 for (i
= 0; i
< f
->id_table
.size
; i
++) {
4711 for (node
= f
->id_table
.array
[i
]; node
!= NULL
;
4712 node
= node
->id_next
) {
4713 if (node
->is_hidden
) {
4715 if (try_get_path(f
, node
->nodeid
, NULL
, &path
, NULL
, 0) == 0) {
4716 fuse_fs_unlink(f
->fs
, path
);
4723 for (i
= 0; i
< f
->id_table
.size
; i
++) {
4727 for (node
= f
->id_table
.array
[i
]; node
!= NULL
; node
= next
) {
4728 next
= node
->id_next
;
4733 assert(list_empty(&f
->partial_slabs
));
4734 assert(list_empty(&f
->full_slabs
));
4736 free(f
->id_table
.array
);
4737 free(f
->name_table
.array
);
4738 pthread_mutex_destroy(&f
->lock
);
4739 fuse_session_destroy(f
->se
);
4740 free(f
->conf
.modules
);
4742 fuse_delete_context_key();
4745 static struct fuse
*fuse_new_common_compat25(int fd
, struct fuse_args
*args
,
4746 const struct fuse_operations
*op
,
4747 size_t op_size
, int compat
)
4749 struct fuse
*f
= NULL
;
4750 struct fuse_chan
*ch
= fuse_kern_chan_new(fd
);
4753 f
= fuse_new_common(ch
, args
, op
, op_size
, NULL
, compat
);
4758 /* called with fuse_context_lock held or during initialization (before
4759 main() has been called) */
4760 void fuse_register_module(struct fuse_module
*mod
)
4763 mod
->so
= fuse_current_so
;
4766 mod
->next
= fuse_modules
;
4770 #if !defined(__FreeBSD__) && !defined(__NetBSD__)
4772 static struct fuse
*fuse_new_common_compat(int fd
, const char *opts
,
4773 const struct fuse_operations
*op
,
4774 size_t op_size
, int compat
)
4777 struct fuse_args args
= FUSE_ARGS_INIT(0, NULL
);
4779 if (fuse_opt_add_arg(&args
, "") == -1)
4782 (fuse_opt_add_arg(&args
, "-o") == -1 ||
4783 fuse_opt_add_arg(&args
, opts
) == -1)) {
4784 fuse_opt_free_args(&args
);
4787 f
= fuse_new_common_compat25(fd
, &args
, op
, op_size
, compat
);
4788 fuse_opt_free_args(&args
);
4793 struct fuse
*fuse_new_compat22(int fd
, const char *opts
,
4794 const struct fuse_operations_compat22
*op
,
4797 return fuse_new_common_compat(fd
, opts
, (struct fuse_operations
*) op
,
4801 struct fuse
*fuse_new_compat2(int fd
, const char *opts
,
4802 const struct fuse_operations_compat2
*op
)
4804 return fuse_new_common_compat(fd
, opts
, (struct fuse_operations
*) op
,
4805 sizeof(struct fuse_operations_compat2
),
4809 struct fuse
*fuse_new_compat1(int fd
, int flags
,
4810 const struct fuse_operations_compat1
*op
)
4812 const char *opts
= NULL
;
4813 if (flags
& FUSE_DEBUG_COMPAT1
)
4815 return fuse_new_common_compat(fd
, opts
, (struct fuse_operations
*) op
,
4816 sizeof(struct fuse_operations_compat1
),
4820 FUSE_SYMVER(".symver fuse_exited,__fuse_exited@");
4821 FUSE_SYMVER(".symver fuse_process_cmd,__fuse_process_cmd@");
4822 FUSE_SYMVER(".symver fuse_read_cmd,__fuse_read_cmd@");
4823 FUSE_SYMVER(".symver fuse_set_getcontext_func,__fuse_set_getcontext_func@");
4824 FUSE_SYMVER(".symver fuse_new_compat2,fuse_new@");
4825 FUSE_SYMVER(".symver fuse_new_compat22,fuse_new@FUSE_2.2");
4827 #endif /* __FreeBSD__ || __NetBSD__ */
4829 struct fuse
*fuse_new_compat25(int fd
, struct fuse_args
*args
,
4830 const struct fuse_operations_compat25
*op
,
4833 return fuse_new_common_compat25(fd
, args
, (struct fuse_operations
*) op
,
4837 FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5");