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"
36 #include <sys/param.h>
41 #define FUSE_NODE_SLAB 1
47 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
49 #define FUSE_UNKNOWN_INO 0xffffffff
50 #define OFFSET_MAX 0x7fffffffffffffffLL
52 #define NODE_TABLE_MIN_SIZE 8192
59 double negative_timeout
;
61 double ac_attr_timeout
;
62 int ac_attr_timeout_set
;
82 struct fuse_operations op
;
83 struct fuse_module
*m
;
94 struct lock_queue_element
{
95 struct lock_queue_element
*next
;
100 struct node
**wnode1
;
104 struct node
**wnode2
;
106 bool first_locked
: 1;
107 bool second_locked
: 1;
118 #define container_of(ptr, type, member) ({ \
119 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
120 (type *)( (char *)__mptr - offsetof(type,member) );})
122 #define list_entry(ptr, type, member) \
123 container_of(ptr, type, member)
126 struct list_head
*next
;
127 struct list_head
*prev
;
131 struct list_head list
; /* must be the first member */
132 struct list_head freelist
;
137 struct fuse_session
*se
;
138 struct node_table name_table
;
139 struct node_table id_table
;
140 struct list_head lru_table
;
142 unsigned int generation
;
143 unsigned int hidectr
;
144 pthread_mutex_t lock
;
145 struct fuse_config conf
;
150 struct lock_queue_element
*lockq
;
152 struct list_head partial_slabs
;
153 struct list_head full_slabs
;
154 pthread_t prune_thread
;
167 struct node
*name_next
;
168 struct node
*id_next
;
170 unsigned int generation
;
176 struct timespec stat_updated
;
177 struct timespec mtime
;
180 unsigned int is_hidden
: 1;
181 unsigned int cache_valid
: 1;
183 char inline_name
[32];
186 #define TREELOCK_WRITE -1
187 #define TREELOCK_WAIT_OFFSET INT_MIN
191 struct list_head lru
;
192 struct timespec forget_time
;
196 pthread_mutex_t lock
;
211 struct fuse_dirhandle
{
212 fuse_fill_dir_t filler
;
216 struct fuse_context_i
{
217 struct fuse_context ctx
;
221 static pthread_key_t fuse_context_key
;
222 static pthread_mutex_t fuse_context_lock
= PTHREAD_MUTEX_INITIALIZER
;
223 static int fuse_context_ref
;
224 static struct fusemod_so
*fuse_current_so
;
225 static struct fuse_module
*fuse_modules
;
227 static int fuse_load_so_name(const char *soname
)
229 struct fusemod_so
*so
;
231 so
= calloc(1, sizeof(struct fusemod_so
));
233 fprintf(stderr
, "fuse: memory allocation failed\n");
237 fuse_current_so
= so
;
238 so
->handle
= dlopen(soname
, RTLD_NOW
);
239 fuse_current_so
= NULL
;
241 fprintf(stderr
, "fuse: %s\n", dlerror());
245 fprintf(stderr
, "fuse: %s did not register any modules\n",
258 static int fuse_load_so_module(const char *module
)
261 char *soname
= malloc(strlen(module
) + 64);
263 fprintf(stderr
, "fuse: memory allocation failed\n");
266 sprintf(soname
, "libfusemod_%s.so", module
);
267 res
= fuse_load_so_name(soname
);
272 static struct fuse_module
*fuse_find_module(const char *module
)
274 struct fuse_module
*m
;
275 for (m
= fuse_modules
; m
; m
= m
->next
) {
276 if (strcmp(module
, m
->name
) == 0) {
284 static struct fuse_module
*fuse_get_module(const char *module
)
286 struct fuse_module
*m
;
288 pthread_mutex_lock(&fuse_context_lock
);
289 m
= fuse_find_module(module
);
291 int err
= fuse_load_so_module(module
);
293 m
= fuse_find_module(module
);
295 pthread_mutex_unlock(&fuse_context_lock
);
299 static void fuse_put_module(struct fuse_module
*m
)
301 pthread_mutex_lock(&fuse_context_lock
);
304 if (!m
->ctr
&& m
->so
) {
305 struct fusemod_so
*so
= m
->so
;
309 struct fuse_module
**mp
;
310 for (mp
= &fuse_modules
; *mp
;) {
320 pthread_mutex_unlock(&fuse_context_lock
);
323 static void init_list_head(struct list_head
*list
)
329 static int list_empty(const struct list_head
*head
)
331 return head
->next
== head
;
334 static void list_add(struct list_head
*new, struct list_head
*prev
,
335 struct list_head
*next
)
343 static inline void list_add_head(struct list_head
*new, struct list_head
*head
)
345 list_add(new, head
, head
->next
);
348 static inline void list_add_tail(struct list_head
*new, struct list_head
*head
)
350 list_add(new, head
->prev
, head
);
353 static inline void list_del(struct list_head
*entry
)
355 struct list_head
*prev
= entry
->prev
;
356 struct list_head
*next
= entry
->next
;
362 static inline int lru_enabled(struct fuse
*f
)
364 return f
->conf
.remember
> 0;
367 static struct node_lru
*node_lru(struct node
*node
)
369 return (struct node_lru
*) node
;
372 static size_t get_node_size(struct fuse
*f
)
375 return sizeof(struct node_lru
);
377 return sizeof(struct node
);
380 #ifdef FUSE_NODE_SLAB
381 static struct node_slab
*list_to_slab(struct list_head
*head
)
383 return (struct node_slab
*) head
;
386 static struct node_slab
*node_to_slab(struct fuse
*f
, struct node
*node
)
388 return (struct node_slab
*) (((uintptr_t) node
) & ~((uintptr_t) f
->pagesize
- 1));
391 static int alloc_slab(struct fuse
*f
)
394 struct node_slab
*slab
;
398 size_t node_size
= get_node_size(f
);
400 mem
= mmap(NULL
, f
->pagesize
, PROT_READ
| PROT_WRITE
,
401 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
403 if (mem
== MAP_FAILED
)
407 init_list_head(&slab
->freelist
);
409 num
= (f
->pagesize
- sizeof(struct node_slab
)) / node_size
;
411 start
= (char *) mem
+ f
->pagesize
- num
* node_size
;
412 for (i
= 0; i
< num
; i
++) {
415 n
= (struct list_head
*) (start
+ i
* node_size
);
416 list_add_tail(n
, &slab
->freelist
);
418 list_add_tail(&slab
->list
, &f
->partial_slabs
);
423 static struct node
*alloc_node(struct fuse
*f
)
425 struct node_slab
*slab
;
426 struct list_head
*node
;
428 if (list_empty(&f
->partial_slabs
)) {
429 int res
= alloc_slab(f
);
433 slab
= list_to_slab(f
->partial_slabs
.next
);
435 node
= slab
->freelist
.next
;
437 if (list_empty(&slab
->freelist
)) {
438 list_del(&slab
->list
);
439 list_add_tail(&slab
->list
, &f
->full_slabs
);
441 memset(node
, 0, sizeof(struct node
));
443 return (struct node
*) node
;
446 static void free_slab(struct fuse
*f
, struct node_slab
*slab
)
450 list_del(&slab
->list
);
451 res
= munmap(slab
, f
->pagesize
);
453 fprintf(stderr
, "fuse warning: munmap(%p) failed\n", slab
);
456 static void free_node_mem(struct fuse
*f
, struct node
*node
)
458 struct node_slab
*slab
= node_to_slab(f
, node
);
459 struct list_head
*n
= (struct list_head
*) node
;
463 if (list_empty(&slab
->freelist
)) {
464 list_del(&slab
->list
);
465 list_add_tail(&slab
->list
, &f
->partial_slabs
);
467 list_add_head(n
, &slab
->freelist
);
473 static struct node
*alloc_node(struct fuse
*f
)
475 return (struct node
*) calloc(1, get_node_size(f
));
478 static void free_node_mem(struct fuse
*f
, struct node
*node
)
485 static size_t id_hash(struct fuse
*f
, fuse_ino_t ino
)
487 uint64_t hash
= ((uint32_t) ino
* 2654435761U) % f
->id_table
.size
;
488 uint64_t oldhash
= hash
% (f
->id_table
.size
/ 2);
490 if (oldhash
>= f
->id_table
.split
)
496 static struct node
*get_node_nocheck(struct fuse
*f
, fuse_ino_t nodeid
)
498 size_t hash
= id_hash(f
, nodeid
);
501 for (node
= f
->id_table
.array
[hash
]; node
!= NULL
; node
= node
->id_next
)
502 if (node
->nodeid
== nodeid
)
508 static struct node
*get_node(struct fuse
*f
, fuse_ino_t nodeid
)
510 struct node
*node
= get_node_nocheck(f
, nodeid
);
512 fprintf(stderr
, "fuse internal error: node %llu not found\n",
513 (unsigned long long) nodeid
);
519 static void curr_time(struct timespec
*now
);
520 static double diff_timespec(const struct timespec
*t1
,
521 const struct timespec
*t2
);
523 static void remove_node_lru(struct node
*node
)
525 struct node_lru
*lnode
= node_lru(node
);
526 list_del(&lnode
->lru
);
527 init_list_head(&lnode
->lru
);
530 static void set_forget_time(struct fuse
*f
, struct node
*node
)
532 struct node_lru
*lnode
= node_lru(node
);
534 list_del(&lnode
->lru
);
535 list_add_tail(&lnode
->lru
, &f
->lru_table
);
536 curr_time(&lnode
->forget_time
);
539 static void free_node(struct fuse
*f
, struct node
*node
)
541 if (node
->name
!= node
->inline_name
)
543 free_node_mem(f
, node
);
546 static void node_table_reduce(struct node_table
*t
)
548 size_t newsize
= t
->size
/ 2;
551 if (newsize
< NODE_TABLE_MIN_SIZE
)
554 newarray
= realloc(t
->array
, sizeof(struct node
*) * newsize
);
555 if (newarray
!= NULL
)
559 t
->split
= t
->size
/ 2;
562 static void remerge_id(struct fuse
*f
)
564 struct node_table
*t
= &f
->id_table
;
568 node_table_reduce(t
);
570 for (iter
= 8; t
->split
> 0 && iter
; iter
--) {
574 upper
= &t
->array
[t
->split
+ t
->size
/ 2];
578 for (nodep
= &t
->array
[t
->split
]; *nodep
;
579 nodep
= &(*nodep
)->id_next
);
588 static void unhash_id(struct fuse
*f
, struct node
*node
)
590 struct node
**nodep
= &f
->id_table
.array
[id_hash(f
, node
->nodeid
)];
592 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->id_next
)
593 if (*nodep
== node
) {
594 *nodep
= node
->id_next
;
597 if(f
->id_table
.use
< f
->id_table
.size
/ 4)
603 static int node_table_resize(struct node_table
*t
)
605 size_t newsize
= t
->size
* 2;
608 newarray
= realloc(t
->array
, sizeof(struct node
*) * newsize
);
609 if (newarray
== NULL
)
613 memset(t
->array
+ t
->size
, 0, t
->size
* sizeof(struct node
*));
620 static void rehash_id(struct fuse
*f
)
622 struct node_table
*t
= &f
->id_table
;
627 if (t
->split
== t
->size
/ 2)
632 for (nodep
= &t
->array
[hash
]; *nodep
!= NULL
; nodep
= next
) {
633 struct node
*node
= *nodep
;
634 size_t newhash
= id_hash(f
, node
->nodeid
);
636 if (newhash
!= hash
) {
638 *nodep
= node
->id_next
;
639 node
->id_next
= t
->array
[newhash
];
640 t
->array
[newhash
] = node
;
642 next
= &node
->id_next
;
645 if (t
->split
== t
->size
/ 2)
646 node_table_resize(t
);
649 static void hash_id(struct fuse
*f
, struct node
*node
)
651 size_t hash
= id_hash(f
, node
->nodeid
);
652 node
->id_next
= f
->id_table
.array
[hash
];
653 f
->id_table
.array
[hash
] = node
;
656 if (f
->id_table
.use
>= f
->id_table
.size
/ 2)
660 static size_t name_hash(struct fuse
*f
, fuse_ino_t parent
,
663 uint64_t hash
= parent
;
666 for (; *name
; name
++)
667 hash
= hash
* 31 + (unsigned char) *name
;
669 hash
%= f
->name_table
.size
;
670 oldhash
= hash
% (f
->name_table
.size
/ 2);
671 if (oldhash
>= f
->name_table
.split
)
677 static void unref_node(struct fuse
*f
, struct node
*node
);
679 static void remerge_name(struct fuse
*f
)
681 struct node_table
*t
= &f
->name_table
;
685 node_table_reduce(t
);
687 for (iter
= 8; t
->split
> 0 && iter
; iter
--) {
691 upper
= &t
->array
[t
->split
+ t
->size
/ 2];
695 for (nodep
= &t
->array
[t
->split
]; *nodep
;
696 nodep
= &(*nodep
)->name_next
);
705 static void unhash_name(struct fuse
*f
, struct node
*node
)
708 size_t hash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
709 struct node
**nodep
= &f
->name_table
.array
[hash
];
711 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->name_next
)
712 if (*nodep
== node
) {
713 *nodep
= node
->name_next
;
714 node
->name_next
= NULL
;
715 unref_node(f
, node
->parent
);
716 if (node
->name
!= node
->inline_name
)
722 if (f
->name_table
.use
< f
->name_table
.size
/ 4)
727 "fuse internal error: unable to unhash node: %llu\n",
728 (unsigned long long) node
->nodeid
);
733 static void rehash_name(struct fuse
*f
)
735 struct node_table
*t
= &f
->name_table
;
740 if (t
->split
== t
->size
/ 2)
745 for (nodep
= &t
->array
[hash
]; *nodep
!= NULL
; nodep
= next
) {
746 struct node
*node
= *nodep
;
747 size_t newhash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
749 if (newhash
!= hash
) {
751 *nodep
= node
->name_next
;
752 node
->name_next
= t
->array
[newhash
];
753 t
->array
[newhash
] = node
;
755 next
= &node
->name_next
;
758 if (t
->split
== t
->size
/ 2)
759 node_table_resize(t
);
762 static int hash_name(struct fuse
*f
, struct node
*node
, fuse_ino_t parentid
,
765 size_t hash
= name_hash(f
, parentid
, name
);
766 struct node
*parent
= get_node(f
, parentid
);
767 if (strlen(name
) < sizeof(node
->inline_name
)) {
768 strcpy(node
->inline_name
, name
);
769 node
->name
= node
->inline_name
;
771 node
->name
= strdup(name
);
772 if (node
->name
== NULL
)
777 node
->parent
= parent
;
778 node
->name_next
= f
->name_table
.array
[hash
];
779 f
->name_table
.array
[hash
] = node
;
782 if (f
->name_table
.use
>= f
->name_table
.size
/ 2)
788 static void delete_node(struct fuse
*f
, struct node
*node
)
791 fprintf(stderr
, "DELETE: %llu\n",
792 (unsigned long long) node
->nodeid
);
794 assert(node
->treelock
== 0);
795 unhash_name(f
, node
);
797 remove_node_lru(node
);
802 static void unref_node(struct fuse
*f
, struct node
*node
)
804 assert(node
->refctr
> 0);
807 delete_node(f
, node
);
810 static fuse_ino_t
next_id(struct fuse
*f
)
813 f
->ctr
= (f
->ctr
+ 1) & 0xffffffff;
816 } while (f
->ctr
== 0 || f
->ctr
== FUSE_UNKNOWN_INO
||
817 get_node_nocheck(f
, f
->ctr
) != NULL
);
821 static struct node
*lookup_node(struct fuse
*f
, fuse_ino_t parent
,
824 size_t hash
= name_hash(f
, parent
, name
);
827 for (node
= f
->name_table
.array
[hash
]; node
!= NULL
; node
= node
->name_next
)
828 if (node
->parent
->nodeid
== parent
&&
829 strcmp(node
->name
, name
) == 0)
835 static void inc_nlookup(struct node
*node
)
842 static struct node
*find_node(struct fuse
*f
, fuse_ino_t parent
,
847 pthread_mutex_lock(&f
->lock
);
849 node
= get_node(f
, parent
);
851 node
= lookup_node(f
, parent
, name
);
853 node
= alloc_node(f
);
857 node
->nodeid
= next_id(f
);
858 node
->generation
= f
->generation
;
859 if (f
->conf
.remember
)
862 if (hash_name(f
, node
, parent
, name
) == -1) {
868 if (lru_enabled(f
)) {
869 struct node_lru
*lnode
= node_lru(node
);
870 init_list_head(&lnode
->lru
);
872 } else if (lru_enabled(f
) && node
->nlookup
== 1) {
873 remove_node_lru(node
);
877 pthread_mutex_unlock(&f
->lock
);
881 static char *add_name(char **buf
, unsigned *bufsize
, char *s
, const char *name
)
883 size_t len
= strlen(name
);
885 if (s
- len
<= *buf
) {
886 unsigned pathlen
= *bufsize
- (s
- *buf
);
887 unsigned newbufsize
= *bufsize
;
890 while (newbufsize
< pathlen
+ len
+ 1) {
891 if (newbufsize
>= 0x80000000)
892 newbufsize
= 0xffffffff;
897 newbuf
= realloc(*buf
, newbufsize
);
902 s
= newbuf
+ newbufsize
- pathlen
;
903 memmove(s
, newbuf
+ *bufsize
- pathlen
, pathlen
);
904 *bufsize
= newbufsize
;
907 strncpy(s
, name
, len
);
914 static void unlock_path(struct fuse
*f
, fuse_ino_t nodeid
, struct node
*wnode
,
920 assert(wnode
->treelock
== TREELOCK_WRITE
);
924 for (node
= get_node(f
, nodeid
);
925 node
!= end
&& node
->nodeid
!= FUSE_ROOT_ID
; node
= node
->parent
) {
926 assert(node
->treelock
!= 0);
927 assert(node
->treelock
!= TREELOCK_WAIT_OFFSET
);
928 assert(node
->treelock
!= TREELOCK_WRITE
);
930 if (node
->treelock
== TREELOCK_WAIT_OFFSET
)
935 static int try_get_path(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
936 char **path
, struct node
**wnodep
, bool need_lock
)
938 unsigned bufsize
= 256;
942 struct node
*wnode
= NULL
;
948 buf
= malloc(bufsize
);
952 s
= buf
+ bufsize
- 1;
956 s
= add_name(&buf
, &bufsize
, s
, name
);
964 wnode
= lookup_node(f
, nodeid
, name
);
966 if (wnode
->treelock
!= 0) {
967 if (wnode
->treelock
> 0)
968 wnode
->treelock
+= TREELOCK_WAIT_OFFSET
;
972 wnode
->treelock
= TREELOCK_WRITE
;
976 for (node
= get_node(f
, nodeid
); node
->nodeid
!= FUSE_ROOT_ID
;
977 node
= node
->parent
) {
979 if (node
->name
== NULL
|| node
->parent
== NULL
)
983 s
= add_name(&buf
, &bufsize
, s
, node
->name
);
989 if (node
->treelock
< 0)
997 memmove(buf
, s
, bufsize
- (s
- buf
));
1009 unlock_path(f
, nodeid
, wnode
, node
);
1017 static void queue_element_unlock(struct fuse
*f
, struct lock_queue_element
*qe
)
1021 if (qe
->first_locked
) {
1022 wnode
= qe
->wnode1
? *qe
->wnode1
: NULL
;
1023 unlock_path(f
, qe
->nodeid1
, wnode
, NULL
);
1024 qe
->first_locked
= false;
1026 if (qe
->second_locked
) {
1027 wnode
= qe
->wnode2
? *qe
->wnode2
: NULL
;
1028 unlock_path(f
, qe
->nodeid2
, wnode
, NULL
);
1029 qe
->second_locked
= false;
1033 static void queue_element_wakeup(struct fuse
*f
, struct lock_queue_element
*qe
)
1036 bool first
= (qe
== f
->lockq
);
1039 /* Just waiting for it to be unlocked */
1040 if (get_node(f
, qe
->nodeid1
)->treelock
== 0)
1041 pthread_cond_signal(&qe
->cond
);
1046 if (!qe
->first_locked
) {
1047 err
= try_get_path(f
, qe
->nodeid1
, qe
->name1
, qe
->path1
,
1050 qe
->first_locked
= true;
1051 else if (err
!= -EAGAIN
)
1054 if (!qe
->second_locked
&& qe
->path2
) {
1055 err
= try_get_path(f
, qe
->nodeid2
, qe
->name2
, qe
->path2
,
1058 qe
->second_locked
= true;
1059 else if (err
!= -EAGAIN
)
1063 if (qe
->first_locked
&& (qe
->second_locked
|| !qe
->path2
)) {
1069 * Only let the first element be partially locked otherwise there could
1072 * But do allow the first element to be partially locked to prevent
1076 queue_element_unlock(f
, qe
);
1082 queue_element_unlock(f
, qe
);
1086 pthread_cond_signal(&qe
->cond
);
1089 static void wake_up_queued(struct fuse
*f
)
1091 struct lock_queue_element
*qe
;
1093 for (qe
= f
->lockq
; qe
!= NULL
; qe
= qe
->next
)
1094 queue_element_wakeup(f
, qe
);
1097 static void debug_path(struct fuse
*f
, const char *msg
, fuse_ino_t nodeid
,
1098 const char *name
, bool wr
)
1100 if (f
->conf
.debug
) {
1101 struct node
*wnode
= NULL
;
1104 wnode
= lookup_node(f
, nodeid
, name
);
1107 fprintf(stderr
, "%s %li (w)\n", msg
, wnode
->nodeid
);
1109 fprintf(stderr
, "%s %li\n", msg
, nodeid
);
1113 static void queue_path(struct fuse
*f
, struct lock_queue_element
*qe
)
1115 struct lock_queue_element
**qp
;
1118 qe
->first_locked
= false;
1119 qe
->second_locked
= false;
1120 pthread_cond_init(&qe
->cond
, NULL
);
1122 for (qp
= &f
->lockq
; *qp
!= NULL
; qp
= &(*qp
)->next
);
1126 static void dequeue_path(struct fuse
*f
, struct lock_queue_element
*qe
)
1128 struct lock_queue_element
**qp
;
1130 pthread_cond_destroy(&qe
->cond
);
1131 for (qp
= &f
->lockq
; *qp
!= qe
; qp
= &(*qp
)->next
);
1135 static int wait_path(struct fuse
*f
, struct lock_queue_element
*qe
)
1140 pthread_cond_wait(&qe
->cond
, &f
->lock
);
1141 } while (!qe
->done
);
1143 dequeue_path(f
, qe
);
1148 static int get_path_common(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1149 char **path
, struct node
**wnode
)
1153 pthread_mutex_lock(&f
->lock
);
1154 err
= try_get_path(f
, nodeid
, name
, path
, wnode
, true);
1155 if (err
== -EAGAIN
) {
1156 struct lock_queue_element qe
= {
1162 debug_path(f
, "QUEUE PATH", nodeid
, name
, !!wnode
);
1163 err
= wait_path(f
, &qe
);
1164 debug_path(f
, "DEQUEUE PATH", nodeid
, name
, !!wnode
);
1166 pthread_mutex_unlock(&f
->lock
);
1171 static int get_path(struct fuse
*f
, fuse_ino_t nodeid
, char **path
)
1173 return get_path_common(f
, nodeid
, NULL
, path
, NULL
);
1176 static int get_path_nullok(struct fuse
*f
, fuse_ino_t nodeid
, char **path
)
1180 if (f
->conf
.nopath
) {
1183 err
= get_path_common(f
, nodeid
, NULL
, path
, NULL
);
1184 if (err
== -ENOENT
&& f
->nullpath_ok
)
1191 static int get_path_name(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1194 return get_path_common(f
, nodeid
, name
, path
, NULL
);
1197 static int get_path_wrlock(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
,
1198 char **path
, struct node
**wnode
)
1200 return get_path_common(f
, nodeid
, name
, path
, wnode
);
1203 static int try_get_path2(struct fuse
*f
, fuse_ino_t nodeid1
, const char *name1
,
1204 fuse_ino_t nodeid2
, const char *name2
,
1205 char **path1
, char **path2
,
1206 struct node
**wnode1
, struct node
**wnode2
)
1210 /* FIXME: locking two paths needs deadlock checking */
1211 err
= try_get_path(f
, nodeid1
, name1
, path1
, wnode1
, true);
1213 err
= try_get_path(f
, nodeid2
, name2
, path2
, wnode2
, true);
1215 struct node
*wn1
= wnode1
? *wnode1
: NULL
;
1217 unlock_path(f
, nodeid1
, wn1
, NULL
);
1224 static int get_path2(struct fuse
*f
, fuse_ino_t nodeid1
, const char *name1
,
1225 fuse_ino_t nodeid2
, const char *name2
,
1226 char **path1
, char **path2
,
1227 struct node
**wnode1
, struct node
**wnode2
)
1231 pthread_mutex_lock(&f
->lock
);
1232 err
= try_get_path2(f
, nodeid1
, name1
, nodeid2
, name2
,
1233 path1
, path2
, wnode1
, wnode2
);
1234 if (err
== -EAGAIN
) {
1235 struct lock_queue_element qe
= {
1246 debug_path(f
, "QUEUE PATH1", nodeid1
, name1
, !!wnode1
);
1247 debug_path(f
, " PATH2", nodeid2
, name2
, !!wnode2
);
1248 err
= wait_path(f
, &qe
);
1249 debug_path(f
, "DEQUEUE PATH1", nodeid1
, name1
, !!wnode1
);
1250 debug_path(f
, " PATH2", nodeid2
, name2
, !!wnode2
);
1252 pthread_mutex_unlock(&f
->lock
);
1257 static void free_path_wrlock(struct fuse
*f
, fuse_ino_t nodeid
,
1258 struct node
*wnode
, char *path
)
1260 pthread_mutex_lock(&f
->lock
);
1261 unlock_path(f
, nodeid
, wnode
, NULL
);
1264 pthread_mutex_unlock(&f
->lock
);
1268 static void free_path(struct fuse
*f
, fuse_ino_t nodeid
, char *path
)
1271 free_path_wrlock(f
, nodeid
, NULL
, path
);
1274 static void free_path2(struct fuse
*f
, fuse_ino_t nodeid1
, fuse_ino_t nodeid2
,
1275 struct node
*wnode1
, struct node
*wnode2
,
1276 char *path1
, char *path2
)
1278 pthread_mutex_lock(&f
->lock
);
1279 unlock_path(f
, nodeid1
, wnode1
, NULL
);
1280 unlock_path(f
, nodeid2
, wnode2
, NULL
);
1282 pthread_mutex_unlock(&f
->lock
);
1287 static void forget_node(struct fuse
*f
, fuse_ino_t nodeid
, uint64_t nlookup
)
1290 if (nodeid
== FUSE_ROOT_ID
)
1292 pthread_mutex_lock(&f
->lock
);
1293 node
= get_node(f
, nodeid
);
1296 * Node may still be locked due to interrupt idiocy in open,
1297 * create and opendir
1299 while (node
->nlookup
== nlookup
&& node
->treelock
) {
1300 struct lock_queue_element qe
= {
1304 debug_path(f
, "QUEUE PATH (forget)", nodeid
, NULL
, false);
1308 pthread_cond_wait(&qe
.cond
, &f
->lock
);
1309 } while (node
->nlookup
== nlookup
&& node
->treelock
);
1311 dequeue_path(f
, &qe
);
1312 debug_path(f
, "DEQUEUE_PATH (forget)", nodeid
, NULL
, false);
1315 assert(node
->nlookup
>= nlookup
);
1316 node
->nlookup
-= nlookup
;
1317 if (!node
->nlookup
) {
1318 unref_node(f
, node
);
1319 } else if (lru_enabled(f
) && node
->nlookup
== 1) {
1320 set_forget_time(f
, node
);
1322 pthread_mutex_unlock(&f
->lock
);
1325 static void unlink_node(struct fuse
*f
, struct node
*node
)
1327 if (f
->conf
.remember
) {
1328 assert(node
->nlookup
> 1);
1331 unhash_name(f
, node
);
1334 static void remove_node(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
1338 pthread_mutex_lock(&f
->lock
);
1339 node
= lookup_node(f
, dir
, name
);
1341 unlink_node(f
, node
);
1342 pthread_mutex_unlock(&f
->lock
);
1345 static int rename_node(struct fuse
*f
, fuse_ino_t olddir
, const char *oldname
,
1346 fuse_ino_t newdir
, const char *newname
, int hide
)
1349 struct node
*newnode
;
1352 pthread_mutex_lock(&f
->lock
);
1353 node
= lookup_node(f
, olddir
, oldname
);
1354 newnode
= lookup_node(f
, newdir
, newname
);
1358 if (newnode
!= NULL
) {
1360 fprintf(stderr
, "fuse: hidden file got created during hiding\n");
1364 unlink_node(f
, newnode
);
1367 unhash_name(f
, node
);
1368 if (hash_name(f
, node
, newdir
, newname
) == -1) {
1374 node
->is_hidden
= 1;
1377 pthread_mutex_unlock(&f
->lock
);
1381 static void set_stat(struct fuse
*f
, fuse_ino_t nodeid
, struct stat
*stbuf
)
1383 if (!f
->conf
.use_ino
)
1384 stbuf
->st_ino
= nodeid
;
1385 if (f
->conf
.set_mode
)
1386 stbuf
->st_mode
= (stbuf
->st_mode
& S_IFMT
) |
1387 (0777 & ~f
->conf
.umask
);
1388 if (f
->conf
.set_uid
)
1389 stbuf
->st_uid
= f
->conf
.uid
;
1390 if (f
->conf
.set_gid
)
1391 stbuf
->st_gid
= f
->conf
.gid
;
1394 static struct fuse
*req_fuse(fuse_req_t req
)
1396 return (struct fuse
*) fuse_req_userdata(req
);
1399 static void fuse_intr_sighandler(int sig
)
1405 struct fuse_intr_data
{
1407 pthread_cond_t cond
;
1411 static void fuse_interrupt(fuse_req_t req
, void *d_
)
1413 struct fuse_intr_data
*d
= d_
;
1414 struct fuse
*f
= req_fuse(req
);
1416 if (d
->id
== pthread_self())
1419 pthread_mutex_lock(&f
->lock
);
1420 while (!d
->finished
) {
1422 struct timespec timeout
;
1424 pthread_kill(d
->id
, f
->conf
.intr_signal
);
1425 gettimeofday(&now
, NULL
);
1426 timeout
.tv_sec
= now
.tv_sec
+ 1;
1427 timeout
.tv_nsec
= now
.tv_usec
* 1000;
1428 pthread_cond_timedwait(&d
->cond
, &f
->lock
, &timeout
);
1430 pthread_mutex_unlock(&f
->lock
);
1433 static void fuse_do_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
1434 struct fuse_intr_data
*d
)
1436 pthread_mutex_lock(&f
->lock
);
1438 pthread_cond_broadcast(&d
->cond
);
1439 pthread_mutex_unlock(&f
->lock
);
1440 fuse_req_interrupt_func(req
, NULL
, NULL
);
1441 pthread_cond_destroy(&d
->cond
);
1444 static void fuse_do_prepare_interrupt(fuse_req_t req
, struct fuse_intr_data
*d
)
1446 d
->id
= pthread_self();
1447 pthread_cond_init(&d
->cond
, NULL
);
1449 fuse_req_interrupt_func(req
, fuse_interrupt
, d
);
1452 static inline void fuse_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
1453 struct fuse_intr_data
*d
)
1456 fuse_do_finish_interrupt(f
, req
, d
);
1459 static inline void fuse_prepare_interrupt(struct fuse
*f
, fuse_req_t req
,
1460 struct fuse_intr_data
*d
)
1463 fuse_do_prepare_interrupt(req
, d
);
1466 #if !defined(__FreeBSD__) && !defined(__NetBSD__)
1468 static int fuse_compat_open(struct fuse_fs
*fs
, const char *path
,
1469 struct fuse_file_info
*fi
)
1472 if (!fs
->compat
|| fs
->compat
>= 25)
1473 err
= fs
->op
.open(path
, fi
);
1474 else if (fs
->compat
== 22) {
1475 struct fuse_file_info_compat tmp
;
1476 memcpy(&tmp
, fi
, sizeof(tmp
));
1477 err
= ((struct fuse_operations_compat22
*) &fs
->op
)->open(path
,
1479 memcpy(fi
, &tmp
, sizeof(tmp
));
1482 err
= ((struct fuse_operations_compat2
*) &fs
->op
)
1483 ->open(path
, fi
->flags
);
1487 static int fuse_compat_release(struct fuse_fs
*fs
, const char *path
,
1488 struct fuse_file_info
*fi
)
1490 if (!fs
->compat
|| fs
->compat
>= 22)
1491 return fs
->op
.release(path
, fi
);
1493 return ((struct fuse_operations_compat2
*) &fs
->op
)
1494 ->release(path
, fi
->flags
);
1497 static int fuse_compat_opendir(struct fuse_fs
*fs
, const char *path
,
1498 struct fuse_file_info
*fi
)
1500 if (!fs
->compat
|| fs
->compat
>= 25)
1501 return fs
->op
.opendir(path
, fi
);
1504 struct fuse_file_info_compat tmp
;
1505 memcpy(&tmp
, fi
, sizeof(tmp
));
1506 err
= ((struct fuse_operations_compat22
*) &fs
->op
)
1507 ->opendir(path
, &tmp
);
1508 memcpy(fi
, &tmp
, sizeof(tmp
));
1514 static void convert_statfs_compat(struct fuse_statfs_compat1
*compatbuf
,
1515 struct statvfs
*stbuf
)
1517 stbuf
->f_bsize
= compatbuf
->block_size
;
1518 stbuf
->f_blocks
= compatbuf
->blocks
;
1519 stbuf
->f_bfree
= compatbuf
->blocks_free
;
1520 stbuf
->f_bavail
= compatbuf
->blocks_free
;
1521 stbuf
->f_files
= compatbuf
->files
;
1522 stbuf
->f_ffree
= compatbuf
->files_free
;
1523 stbuf
->f_namemax
= compatbuf
->namelen
;
1526 static void convert_statfs_old(struct statfs
*oldbuf
, struct statvfs
*stbuf
)
1528 stbuf
->f_bsize
= oldbuf
->f_bsize
;
1529 stbuf
->f_blocks
= oldbuf
->f_blocks
;
1530 stbuf
->f_bfree
= oldbuf
->f_bfree
;
1531 stbuf
->f_bavail
= oldbuf
->f_bavail
;
1532 stbuf
->f_files
= oldbuf
->f_files
;
1533 stbuf
->f_ffree
= oldbuf
->f_ffree
;
1534 stbuf
->f_namemax
= oldbuf
->f_namelen
;
1537 static int fuse_compat_statfs(struct fuse_fs
*fs
, const char *path
,
1538 struct statvfs
*buf
)
1542 if (!fs
->compat
|| fs
->compat
>= 25) {
1543 err
= fs
->op
.statfs(fs
->compat
== 25 ? "/" : path
, buf
);
1544 } else if (fs
->compat
> 11) {
1545 struct statfs oldbuf
;
1546 err
= ((struct fuse_operations_compat22
*) &fs
->op
)
1547 ->statfs("/", &oldbuf
);
1549 convert_statfs_old(&oldbuf
, buf
);
1551 struct fuse_statfs_compat1 compatbuf
;
1552 memset(&compatbuf
, 0, sizeof(struct fuse_statfs_compat1
));
1553 err
= ((struct fuse_operations_compat1
*) &fs
->op
)
1554 ->statfs(&compatbuf
);
1556 convert_statfs_compat(&compatbuf
, buf
);
1561 #else /* __FreeBSD__ || __NetBSD__ */
1563 static inline int fuse_compat_open(struct fuse_fs
*fs
, char *path
,
1564 struct fuse_file_info
*fi
)
1566 return fs
->op
.open(path
, fi
);
1569 static inline int fuse_compat_release(struct fuse_fs
*fs
, const char *path
,
1570 struct fuse_file_info
*fi
)
1572 return fs
->op
.release(path
, fi
);
1575 static inline int fuse_compat_opendir(struct fuse_fs
*fs
, const char *path
,
1576 struct fuse_file_info
*fi
)
1578 return fs
->op
.opendir(path
, fi
);
1581 static inline int fuse_compat_statfs(struct fuse_fs
*fs
, const char *path
,
1582 struct statvfs
*buf
)
1584 return fs
->op
.statfs(fs
->compat
== 25 ? "/" : path
, buf
);
1587 #endif /* __FreeBSD__ || __NetBSD__ */
1589 int fuse_fs_getattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
)
1591 fuse_get_context()->private_data
= fs
->user_data
;
1592 if (fs
->op
.getattr
) {
1594 fprintf(stderr
, "getattr %s\n", path
);
1596 return fs
->op
.getattr(path
, buf
);
1602 int fuse_fs_fgetattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
,
1603 struct fuse_file_info
*fi
)
1605 fuse_get_context()->private_data
= fs
->user_data
;
1606 if (fs
->op
.fgetattr
) {
1608 fprintf(stderr
, "fgetattr[%llu] %s\n",
1609 (unsigned long long) fi
->fh
, path
);
1611 return fs
->op
.fgetattr(path
, buf
, fi
);
1612 } else if (path
&& fs
->op
.getattr
) {
1614 fprintf(stderr
, "getattr %s\n", path
);
1616 return fs
->op
.getattr(path
, buf
);
1622 int fuse_fs_rename(struct fuse_fs
*fs
, const char *oldpath
,
1623 const char *newpath
)
1625 fuse_get_context()->private_data
= fs
->user_data
;
1626 if (fs
->op
.rename
) {
1628 fprintf(stderr
, "rename %s %s\n", oldpath
, newpath
);
1630 return fs
->op
.rename(oldpath
, newpath
);
1636 int fuse_fs_unlink(struct fuse_fs
*fs
, const char *path
)
1638 fuse_get_context()->private_data
= fs
->user_data
;
1639 if (fs
->op
.unlink
) {
1641 fprintf(stderr
, "unlink %s\n", path
);
1643 return fs
->op
.unlink(path
);
1649 int fuse_fs_rmdir(struct fuse_fs
*fs
, const char *path
)
1651 fuse_get_context()->private_data
= fs
->user_data
;
1654 fprintf(stderr
, "rmdir %s\n", path
);
1656 return fs
->op
.rmdir(path
);
1662 int fuse_fs_symlink(struct fuse_fs
*fs
, const char *linkname
, const char *path
)
1664 fuse_get_context()->private_data
= fs
->user_data
;
1665 if (fs
->op
.symlink
) {
1667 fprintf(stderr
, "symlink %s %s\n", linkname
, path
);
1669 return fs
->op
.symlink(linkname
, path
);
1675 int fuse_fs_link(struct fuse_fs
*fs
, const char *oldpath
, const char *newpath
)
1677 fuse_get_context()->private_data
= fs
->user_data
;
1680 fprintf(stderr
, "link %s %s\n", oldpath
, newpath
);
1682 return fs
->op
.link(oldpath
, newpath
);
1688 int fuse_fs_release(struct fuse_fs
*fs
, const char *path
,
1689 struct fuse_file_info
*fi
)
1691 fuse_get_context()->private_data
= fs
->user_data
;
1692 if (fs
->op
.release
) {
1694 fprintf(stderr
, "release%s[%llu] flags: 0x%x\n",
1695 fi
->flush
? "+flush" : "",
1696 (unsigned long long) fi
->fh
, fi
->flags
);
1698 return fuse_compat_release(fs
, path
, fi
);
1704 int fuse_fs_opendir(struct fuse_fs
*fs
, const char *path
,
1705 struct fuse_file_info
*fi
)
1707 fuse_get_context()->private_data
= fs
->user_data
;
1708 if (fs
->op
.opendir
) {
1712 fprintf(stderr
, "opendir flags: 0x%x %s\n", fi
->flags
,
1715 err
= fuse_compat_opendir(fs
, path
, fi
);
1717 if (fs
->debug
&& !err
)
1718 fprintf(stderr
, " opendir[%lli] flags: 0x%x %s\n",
1719 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1727 int fuse_fs_open(struct fuse_fs
*fs
, const char *path
,
1728 struct fuse_file_info
*fi
)
1730 fuse_get_context()->private_data
= fs
->user_data
;
1735 fprintf(stderr
, "open flags: 0x%x %s\n", fi
->flags
,
1738 err
= fuse_compat_open(fs
, path
, fi
);
1740 if (fs
->debug
&& !err
)
1741 fprintf(stderr
, " open[%lli] flags: 0x%x %s\n",
1742 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1750 static void fuse_free_buf(struct fuse_bufvec
*buf
)
1755 for (i
= 0; i
< buf
->count
; i
++)
1756 free(buf
->buf
[i
].mem
);
1761 int fuse_fs_read_buf(struct fuse_fs
*fs
, const char *path
,
1762 struct fuse_bufvec
**bufp
, size_t size
, off_t off
,
1763 struct fuse_file_info
*fi
)
1765 fuse_get_context()->private_data
= fs
->user_data
;
1766 if (fs
->op
.read
|| fs
->op
.read_buf
) {
1771 "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1772 (unsigned long long) fi
->fh
,
1773 size
, (unsigned long long) off
, fi
->flags
);
1775 if (fs
->op
.read_buf
) {
1776 res
= fs
->op
.read_buf(path
, bufp
, size
, off
, fi
);
1778 struct fuse_bufvec
*buf
;
1781 buf
= malloc(sizeof(struct fuse_bufvec
));
1790 *buf
= FUSE_BUFVEC_INIT(size
);
1791 buf
->buf
[0].mem
= mem
;
1794 res
= fs
->op
.read(path
, mem
, size
, off
, fi
);
1796 buf
->buf
[0].size
= res
;
1799 if (fs
->debug
&& res
>= 0)
1800 fprintf(stderr
, " read[%llu] %zu bytes from %llu\n",
1801 (unsigned long long) fi
->fh
,
1802 fuse_buf_size(*bufp
),
1803 (unsigned long long) off
);
1804 if (res
>= 0 && fuse_buf_size(*bufp
) > (int) size
)
1805 fprintf(stderr
, "fuse: read too many bytes\n");
1816 int fuse_fs_read(struct fuse_fs
*fs
, const char *path
, char *mem
, size_t size
,
1817 off_t off
, struct fuse_file_info
*fi
)
1820 struct fuse_bufvec
*buf
= NULL
;
1822 res
= fuse_fs_read_buf(fs
, path
, &buf
, size
, off
, fi
);
1824 struct fuse_bufvec dst
= FUSE_BUFVEC_INIT(size
);
1826 dst
.buf
[0].mem
= mem
;
1827 res
= fuse_buf_copy(&dst
, buf
, 0);
1834 int fuse_fs_write_buf(struct fuse_fs
*fs
, const char *path
,
1835 struct fuse_bufvec
*buf
, off_t off
,
1836 struct fuse_file_info
*fi
)
1838 fuse_get_context()->private_data
= fs
->user_data
;
1839 if (fs
->op
.write_buf
|| fs
->op
.write
) {
1841 size_t size
= fuse_buf_size(buf
);
1843 assert(buf
->idx
== 0 && buf
->off
== 0);
1846 "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1847 fi
->writepage
? "page" : "",
1848 (unsigned long long) fi
->fh
,
1850 (unsigned long long) off
,
1853 if (fs
->op
.write_buf
) {
1854 res
= fs
->op
.write_buf(path
, buf
, off
, fi
);
1857 struct fuse_buf
*flatbuf
;
1858 struct fuse_bufvec tmp
= FUSE_BUFVEC_INIT(size
);
1860 if (buf
->count
== 1 &&
1861 !(buf
->buf
[0].flags
& FUSE_BUF_IS_FD
)) {
1862 flatbuf
= &buf
->buf
[0];
1869 tmp
.buf
[0].mem
= mem
;
1870 res
= fuse_buf_copy(&tmp
, buf
, 0);
1874 tmp
.buf
[0].size
= res
;
1875 flatbuf
= &tmp
.buf
[0];
1878 res
= fs
->op
.write(path
, flatbuf
->mem
, flatbuf
->size
,
1884 if (fs
->debug
&& res
>= 0)
1885 fprintf(stderr
, " write%s[%llu] %u bytes to %llu\n",
1886 fi
->writepage
? "page" : "",
1887 (unsigned long long) fi
->fh
, res
,
1888 (unsigned long long) off
);
1889 if (res
> (int) size
)
1890 fprintf(stderr
, "fuse: wrote too many bytes\n");
1898 int fuse_fs_write(struct fuse_fs
*fs
, const char *path
, const char *mem
,
1899 size_t size
, off_t off
, struct fuse_file_info
*fi
)
1901 struct fuse_bufvec bufv
= FUSE_BUFVEC_INIT(size
);
1903 bufv
.buf
[0].mem
= (void *) mem
;
1905 return fuse_fs_write_buf(fs
, path
, &bufv
, off
, fi
);
1908 int fuse_fs_fsync(struct fuse_fs
*fs
, const char *path
, int datasync
,
1909 struct fuse_file_info
*fi
)
1911 fuse_get_context()->private_data
= fs
->user_data
;
1914 fprintf(stderr
, "fsync[%llu] datasync: %i\n",
1915 (unsigned long long) fi
->fh
, datasync
);
1917 return fs
->op
.fsync(path
, datasync
, fi
);
1923 int fuse_fs_fsyncdir(struct fuse_fs
*fs
, const char *path
, int datasync
,
1924 struct fuse_file_info
*fi
)
1926 fuse_get_context()->private_data
= fs
->user_data
;
1927 if (fs
->op
.fsyncdir
) {
1929 fprintf(stderr
, "fsyncdir[%llu] datasync: %i\n",
1930 (unsigned long long) fi
->fh
, datasync
);
1932 return fs
->op
.fsyncdir(path
, datasync
, fi
);
1938 int fuse_fs_flush(struct fuse_fs
*fs
, const char *path
,
1939 struct fuse_file_info
*fi
)
1941 fuse_get_context()->private_data
= fs
->user_data
;
1944 fprintf(stderr
, "flush[%llu]\n",
1945 (unsigned long long) fi
->fh
);
1947 return fs
->op
.flush(path
, fi
);
1953 int fuse_fs_statfs(struct fuse_fs
*fs
, const char *path
, struct statvfs
*buf
)
1955 fuse_get_context()->private_data
= fs
->user_data
;
1956 if (fs
->op
.statfs
) {
1958 fprintf(stderr
, "statfs %s\n", path
);
1960 return fuse_compat_statfs(fs
, path
, buf
);
1962 buf
->f_namemax
= 255;
1968 int fuse_fs_releasedir(struct fuse_fs
*fs
, const char *path
,
1969 struct fuse_file_info
*fi
)
1971 fuse_get_context()->private_data
= fs
->user_data
;
1972 if (fs
->op
.releasedir
) {
1974 fprintf(stderr
, "releasedir[%llu] flags: 0x%x\n",
1975 (unsigned long long) fi
->fh
, fi
->flags
);
1977 return fs
->op
.releasedir(path
, fi
);
1983 static int fill_dir_old(struct fuse_dirhandle
*dh
, const char *name
, int type
,
1989 memset(&stbuf
, 0, sizeof(stbuf
));
1990 stbuf
.st_mode
= type
<< 12;
1993 res
= dh
->filler(dh
->buf
, name
, &stbuf
, 0);
1994 return res
? -ENOMEM
: 0;
1997 int fuse_fs_readdir(struct fuse_fs
*fs
, const char *path
, void *buf
,
1998 fuse_fill_dir_t filler
, off_t off
,
1999 struct fuse_file_info
*fi
)
2001 fuse_get_context()->private_data
= fs
->user_data
;
2002 if (fs
->op
.readdir
) {
2004 fprintf(stderr
, "readdir[%llu] from %llu\n",
2005 (unsigned long long) fi
->fh
,
2006 (unsigned long long) off
);
2008 return fs
->op
.readdir(path
, buf
, filler
, off
, fi
);
2009 } else if (fs
->op
.getdir
) {
2010 struct fuse_dirhandle dh
;
2013 fprintf(stderr
, "getdir[%llu]\n",
2014 (unsigned long long) fi
->fh
);
2018 return fs
->op
.getdir(path
, &dh
, fill_dir_old
);
2024 int fuse_fs_create(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
2025 struct fuse_file_info
*fi
)
2027 fuse_get_context()->private_data
= fs
->user_data
;
2028 if (fs
->op
.create
) {
2033 "create flags: 0x%x %s 0%o umask=0%03o\n",
2034 fi
->flags
, path
, mode
,
2035 fuse_get_context()->umask
);
2037 err
= fs
->op
.create(path
, mode
, fi
);
2039 if (fs
->debug
&& !err
)
2040 fprintf(stderr
, " create[%llu] flags: 0x%x %s\n",
2041 (unsigned long long) fi
->fh
, fi
->flags
, path
);
2049 int fuse_fs_lock(struct fuse_fs
*fs
, const char *path
,
2050 struct fuse_file_info
*fi
, int cmd
, struct flock
*lock
)
2052 fuse_get_context()->private_data
= fs
->user_data
;
2055 fprintf(stderr
, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2056 (unsigned long long) fi
->fh
,
2057 (cmd
== F_GETLK
? "F_GETLK" :
2058 (cmd
== F_SETLK
? "F_SETLK" :
2059 (cmd
== F_SETLKW
? "F_SETLKW" : "???"))),
2060 (lock
->l_type
== F_RDLCK
? "F_RDLCK" :
2061 (lock
->l_type
== F_WRLCK
? "F_WRLCK" :
2062 (lock
->l_type
== F_UNLCK
? "F_UNLCK" :
2064 (unsigned long long) lock
->l_start
,
2065 (unsigned long long) lock
->l_len
,
2066 (unsigned long long) lock
->l_pid
);
2068 return fs
->op
.lock(path
, fi
, cmd
, lock
);
2074 int fuse_fs_flock(struct fuse_fs
*fs
, const char *path
,
2075 struct fuse_file_info
*fi
, int op
)
2077 fuse_get_context()->private_data
= fs
->user_data
;
2080 int xop
= op
& ~LOCK_NB
;
2082 fprintf(stderr
, "lock[%llu] %s%s\n",
2083 (unsigned long long) fi
->fh
,
2084 xop
== LOCK_SH
? "LOCK_SH" :
2085 (xop
== LOCK_EX
? "LOCK_EX" :
2086 (xop
== LOCK_UN
? "LOCK_UN" : "???")),
2087 (op
& LOCK_NB
) ? "|LOCK_NB" : "");
2089 return fs
->op
.flock(path
, fi
, op
);
2095 int fuse_fs_chown(struct fuse_fs
*fs
, const char *path
, uid_t uid
, gid_t gid
)
2097 fuse_get_context()->private_data
= fs
->user_data
;
2100 fprintf(stderr
, "chown %s %lu %lu\n", path
,
2101 (unsigned long) uid
, (unsigned long) gid
);
2103 return fs
->op
.chown(path
, uid
, gid
);
2109 int fuse_fs_truncate(struct fuse_fs
*fs
, const char *path
, off_t size
)
2111 fuse_get_context()->private_data
= fs
->user_data
;
2112 if (fs
->op
.truncate
) {
2114 fprintf(stderr
, "truncate %s %llu\n", path
,
2115 (unsigned long long) size
);
2117 return fs
->op
.truncate(path
, size
);
2123 int fuse_fs_ftruncate(struct fuse_fs
*fs
, const char *path
, off_t size
,
2124 struct fuse_file_info
*fi
)
2126 fuse_get_context()->private_data
= fs
->user_data
;
2127 if (fs
->op
.ftruncate
) {
2129 fprintf(stderr
, "ftruncate[%llu] %llu\n",
2130 (unsigned long long) fi
->fh
,
2131 (unsigned long long) size
);
2133 return fs
->op
.ftruncate(path
, size
, fi
);
2134 } else if (path
&& fs
->op
.truncate
) {
2136 fprintf(stderr
, "truncate %s %llu\n", path
,
2137 (unsigned long long) size
);
2139 return fs
->op
.truncate(path
, size
);
2145 int fuse_fs_utimens(struct fuse_fs
*fs
, const char *path
,
2146 const struct timespec tv
[2])
2148 fuse_get_context()->private_data
= fs
->user_data
;
2149 if (fs
->op
.utimens
) {
2151 fprintf(stderr
, "utimens %s %li.%09lu %li.%09lu\n",
2152 path
, tv
[0].tv_sec
, tv
[0].tv_nsec
,
2153 tv
[1].tv_sec
, tv
[1].tv_nsec
);
2155 return fs
->op
.utimens(path
, tv
);
2156 } else if(fs
->op
.utime
) {
2160 fprintf(stderr
, "utime %s %li %li\n", path
,
2161 tv
[0].tv_sec
, tv
[1].tv_sec
);
2163 buf
.actime
= tv
[0].tv_sec
;
2164 buf
.modtime
= tv
[1].tv_sec
;
2165 return fs
->op
.utime(path
, &buf
);
2171 int fuse_fs_access(struct fuse_fs
*fs
, const char *path
, int mask
)
2173 fuse_get_context()->private_data
= fs
->user_data
;
2174 if (fs
->op
.access
) {
2176 fprintf(stderr
, "access %s 0%o\n", path
, mask
);
2178 return fs
->op
.access(path
, mask
);
2184 int fuse_fs_readlink(struct fuse_fs
*fs
, const char *path
, char *buf
,
2187 fuse_get_context()->private_data
= fs
->user_data
;
2188 if (fs
->op
.readlink
) {
2190 fprintf(stderr
, "readlink %s %lu\n", path
,
2191 (unsigned long) len
);
2193 return fs
->op
.readlink(path
, buf
, len
);
2199 int fuse_fs_mknod(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
2202 fuse_get_context()->private_data
= fs
->user_data
;
2205 fprintf(stderr
, "mknod %s 0%o 0x%llx umask=0%03o\n",
2206 path
, mode
, (unsigned long long) rdev
,
2207 fuse_get_context()->umask
);
2209 return fs
->op
.mknod(path
, mode
, rdev
);
2215 int fuse_fs_mkdir(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
2217 fuse_get_context()->private_data
= fs
->user_data
;
2220 fprintf(stderr
, "mkdir %s 0%o umask=0%03o\n",
2221 path
, mode
, fuse_get_context()->umask
);
2223 return fs
->op
.mkdir(path
, mode
);
2229 int fuse_fs_setxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
2230 const char *value
, size_t size
, int flags
)
2232 fuse_get_context()->private_data
= fs
->user_data
;
2233 if (fs
->op
.setxattr
) {
2235 fprintf(stderr
, "setxattr %s %s %lu 0x%x\n",
2236 path
, name
, (unsigned long) size
, flags
);
2238 return fs
->op
.setxattr(path
, name
, value
, size
, flags
);
2244 int fuse_fs_getxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
2245 char *value
, size_t size
)
2247 fuse_get_context()->private_data
= fs
->user_data
;
2248 if (fs
->op
.getxattr
) {
2250 fprintf(stderr
, "getxattr %s %s %lu\n",
2251 path
, name
, (unsigned long) size
);
2253 return fs
->op
.getxattr(path
, name
, value
, size
);
2259 int fuse_fs_listxattr(struct fuse_fs
*fs
, const char *path
, char *list
,
2262 fuse_get_context()->private_data
= fs
->user_data
;
2263 if (fs
->op
.listxattr
) {
2265 fprintf(stderr
, "listxattr %s %lu\n",
2266 path
, (unsigned long) size
);
2268 return fs
->op
.listxattr(path
, list
, size
);
2274 int fuse_fs_bmap(struct fuse_fs
*fs
, const char *path
, size_t blocksize
,
2277 fuse_get_context()->private_data
= fs
->user_data
;
2280 fprintf(stderr
, "bmap %s blocksize: %lu index: %llu\n",
2281 path
, (unsigned long) blocksize
,
2282 (unsigned long long) *idx
);
2284 return fs
->op
.bmap(path
, blocksize
, idx
);
2290 int fuse_fs_removexattr(struct fuse_fs
*fs
, const char *path
, const char *name
)
2292 fuse_get_context()->private_data
= fs
->user_data
;
2293 if (fs
->op
.removexattr
) {
2295 fprintf(stderr
, "removexattr %s %s\n", path
, name
);
2297 return fs
->op
.removexattr(path
, name
);
2303 int fuse_fs_ioctl(struct fuse_fs
*fs
, const char *path
, int cmd
, void *arg
,
2304 struct fuse_file_info
*fi
, unsigned int flags
, void *data
)
2306 fuse_get_context()->private_data
= fs
->user_data
;
2309 fprintf(stderr
, "ioctl[%llu] 0x%x flags: 0x%x\n",
2310 (unsigned long long) fi
->fh
, cmd
, flags
);
2312 return fs
->op
.ioctl(path
, cmd
, arg
, fi
, flags
, data
);
2317 int fuse_fs_poll(struct fuse_fs
*fs
, const char *path
,
2318 struct fuse_file_info
*fi
, struct fuse_pollhandle
*ph
,
2321 fuse_get_context()->private_data
= fs
->user_data
;
2326 fprintf(stderr
, "poll[%llu] ph: %p\n",
2327 (unsigned long long) fi
->fh
, ph
);
2329 res
= fs
->op
.poll(path
, fi
, ph
, reventsp
);
2331 if (fs
->debug
&& !res
)
2332 fprintf(stderr
, " poll[%llu] revents: 0x%x\n",
2333 (unsigned long long) fi
->fh
, *reventsp
);
2340 int fuse_fs_fallocate(struct fuse_fs
*fs
, const char *path
, int mode
,
2341 off_t offset
, off_t length
, struct fuse_file_info
*fi
)
2343 fuse_get_context()->private_data
= fs
->user_data
;
2344 if (fs
->op
.fallocate
) {
2346 fprintf(stderr
, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2349 (unsigned long long) offset
,
2350 (unsigned long long) length
);
2352 return fs
->op
.fallocate(path
, mode
, offset
, length
, fi
);
2357 static int is_open(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
2361 pthread_mutex_lock(&f
->lock
);
2362 node
= lookup_node(f
, dir
, name
);
2363 if (node
&& node
->open_count
> 0)
2365 pthread_mutex_unlock(&f
->lock
);
2369 static char *hidden_name(struct fuse
*f
, fuse_ino_t dir
, const char *oldname
,
2370 char *newname
, size_t bufsize
)
2374 struct node
*newnode
;
2380 pthread_mutex_lock(&f
->lock
);
2381 node
= lookup_node(f
, dir
, oldname
);
2383 pthread_mutex_unlock(&f
->lock
);
2388 snprintf(newname
, bufsize
, ".fuse_hidden%08x%08x",
2389 (unsigned int) node
->nodeid
, f
->hidectr
);
2390 newnode
= lookup_node(f
, dir
, newname
);
2393 res
= try_get_path(f
, dir
, newname
, &newpath
, NULL
, false);
2394 pthread_mutex_unlock(&f
->lock
);
2398 res
= fuse_fs_getattr(f
->fs
, newpath
, &buf
);
2403 } while(res
== 0 && --failctr
);
2408 static int hide_node(struct fuse
*f
, const char *oldpath
,
2409 fuse_ino_t dir
, const char *oldname
)
2415 newpath
= hidden_name(f
, dir
, oldname
, newname
, sizeof(newname
));
2417 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
2419 err
= rename_node(f
, dir
, oldname
, dir
, newname
, 1);
2425 static int mtime_eq(const struct stat
*stbuf
, const struct timespec
*ts
)
2427 return stbuf
->st_mtime
== ts
->tv_sec
&&
2428 ST_MTIM_NSEC(stbuf
) == ts
->tv_nsec
;
2431 #ifndef CLOCK_MONOTONIC
2432 #define CLOCK_MONOTONIC CLOCK_REALTIME
2435 static void curr_time(struct timespec
*now
)
2437 static clockid_t clockid
= CLOCK_MONOTONIC
;
2438 int res
= clock_gettime(clockid
, now
);
2439 if (res
== -1 && errno
== EINVAL
) {
2440 clockid
= CLOCK_REALTIME
;
2441 res
= clock_gettime(clockid
, now
);
2444 perror("fuse: clock_gettime");
2449 static void update_stat(struct node
*node
, const struct stat
*stbuf
)
2451 if (node
->cache_valid
&& (!mtime_eq(stbuf
, &node
->mtime
) ||
2452 stbuf
->st_size
!= node
->size
))
2453 node
->cache_valid
= 0;
2454 node
->mtime
.tv_sec
= stbuf
->st_mtime
;
2455 node
->mtime
.tv_nsec
= ST_MTIM_NSEC(stbuf
);
2456 node
->size
= stbuf
->st_size
;
2457 curr_time(&node
->stat_updated
);
2460 static int lookup_path(struct fuse
*f
, fuse_ino_t nodeid
,
2461 const char *name
, const char *path
,
2462 struct fuse_entry_param
*e
, struct fuse_file_info
*fi
)
2466 memset(e
, 0, sizeof(struct fuse_entry_param
));
2468 res
= fuse_fs_fgetattr(f
->fs
, path
, &e
->attr
, fi
);
2470 res
= fuse_fs_getattr(f
->fs
, path
, &e
->attr
);
2474 node
= find_node(f
, nodeid
, name
);
2478 e
->ino
= node
->nodeid
;
2479 e
->generation
= node
->generation
;
2480 e
->entry_timeout
= f
->conf
.entry_timeout
;
2481 e
->attr_timeout
= f
->conf
.attr_timeout
;
2482 if (f
->conf
.auto_cache
) {
2483 pthread_mutex_lock(&f
->lock
);
2484 update_stat(node
, &e
->attr
);
2485 pthread_mutex_unlock(&f
->lock
);
2487 set_stat(f
, e
->ino
, &e
->attr
);
2489 fprintf(stderr
, " NODEID: %lu\n",
2490 (unsigned long) e
->ino
);
2496 static struct fuse_context_i
*fuse_get_context_internal(void)
2498 struct fuse_context_i
*c
;
2500 c
= (struct fuse_context_i
*) pthread_getspecific(fuse_context_key
);
2502 c
= (struct fuse_context_i
*)
2503 calloc(1, sizeof(struct fuse_context_i
));
2505 /* This is hard to deal with properly, so just
2506 abort. If memory is so low that the
2507 context cannot be allocated, there's not
2508 much hope for the filesystem anyway */
2509 fprintf(stderr
, "fuse: failed to allocate thread specific data\n");
2512 pthread_setspecific(fuse_context_key
, c
);
2517 static void fuse_freecontext(void *data
)
2522 static int fuse_create_context_key(void)
2525 pthread_mutex_lock(&fuse_context_lock
);
2526 if (!fuse_context_ref
) {
2527 err
= pthread_key_create(&fuse_context_key
, fuse_freecontext
);
2529 fprintf(stderr
, "fuse: failed to create thread specific key: %s\n",
2531 pthread_mutex_unlock(&fuse_context_lock
);
2536 pthread_mutex_unlock(&fuse_context_lock
);
2540 static void fuse_delete_context_key(void)
2542 pthread_mutex_lock(&fuse_context_lock
);
2544 if (!fuse_context_ref
) {
2545 free(pthread_getspecific(fuse_context_key
));
2546 pthread_key_delete(fuse_context_key
);
2548 pthread_mutex_unlock(&fuse_context_lock
);
2551 static struct fuse
*req_fuse_prepare(fuse_req_t req
)
2553 struct fuse_context_i
*c
= fuse_get_context_internal();
2554 const struct fuse_ctx
*ctx
= fuse_req_ctx(req
);
2556 c
->ctx
.fuse
= req_fuse(req
);
2557 c
->ctx
.uid
= ctx
->uid
;
2558 c
->ctx
.gid
= ctx
->gid
;
2559 c
->ctx
.pid
= ctx
->pid
;
2560 c
->ctx
.umask
= ctx
->umask
;
2564 static inline void reply_err(fuse_req_t req
, int err
)
2566 /* fuse_reply_err() uses non-negated errno values */
2567 fuse_reply_err(req
, -err
);
2570 static void reply_entry(fuse_req_t req
, const struct fuse_entry_param
*e
,
2574 struct fuse
*f
= req_fuse(req
);
2575 if (fuse_reply_entry(req
, e
) == -ENOENT
) {
2576 /* Skip forget for negative result */
2578 forget_node(f
, e
->ino
, 1);
2581 reply_err(req
, err
);
2584 void fuse_fs_init(struct fuse_fs
*fs
, struct fuse_conn_info
*conn
)
2586 fuse_get_context()->private_data
= fs
->user_data
;
2587 if (!fs
->op
.write_buf
)
2588 conn
->want
&= ~FUSE_CAP_SPLICE_READ
;
2590 conn
->want
&= ~FUSE_CAP_POSIX_LOCKS
;
2592 conn
->want
&= ~FUSE_CAP_FLOCK_LOCKS
;
2594 fs
->user_data
= fs
->op
.init(conn
);
2597 static void fuse_lib_init(void *data
, struct fuse_conn_info
*conn
)
2599 struct fuse
*f
= (struct fuse
*) data
;
2600 struct fuse_context_i
*c
= fuse_get_context_internal();
2602 memset(c
, 0, sizeof(*c
));
2604 conn
->want
|= FUSE_CAP_EXPORT_SUPPORT
;
2605 fuse_fs_init(f
->fs
, conn
);
2608 void fuse_fs_destroy(struct fuse_fs
*fs
)
2610 fuse_get_context()->private_data
= fs
->user_data
;
2612 fs
->op
.destroy(fs
->user_data
);
2614 fuse_put_module(fs
->m
);
2618 static void fuse_lib_destroy(void *data
)
2620 struct fuse
*f
= (struct fuse
*) data
;
2621 struct fuse_context_i
*c
= fuse_get_context_internal();
2623 memset(c
, 0, sizeof(*c
));
2625 fuse_fs_destroy(f
->fs
);
2629 static void fuse_lib_lookup(fuse_req_t req
, fuse_ino_t parent
,
2632 struct fuse
*f
= req_fuse_prepare(req
);
2633 struct fuse_entry_param e
;
2636 struct node
*dot
= NULL
;
2638 if (name
[0] == '.') {
2639 int len
= strlen(name
);
2641 if (len
== 1 || (name
[1] == '.' && len
== 2)) {
2642 pthread_mutex_lock(&f
->lock
);
2645 fprintf(stderr
, "LOOKUP-DOT\n");
2646 dot
= get_node_nocheck(f
, parent
);
2648 pthread_mutex_unlock(&f
->lock
);
2649 reply_entry(req
, &e
, -ESTALE
);
2655 fprintf(stderr
, "LOOKUP-DOTDOT\n");
2656 parent
= get_node(f
, parent
)->parent
->nodeid
;
2658 pthread_mutex_unlock(&f
->lock
);
2663 err
= get_path_name(f
, parent
, name
, &path
);
2665 struct fuse_intr_data d
;
2667 fprintf(stderr
, "LOOKUP %s\n", path
);
2668 fuse_prepare_interrupt(f
, req
, &d
);
2669 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2670 if (err
== -ENOENT
&& f
->conf
.negative_timeout
!= 0.0) {
2672 e
.entry_timeout
= f
->conf
.negative_timeout
;
2675 fuse_finish_interrupt(f
, req
, &d
);
2676 free_path(f
, parent
, path
);
2679 pthread_mutex_lock(&f
->lock
);
2681 pthread_mutex_unlock(&f
->lock
);
2683 reply_entry(req
, &e
, err
);
2686 static void do_forget(struct fuse
*f
, fuse_ino_t ino
, uint64_t nlookup
)
2689 fprintf(stderr
, "FORGET %llu/%llu\n", (unsigned long long)ino
,
2690 (unsigned long long) nlookup
);
2691 forget_node(f
, ino
, nlookup
);
2694 static void fuse_lib_forget(fuse_req_t req
, fuse_ino_t ino
,
2695 unsigned long nlookup
)
2697 do_forget(req_fuse(req
), ino
, nlookup
);
2698 fuse_reply_none(req
);
2701 static void fuse_lib_forget_multi(fuse_req_t req
, size_t count
,
2702 struct fuse_forget_data
*forgets
)
2704 struct fuse
*f
= req_fuse(req
);
2707 for (i
= 0; i
< count
; i
++)
2708 do_forget(f
, forgets
[i
].ino
, forgets
[i
].nlookup
);
2710 fuse_reply_none(req
);
2714 static void fuse_lib_getattr(fuse_req_t req
, fuse_ino_t ino
,
2715 struct fuse_file_info
*fi
)
2717 struct fuse
*f
= req_fuse_prepare(req
);
2722 memset(&buf
, 0, sizeof(buf
));
2724 if (fi
!= NULL
&& f
->fs
->op
.fgetattr
)
2725 err
= get_path_nullok(f
, ino
, &path
);
2727 err
= get_path(f
, ino
, &path
);
2729 struct fuse_intr_data d
;
2730 fuse_prepare_interrupt(f
, req
, &d
);
2732 err
= fuse_fs_fgetattr(f
->fs
, path
, &buf
, fi
);
2734 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
2735 fuse_finish_interrupt(f
, req
, &d
);
2736 free_path(f
, ino
, path
);
2741 pthread_mutex_lock(&f
->lock
);
2742 node
= get_node(f
, ino
);
2743 if (node
->is_hidden
&& buf
.st_nlink
> 0)
2745 if (f
->conf
.auto_cache
)
2746 update_stat(node
, &buf
);
2747 pthread_mutex_unlock(&f
->lock
);
2748 set_stat(f
, ino
, &buf
);
2749 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
2751 reply_err(req
, err
);
2754 int fuse_fs_chmod(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
2756 fuse_get_context()->private_data
= fs
->user_data
;
2758 return fs
->op
.chmod(path
, mode
);
2763 static void fuse_lib_setattr(fuse_req_t req
, fuse_ino_t ino
, struct stat
*attr
,
2764 int valid
, struct fuse_file_info
*fi
)
2766 struct fuse
*f
= req_fuse_prepare(req
);
2771 if (valid
== FUSE_SET_ATTR_SIZE
&& fi
!= NULL
&&
2772 f
->fs
->op
.ftruncate
&& f
->fs
->op
.fgetattr
)
2773 err
= get_path_nullok(f
, ino
, &path
);
2775 err
= get_path(f
, ino
, &path
);
2777 struct fuse_intr_data d
;
2778 fuse_prepare_interrupt(f
, req
, &d
);
2780 if (!err
&& (valid
& FUSE_SET_ATTR_MODE
))
2781 err
= fuse_fs_chmod(f
->fs
, path
, attr
->st_mode
);
2782 if (!err
&& (valid
& (FUSE_SET_ATTR_UID
| FUSE_SET_ATTR_GID
))) {
2783 uid_t uid
= (valid
& FUSE_SET_ATTR_UID
) ?
2784 attr
->st_uid
: (uid_t
) -1;
2785 gid_t gid
= (valid
& FUSE_SET_ATTR_GID
) ?
2786 attr
->st_gid
: (gid_t
) -1;
2787 err
= fuse_fs_chown(f
->fs
, path
, uid
, gid
);
2789 if (!err
&& (valid
& FUSE_SET_ATTR_SIZE
)) {
2791 err
= fuse_fs_ftruncate(f
->fs
, path
,
2794 err
= fuse_fs_truncate(f
->fs
, path
,
2797 #ifdef HAVE_UTIMENSAT
2798 if (!err
&& f
->utime_omit_ok
&&
2799 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
))) {
2800 struct timespec tv
[2];
2804 tv
[0].tv_nsec
= UTIME_OMIT
;
2805 tv
[1].tv_nsec
= UTIME_OMIT
;
2807 if (valid
& FUSE_SET_ATTR_ATIME_NOW
)
2808 tv
[0].tv_nsec
= UTIME_NOW
;
2809 else if (valid
& FUSE_SET_ATTR_ATIME
)
2810 tv
[0] = attr
->st_atim
;
2812 if (valid
& FUSE_SET_ATTR_MTIME_NOW
)
2813 tv
[1].tv_nsec
= UTIME_NOW
;
2814 else if (valid
& FUSE_SET_ATTR_MTIME
)
2815 tv
[1] = attr
->st_mtim
;
2817 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
2821 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) ==
2822 (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) {
2823 struct timespec tv
[2];
2824 tv
[0].tv_sec
= attr
->st_atime
;
2825 tv
[0].tv_nsec
= ST_ATIM_NSEC(attr
);
2826 tv
[1].tv_sec
= attr
->st_mtime
;
2827 tv
[1].tv_nsec
= ST_MTIM_NSEC(attr
);
2828 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
2832 err
= fuse_fs_fgetattr(f
->fs
, path
, &buf
, fi
);
2834 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
2836 fuse_finish_interrupt(f
, req
, &d
);
2837 free_path(f
, ino
, path
);
2840 if (f
->conf
.auto_cache
) {
2841 pthread_mutex_lock(&f
->lock
);
2842 update_stat(get_node(f
, ino
), &buf
);
2843 pthread_mutex_unlock(&f
->lock
);
2845 set_stat(f
, ino
, &buf
);
2846 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
2848 reply_err(req
, err
);
2851 static void fuse_lib_access(fuse_req_t req
, fuse_ino_t ino
, int mask
)
2853 struct fuse
*f
= req_fuse_prepare(req
);
2857 err
= get_path(f
, ino
, &path
);
2859 struct fuse_intr_data d
;
2861 fuse_prepare_interrupt(f
, req
, &d
);
2862 err
= fuse_fs_access(f
->fs
, path
, mask
);
2863 fuse_finish_interrupt(f
, req
, &d
);
2864 free_path(f
, ino
, path
);
2866 reply_err(req
, err
);
2869 static void fuse_lib_readlink(fuse_req_t req
, fuse_ino_t ino
)
2871 struct fuse
*f
= req_fuse_prepare(req
);
2872 char linkname
[PATH_MAX
+ 1];
2876 err
= get_path(f
, ino
, &path
);
2878 struct fuse_intr_data d
;
2879 fuse_prepare_interrupt(f
, req
, &d
);
2880 err
= fuse_fs_readlink(f
->fs
, path
, linkname
, sizeof(linkname
));
2881 fuse_finish_interrupt(f
, req
, &d
);
2882 free_path(f
, ino
, path
);
2885 linkname
[PATH_MAX
] = '\0';
2886 fuse_reply_readlink(req
, linkname
);
2888 reply_err(req
, err
);
2891 static void fuse_lib_mknod(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
2892 mode_t mode
, dev_t rdev
)
2894 struct fuse
*f
= req_fuse_prepare(req
);
2895 struct fuse_entry_param e
;
2899 err
= get_path_name(f
, parent
, name
, &path
);
2901 struct fuse_intr_data d
;
2903 fuse_prepare_interrupt(f
, req
, &d
);
2905 if (S_ISREG(mode
)) {
2906 struct fuse_file_info fi
;
2908 memset(&fi
, 0, sizeof(fi
));
2909 fi
.flags
= O_CREAT
| O_EXCL
| O_WRONLY
;
2910 err
= fuse_fs_create(f
->fs
, path
, mode
, &fi
);
2912 err
= lookup_path(f
, parent
, name
, path
, &e
,
2914 fuse_fs_release(f
->fs
, path
, &fi
);
2917 if (err
== -ENOSYS
) {
2918 err
= fuse_fs_mknod(f
->fs
, path
, mode
, rdev
);
2920 err
= lookup_path(f
, parent
, name
, path
, &e
,
2923 fuse_finish_interrupt(f
, req
, &d
);
2924 free_path(f
, parent
, path
);
2926 reply_entry(req
, &e
, err
);
2929 static void fuse_lib_mkdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
2932 struct fuse
*f
= req_fuse_prepare(req
);
2933 struct fuse_entry_param e
;
2937 err
= get_path_name(f
, parent
, name
, &path
);
2939 struct fuse_intr_data d
;
2941 fuse_prepare_interrupt(f
, req
, &d
);
2942 err
= fuse_fs_mkdir(f
->fs
, path
, mode
);
2944 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
2945 fuse_finish_interrupt(f
, req
, &d
);
2946 free_path(f
, parent
, path
);
2948 reply_entry(req
, &e
, err
);
2951 static void fuse_lib_unlink(fuse_req_t req
, fuse_ino_t parent
,
2954 struct fuse
*f
= req_fuse_prepare(req
);
2959 err
= get_path_wrlock(f
, parent
, name
, &path
, &wnode
);
2961 struct fuse_intr_data d
;
2963 fuse_prepare_interrupt(f
, req
, &d
);
2964 if (!f
->conf
.hard_remove
&& is_open(f
, parent
, name
)) {
2965 err
= hide_node(f
, path
, parent
, name
);
2967 err
= fuse_fs_unlink(f
->fs
, path
);
2969 remove_node(f
, parent
, name
);
2971 fuse_finish_interrupt(f
, req
, &d
);
2972 free_path_wrlock(f
, parent
, wnode
, path
);
2974 reply_err(req
, err
);
2977 static void fuse_lib_rmdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
2979 struct fuse
*f
= req_fuse_prepare(req
);
2984 err
= get_path_wrlock(f
, parent
, name
, &path
, &wnode
);
2986 struct fuse_intr_data d
;
2988 fuse_prepare_interrupt(f
, req
, &d
);
2989 err
= fuse_fs_rmdir(f
->fs
, path
);
2990 fuse_finish_interrupt(f
, req
, &d
);
2992 remove_node(f
, parent
, name
);
2993 free_path_wrlock(f
, parent
, wnode
, path
);
2995 reply_err(req
, err
);
2998 static void fuse_lib_symlink(fuse_req_t req
, const char *linkname
,
2999 fuse_ino_t parent
, const char *name
)
3001 struct fuse
*f
= req_fuse_prepare(req
);
3002 struct fuse_entry_param e
;
3006 err
= get_path_name(f
, parent
, name
, &path
);
3008 struct fuse_intr_data d
;
3010 fuse_prepare_interrupt(f
, req
, &d
);
3011 err
= fuse_fs_symlink(f
->fs
, linkname
, path
);
3013 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
3014 fuse_finish_interrupt(f
, req
, &d
);
3015 free_path(f
, parent
, path
);
3017 reply_entry(req
, &e
, err
);
3020 static void fuse_lib_rename(fuse_req_t req
, fuse_ino_t olddir
,
3021 const char *oldname
, fuse_ino_t newdir
,
3022 const char *newname
)
3024 struct fuse
*f
= req_fuse_prepare(req
);
3027 struct node
*wnode1
;
3028 struct node
*wnode2
;
3031 err
= get_path2(f
, olddir
, oldname
, newdir
, newname
,
3032 &oldpath
, &newpath
, &wnode1
, &wnode2
);
3034 struct fuse_intr_data d
;
3036 fuse_prepare_interrupt(f
, req
, &d
);
3037 if (!f
->conf
.hard_remove
&& is_open(f
, newdir
, newname
))
3038 err
= hide_node(f
, newpath
, newdir
, newname
);
3040 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
3042 err
= rename_node(f
, olddir
, oldname
, newdir
,
3045 fuse_finish_interrupt(f
, req
, &d
);
3046 free_path2(f
, olddir
, newdir
, wnode1
, wnode2
, oldpath
, newpath
);
3048 reply_err(req
, err
);
3051 static void fuse_lib_link(fuse_req_t req
, fuse_ino_t ino
, fuse_ino_t newparent
,
3052 const char *newname
)
3054 struct fuse
*f
= req_fuse_prepare(req
);
3055 struct fuse_entry_param e
;
3060 err
= get_path2(f
, ino
, NULL
, newparent
, newname
,
3061 &oldpath
, &newpath
, NULL
, NULL
);
3063 struct fuse_intr_data d
;
3065 fuse_prepare_interrupt(f
, req
, &d
);
3066 err
= fuse_fs_link(f
->fs
, oldpath
, newpath
);
3068 err
= lookup_path(f
, newparent
, newname
, newpath
,
3070 fuse_finish_interrupt(f
, req
, &d
);
3071 free_path2(f
, ino
, newparent
, NULL
, NULL
, oldpath
, newpath
);
3073 reply_entry(req
, &e
, err
);
3076 static void fuse_do_release(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
3077 struct fuse_file_info
*fi
)
3080 int unlink_hidden
= 0;
3081 const char *compatpath
;
3083 if (path
!= NULL
|| f
->nullpath_ok
|| f
->conf
.nopath
)
3088 fuse_fs_release(f
->fs
, compatpath
, fi
);
3090 pthread_mutex_lock(&f
->lock
);
3091 node
= get_node(f
, ino
);
3092 assert(node
->open_count
> 0);
3094 if (node
->is_hidden
&& !node
->open_count
) {
3096 node
->is_hidden
= 0;
3098 pthread_mutex_unlock(&f
->lock
);
3102 fuse_fs_unlink(f
->fs
, path
);
3103 } else if (f
->conf
.nopath
) {
3106 if (get_path(f
, ino
, &unlinkpath
) == 0)
3107 fuse_fs_unlink(f
->fs
, unlinkpath
);
3109 free_path(f
, ino
, unlinkpath
);
3114 static void fuse_lib_create(fuse_req_t req
, fuse_ino_t parent
,
3115 const char *name
, mode_t mode
,
3116 struct fuse_file_info
*fi
)
3118 struct fuse
*f
= req_fuse_prepare(req
);
3119 struct fuse_intr_data d
;
3120 struct fuse_entry_param e
;
3124 err
= get_path_name(f
, parent
, name
, &path
);
3126 fuse_prepare_interrupt(f
, req
, &d
);
3127 err
= fuse_fs_create(f
->fs
, path
, mode
, fi
);
3129 err
= lookup_path(f
, parent
, name
, path
, &e
, fi
);
3131 fuse_fs_release(f
->fs
, path
, fi
);
3132 else if (!S_ISREG(e
.attr
.st_mode
)) {
3134 fuse_fs_release(f
->fs
, path
, fi
);
3135 forget_node(f
, e
.ino
, 1);
3137 if (f
->conf
.direct_io
)
3139 if (f
->conf
.kernel_cache
)
3144 fuse_finish_interrupt(f
, req
, &d
);
3147 pthread_mutex_lock(&f
->lock
);
3148 get_node(f
, e
.ino
)->open_count
++;
3149 pthread_mutex_unlock(&f
->lock
);
3150 if (fuse_reply_create(req
, &e
, fi
) == -ENOENT
) {
3151 /* The open syscall was interrupted, so it
3152 must be cancelled */
3153 fuse_do_release(f
, e
.ino
, path
, fi
);
3154 forget_node(f
, e
.ino
, 1);
3157 reply_err(req
, err
);
3160 free_path(f
, parent
, path
);
3163 static double diff_timespec(const struct timespec
*t1
,
3164 const struct timespec
*t2
)
3166 return (t1
->tv_sec
- t2
->tv_sec
) +
3167 ((double) t1
->tv_nsec
- (double) t2
->tv_nsec
) / 1000000000.0;
3170 static void open_auto_cache(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
3171 struct fuse_file_info
*fi
)
3175 pthread_mutex_lock(&f
->lock
);
3176 node
= get_node(f
, ino
);
3177 if (node
->cache_valid
) {
3178 struct timespec now
;
3181 if (diff_timespec(&now
, &node
->stat_updated
) >
3182 f
->conf
.ac_attr_timeout
) {
3185 pthread_mutex_unlock(&f
->lock
);
3186 err
= fuse_fs_fgetattr(f
->fs
, path
, &stbuf
, fi
);
3187 pthread_mutex_lock(&f
->lock
);
3189 update_stat(node
, &stbuf
);
3191 node
->cache_valid
= 0;
3194 if (node
->cache_valid
)
3197 node
->cache_valid
= 1;
3198 pthread_mutex_unlock(&f
->lock
);
3201 static void fuse_lib_open(fuse_req_t req
, fuse_ino_t ino
,
3202 struct fuse_file_info
*fi
)
3204 struct fuse
*f
= req_fuse_prepare(req
);
3205 struct fuse_intr_data d
;
3209 err
= get_path(f
, ino
, &path
);
3211 fuse_prepare_interrupt(f
, req
, &d
);
3212 err
= fuse_fs_open(f
->fs
, path
, fi
);
3214 if (f
->conf
.direct_io
)
3216 if (f
->conf
.kernel_cache
)
3219 if (f
->conf
.auto_cache
)
3220 open_auto_cache(f
, ino
, path
, fi
);
3222 fuse_finish_interrupt(f
, req
, &d
);
3225 pthread_mutex_lock(&f
->lock
);
3226 get_node(f
, ino
)->open_count
++;
3227 pthread_mutex_unlock(&f
->lock
);
3228 if (fuse_reply_open(req
, fi
) == -ENOENT
) {
3229 /* The open syscall was interrupted, so it
3230 must be cancelled */
3231 fuse_do_release(f
, ino
, path
, fi
);
3234 reply_err(req
, err
);
3236 free_path(f
, ino
, path
);
3239 static void fuse_lib_read(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
3240 off_t off
, struct fuse_file_info
*fi
)
3242 struct fuse
*f
= req_fuse_prepare(req
);
3243 struct fuse_bufvec
*buf
= NULL
;
3247 res
= get_path_nullok(f
, ino
, &path
);
3249 struct fuse_intr_data d
;
3251 fuse_prepare_interrupt(f
, req
, &d
);
3252 res
= fuse_fs_read_buf(f
->fs
, path
, &buf
, size
, off
, fi
);
3253 fuse_finish_interrupt(f
, req
, &d
);
3254 free_path(f
, ino
, path
);
3258 fuse_reply_data(req
, buf
, FUSE_BUF_SPLICE_MOVE
);
3260 reply_err(req
, res
);
3265 static void fuse_lib_write_buf(fuse_req_t req
, fuse_ino_t ino
,
3266 struct fuse_bufvec
*buf
, off_t off
,
3267 struct fuse_file_info
*fi
)
3269 struct fuse
*f
= req_fuse_prepare(req
);
3273 res
= get_path_nullok(f
, ino
, &path
);
3275 struct fuse_intr_data d
;
3277 fuse_prepare_interrupt(f
, req
, &d
);
3278 res
= fuse_fs_write_buf(f
->fs
, path
, buf
, off
, fi
);
3279 fuse_finish_interrupt(f
, req
, &d
);
3280 free_path(f
, ino
, path
);
3284 fuse_reply_write(req
, res
);
3286 reply_err(req
, res
);
3289 static void fuse_lib_fsync(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
3290 struct fuse_file_info
*fi
)
3292 struct fuse
*f
= req_fuse_prepare(req
);
3296 err
= get_path_nullok(f
, ino
, &path
);
3298 struct fuse_intr_data d
;
3300 fuse_prepare_interrupt(f
, req
, &d
);
3301 err
= fuse_fs_fsync(f
->fs
, path
, datasync
, fi
);
3302 fuse_finish_interrupt(f
, req
, &d
);
3303 free_path(f
, ino
, path
);
3305 reply_err(req
, err
);
3308 static struct fuse_dh
*get_dirhandle(const struct fuse_file_info
*llfi
,
3309 struct fuse_file_info
*fi
)
3311 struct fuse_dh
*dh
= (struct fuse_dh
*) (uintptr_t) llfi
->fh
;
3312 memset(fi
, 0, sizeof(struct fuse_file_info
));
3314 fi
->fh_old
= dh
->fh
;
3318 static void fuse_lib_opendir(fuse_req_t req
, fuse_ino_t ino
,
3319 struct fuse_file_info
*llfi
)
3321 struct fuse
*f
= req_fuse_prepare(req
);
3322 struct fuse_intr_data d
;
3324 struct fuse_file_info fi
;
3328 dh
= (struct fuse_dh
*) malloc(sizeof(struct fuse_dh
));
3330 reply_err(req
, -ENOMEM
);
3333 memset(dh
, 0, sizeof(struct fuse_dh
));
3335 dh
->contents
= NULL
;
3339 fuse_mutex_init(&dh
->lock
);
3341 llfi
->fh
= (uintptr_t) dh
;
3343 memset(&fi
, 0, sizeof(fi
));
3344 fi
.flags
= llfi
->flags
;
3346 err
= get_path(f
, ino
, &path
);
3348 fuse_prepare_interrupt(f
, req
, &d
);
3349 err
= fuse_fs_opendir(f
->fs
, path
, &fi
);
3350 fuse_finish_interrupt(f
, req
, &d
);
3354 if (fuse_reply_open(req
, llfi
) == -ENOENT
) {
3355 /* The opendir syscall was interrupted, so it
3356 must be cancelled */
3357 fuse_fs_releasedir(f
->fs
, path
, &fi
);
3358 pthread_mutex_destroy(&dh
->lock
);
3362 reply_err(req
, err
);
3363 pthread_mutex_destroy(&dh
->lock
);
3366 free_path(f
, ino
, path
);
3369 static int extend_contents(struct fuse_dh
*dh
, unsigned minsize
)
3371 if (minsize
> dh
->size
) {
3373 unsigned newsize
= dh
->size
;
3376 while (newsize
< minsize
) {
3377 if (newsize
>= 0x80000000)
3378 newsize
= 0xffffffff;
3383 newptr
= (char *) realloc(dh
->contents
, newsize
);
3385 dh
->error
= -ENOMEM
;
3388 dh
->contents
= newptr
;
3394 static int fill_dir(void *dh_
, const char *name
, const struct stat
*statp
,
3397 struct fuse_dh
*dh
= (struct fuse_dh
*) dh_
;
3404 memset(&stbuf
, 0, sizeof(stbuf
));
3405 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
3408 if (!dh
->fuse
->conf
.use_ino
) {
3409 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
3410 if (dh
->fuse
->conf
.readdir_ino
) {
3412 pthread_mutex_lock(&dh
->fuse
->lock
);
3413 node
= lookup_node(dh
->fuse
, dh
->nodeid
, name
);
3415 stbuf
.st_ino
= (ino_t
) node
->nodeid
;
3416 pthread_mutex_unlock(&dh
->fuse
->lock
);
3421 if (extend_contents(dh
, dh
->needlen
) == -1)
3426 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
3427 dh
->needlen
- dh
->len
, name
,
3429 if (newlen
> dh
->needlen
)
3433 fuse_add_direntry(dh
->req
, NULL
, 0, name
, NULL
, 0);
3434 if (extend_contents(dh
, newlen
) == -1)
3437 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
3438 dh
->size
- dh
->len
, name
, &stbuf
, newlen
);
3444 static int readdir_fill(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3445 size_t size
, off_t off
, struct fuse_dh
*dh
,
3446 struct fuse_file_info
*fi
)
3451 if (f
->fs
->op
.readdir
)
3452 err
= get_path_nullok(f
, ino
, &path
);
3454 err
= get_path(f
, ino
, &path
);
3456 struct fuse_intr_data d
;
3463 fuse_prepare_interrupt(f
, req
, &d
);
3464 err
= fuse_fs_readdir(f
->fs
, path
, dh
, fill_dir
, off
, fi
);
3465 fuse_finish_interrupt(f
, req
, &d
);
3471 free_path(f
, ino
, path
);
3476 static void fuse_lib_readdir(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
3477 off_t off
, struct fuse_file_info
*llfi
)
3479 struct fuse
*f
= req_fuse_prepare(req
);
3480 struct fuse_file_info fi
;
3481 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
3483 pthread_mutex_lock(&dh
->lock
);
3484 /* According to SUS, directory contents need to be refreshed on
3490 int err
= readdir_fill(f
, req
, ino
, size
, off
, dh
, &fi
);
3492 reply_err(req
, err
);
3497 if (off
< dh
->len
) {
3498 if (off
+ size
> dh
->len
)
3499 size
= dh
->len
- off
;
3506 fuse_reply_buf(req
, dh
->contents
+ off
, size
);
3508 pthread_mutex_unlock(&dh
->lock
);
3511 static void fuse_lib_releasedir(fuse_req_t req
, fuse_ino_t ino
,
3512 struct fuse_file_info
*llfi
)
3514 struct fuse
*f
= req_fuse_prepare(req
);
3515 struct fuse_intr_data d
;
3516 struct fuse_file_info fi
;
3517 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
3519 const char *compatpath
;
3521 get_path_nullok(f
, ino
, &path
);
3522 if (path
!= NULL
|| f
->nullpath_ok
|| f
->conf
.nopath
)
3527 fuse_prepare_interrupt(f
, req
, &d
);
3528 fuse_fs_releasedir(f
->fs
, compatpath
, &fi
);
3529 fuse_finish_interrupt(f
, req
, &d
);
3530 free_path(f
, ino
, path
);
3532 pthread_mutex_lock(&dh
->lock
);
3533 pthread_mutex_unlock(&dh
->lock
);
3534 pthread_mutex_destroy(&dh
->lock
);
3540 static void fuse_lib_fsyncdir(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
3541 struct fuse_file_info
*llfi
)
3543 struct fuse
*f
= req_fuse_prepare(req
);
3544 struct fuse_file_info fi
;
3548 get_dirhandle(llfi
, &fi
);
3550 err
= get_path_nullok(f
, ino
, &path
);
3552 struct fuse_intr_data d
;
3553 fuse_prepare_interrupt(f
, req
, &d
);
3554 err
= fuse_fs_fsyncdir(f
->fs
, path
, datasync
, &fi
);
3555 fuse_finish_interrupt(f
, req
, &d
);
3556 free_path(f
, ino
, path
);
3558 reply_err(req
, err
);
3561 static void fuse_lib_statfs(fuse_req_t req
, fuse_ino_t ino
)
3563 struct fuse
*f
= req_fuse_prepare(req
);
3568 memset(&buf
, 0, sizeof(buf
));
3570 err
= get_path(f
, ino
, &path
);
3573 struct fuse_intr_data d
;
3574 fuse_prepare_interrupt(f
, req
, &d
);
3575 err
= fuse_fs_statfs(f
->fs
, path
? path
: "/", &buf
);
3576 fuse_finish_interrupt(f
, req
, &d
);
3577 free_path(f
, ino
, path
);
3581 fuse_reply_statfs(req
, &buf
);
3583 reply_err(req
, err
);
3586 static void fuse_lib_setxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
3587 const char *value
, size_t size
, int flags
)
3589 struct fuse
*f
= req_fuse_prepare(req
);
3593 err
= get_path(f
, ino
, &path
);
3595 struct fuse_intr_data d
;
3596 fuse_prepare_interrupt(f
, req
, &d
);
3597 err
= fuse_fs_setxattr(f
->fs
, path
, name
, value
, size
, flags
);
3598 fuse_finish_interrupt(f
, req
, &d
);
3599 free_path(f
, ino
, path
);
3601 reply_err(req
, err
);
3604 static int common_getxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3605 const char *name
, char *value
, size_t size
)
3610 err
= get_path(f
, ino
, &path
);
3612 struct fuse_intr_data d
;
3613 fuse_prepare_interrupt(f
, req
, &d
);
3614 err
= fuse_fs_getxattr(f
->fs
, path
, name
, value
, size
);
3615 fuse_finish_interrupt(f
, req
, &d
);
3616 free_path(f
, ino
, path
);
3621 static void fuse_lib_getxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
3624 struct fuse
*f
= req_fuse_prepare(req
);
3628 char *value
= (char *) malloc(size
);
3629 if (value
== NULL
) {
3630 reply_err(req
, -ENOMEM
);
3633 res
= common_getxattr(f
, req
, ino
, name
, value
, size
);
3635 fuse_reply_buf(req
, value
, res
);
3637 reply_err(req
, res
);
3640 res
= common_getxattr(f
, req
, ino
, name
, NULL
, 0);
3642 fuse_reply_xattr(req
, res
);
3644 reply_err(req
, res
);
3648 static int common_listxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3649 char *list
, size_t size
)
3654 err
= get_path(f
, ino
, &path
);
3656 struct fuse_intr_data d
;
3657 fuse_prepare_interrupt(f
, req
, &d
);
3658 err
= fuse_fs_listxattr(f
->fs
, path
, list
, size
);
3659 fuse_finish_interrupt(f
, req
, &d
);
3660 free_path(f
, ino
, path
);
3665 static void fuse_lib_listxattr(fuse_req_t req
, fuse_ino_t ino
, size_t size
)
3667 struct fuse
*f
= req_fuse_prepare(req
);
3671 char *list
= (char *) malloc(size
);
3673 reply_err(req
, -ENOMEM
);
3676 res
= common_listxattr(f
, req
, ino
, list
, size
);
3678 fuse_reply_buf(req
, list
, res
);
3680 reply_err(req
, res
);
3683 res
= common_listxattr(f
, req
, ino
, NULL
, 0);
3685 fuse_reply_xattr(req
, res
);
3687 reply_err(req
, res
);
3691 static void fuse_lib_removexattr(fuse_req_t req
, fuse_ino_t ino
,
3694 struct fuse
*f
= req_fuse_prepare(req
);
3698 err
= get_path(f
, ino
, &path
);
3700 struct fuse_intr_data d
;
3701 fuse_prepare_interrupt(f
, req
, &d
);
3702 err
= fuse_fs_removexattr(f
->fs
, path
, name
);
3703 fuse_finish_interrupt(f
, req
, &d
);
3704 free_path(f
, ino
, path
);
3706 reply_err(req
, err
);
3709 static struct lock
*locks_conflict(struct node
*node
, const struct lock
*lock
)
3713 for (l
= node
->locks
; l
; l
= l
->next
)
3714 if (l
->owner
!= lock
->owner
&&
3715 lock
->start
<= l
->end
&& l
->start
<= lock
->end
&&
3716 (l
->type
== F_WRLCK
|| lock
->type
== F_WRLCK
))
3722 static void delete_lock(struct lock
**lockp
)
3724 struct lock
*l
= *lockp
;
3729 static void insert_lock(struct lock
**pos
, struct lock
*lock
)
3735 static int locks_insert(struct node
*node
, struct lock
*lock
)
3738 struct lock
*newl1
= NULL
;
3739 struct lock
*newl2
= NULL
;
3741 if (lock
->type
!= F_UNLCK
|| lock
->start
!= 0 ||
3742 lock
->end
!= OFFSET_MAX
) {
3743 newl1
= malloc(sizeof(struct lock
));
3744 newl2
= malloc(sizeof(struct lock
));
3746 if (!newl1
|| !newl2
) {
3753 for (lp
= &node
->locks
; *lp
;) {
3754 struct lock
*l
= *lp
;
3755 if (l
->owner
!= lock
->owner
)
3758 if (lock
->type
== l
->type
) {
3759 if (l
->end
< lock
->start
- 1)
3761 if (lock
->end
< l
->start
- 1)
3763 if (l
->start
<= lock
->start
&& lock
->end
<= l
->end
)
3765 if (l
->start
< lock
->start
)
3766 lock
->start
= l
->start
;
3767 if (lock
->end
< l
->end
)
3771 if (l
->end
< lock
->start
)
3773 if (lock
->end
< l
->start
)
3775 if (lock
->start
<= l
->start
&& l
->end
<= lock
->end
)
3777 if (l
->end
<= lock
->end
) {
3778 l
->end
= lock
->start
- 1;
3781 if (lock
->start
<= l
->start
) {
3782 l
->start
= lock
->end
+ 1;
3786 newl2
->start
= lock
->end
+ 1;
3787 l
->end
= lock
->start
- 1;
3788 insert_lock(&l
->next
, newl2
);
3798 if (lock
->type
!= F_UNLCK
) {
3800 insert_lock(lp
, newl1
);
3809 static void flock_to_lock(struct flock
*flock
, struct lock
*lock
)
3811 memset(lock
, 0, sizeof(struct lock
));
3812 lock
->type
= flock
->l_type
;
3813 lock
->start
= flock
->l_start
;
3815 flock
->l_len
? flock
->l_start
+ flock
->l_len
- 1 : OFFSET_MAX
;
3816 lock
->pid
= flock
->l_pid
;
3819 static void lock_to_flock(struct lock
*lock
, struct flock
*flock
)
3821 flock
->l_type
= lock
->type
;
3822 flock
->l_start
= lock
->start
;
3824 (lock
->end
== OFFSET_MAX
) ? 0 : lock
->end
- lock
->start
+ 1;
3825 flock
->l_pid
= lock
->pid
;
3828 static int fuse_flush_common(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
3829 const char *path
, struct fuse_file_info
*fi
)
3831 struct fuse_intr_data d
;
3837 fuse_prepare_interrupt(f
, req
, &d
);
3838 memset(&lock
, 0, sizeof(lock
));
3839 lock
.l_type
= F_UNLCK
;
3840 lock
.l_whence
= SEEK_SET
;
3841 err
= fuse_fs_flush(f
->fs
, path
, fi
);
3842 errlock
= fuse_fs_lock(f
->fs
, path
, fi
, F_SETLK
, &lock
);
3843 fuse_finish_interrupt(f
, req
, &d
);
3845 if (errlock
!= -ENOSYS
) {
3846 flock_to_lock(&lock
, &l
);
3847 l
.owner
= fi
->lock_owner
;
3848 pthread_mutex_lock(&f
->lock
);
3849 locks_insert(get_node(f
, ino
), &l
);
3850 pthread_mutex_unlock(&f
->lock
);
3852 /* if op.lock() is defined FLUSH is needed regardless
3860 static void fuse_lib_release(fuse_req_t req
, fuse_ino_t ino
,
3861 struct fuse_file_info
*fi
)
3863 struct fuse
*f
= req_fuse_prepare(req
);
3864 struct fuse_intr_data d
;
3868 get_path_nullok(f
, ino
, &path
);
3870 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
3875 fuse_prepare_interrupt(f
, req
, &d
);
3876 fuse_do_release(f
, ino
, path
, fi
);
3877 fuse_finish_interrupt(f
, req
, &d
);
3878 free_path(f
, ino
, path
);
3880 reply_err(req
, err
);
3883 static void fuse_lib_flush(fuse_req_t req
, fuse_ino_t ino
,
3884 struct fuse_file_info
*fi
)
3886 struct fuse
*f
= req_fuse_prepare(req
);
3890 get_path_nullok(f
, ino
, &path
);
3891 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
3892 free_path(f
, ino
, path
);
3894 reply_err(req
, err
);
3897 static int fuse_lock_common(fuse_req_t req
, fuse_ino_t ino
,
3898 struct fuse_file_info
*fi
, struct flock
*lock
,
3901 struct fuse
*f
= req_fuse_prepare(req
);
3905 err
= get_path_nullok(f
, ino
, &path
);
3907 struct fuse_intr_data d
;
3908 fuse_prepare_interrupt(f
, req
, &d
);
3909 err
= fuse_fs_lock(f
->fs
, path
, fi
, cmd
, lock
);
3910 fuse_finish_interrupt(f
, req
, &d
);
3911 free_path(f
, ino
, path
);
3916 static void fuse_lib_getlk(fuse_req_t req
, fuse_ino_t ino
,
3917 struct fuse_file_info
*fi
, struct flock
*lock
)
3921 struct lock
*conflict
;
3922 struct fuse
*f
= req_fuse(req
);
3924 flock_to_lock(lock
, &l
);
3925 l
.owner
= fi
->lock_owner
;
3926 pthread_mutex_lock(&f
->lock
);
3927 conflict
= locks_conflict(get_node(f
, ino
), &l
);
3929 lock_to_flock(conflict
, lock
);
3930 pthread_mutex_unlock(&f
->lock
);
3932 err
= fuse_lock_common(req
, ino
, fi
, lock
, F_GETLK
);
3937 fuse_reply_lock(req
, lock
);
3939 reply_err(req
, err
);
3942 static void fuse_lib_setlk(fuse_req_t req
, fuse_ino_t ino
,
3943 struct fuse_file_info
*fi
, struct flock
*lock
,
3946 int err
= fuse_lock_common(req
, ino
, fi
, lock
,
3947 sleep
? F_SETLKW
: F_SETLK
);
3949 struct fuse
*f
= req_fuse(req
);
3951 flock_to_lock(lock
, &l
);
3952 l
.owner
= fi
->lock_owner
;
3953 pthread_mutex_lock(&f
->lock
);
3954 locks_insert(get_node(f
, ino
), &l
);
3955 pthread_mutex_unlock(&f
->lock
);
3957 reply_err(req
, err
);
3960 static void fuse_lib_flock(fuse_req_t req
, fuse_ino_t ino
,
3961 struct fuse_file_info
*fi
, int op
)
3963 struct fuse
*f
= req_fuse_prepare(req
);
3967 err
= get_path_nullok(f
, ino
, &path
);
3969 struct fuse_intr_data d
;
3970 fuse_prepare_interrupt(f
, req
, &d
);
3971 err
= fuse_fs_flock(f
->fs
, path
, fi
, op
);
3972 fuse_finish_interrupt(f
, req
, &d
);
3973 free_path(f
, ino
, path
);
3975 reply_err(req
, err
);
3978 static void fuse_lib_bmap(fuse_req_t req
, fuse_ino_t ino
, size_t blocksize
,
3981 struct fuse
*f
= req_fuse_prepare(req
);
3982 struct fuse_intr_data d
;
3986 err
= get_path(f
, ino
, &path
);
3988 fuse_prepare_interrupt(f
, req
, &d
);
3989 err
= fuse_fs_bmap(f
->fs
, path
, blocksize
, &idx
);
3990 fuse_finish_interrupt(f
, req
, &d
);
3991 free_path(f
, ino
, path
);
3994 fuse_reply_bmap(req
, idx
);
3996 reply_err(req
, err
);
3999 static void fuse_lib_ioctl(fuse_req_t req
, fuse_ino_t ino
, int cmd
, void *arg
,
4000 struct fuse_file_info
*fi
, unsigned int flags
,
4001 const void *in_buf
, size_t in_bufsz
,
4004 struct fuse
*f
= req_fuse_prepare(req
);
4005 struct fuse_intr_data d
;
4006 char *path
, *out_buf
= NULL
;
4010 if (flags
& FUSE_IOCTL_UNRESTRICTED
)
4015 out_buf
= malloc(out_bufsz
);
4020 assert(!in_bufsz
|| !out_bufsz
|| in_bufsz
== out_bufsz
);
4022 memcpy(out_buf
, in_buf
, in_bufsz
);
4024 err
= get_path_nullok(f
, ino
, &path
);
4028 fuse_prepare_interrupt(f
, req
, &d
);
4030 err
= fuse_fs_ioctl(f
->fs
, path
, cmd
, arg
, fi
, flags
,
4031 out_buf
?: (void *)in_buf
);
4033 fuse_finish_interrupt(f
, req
, &d
);
4034 free_path(f
, ino
, path
);
4036 fuse_reply_ioctl(req
, err
, out_buf
, out_bufsz
);
4039 reply_err(req
, err
);
4044 static void fuse_lib_poll(fuse_req_t req
, fuse_ino_t ino
,
4045 struct fuse_file_info
*fi
, struct fuse_pollhandle
*ph
)
4047 struct fuse
*f
= req_fuse_prepare(req
);
4048 struct fuse_intr_data d
;
4051 unsigned revents
= 0;
4053 err
= get_path_nullok(f
, ino
, &path
);
4055 fuse_prepare_interrupt(f
, req
, &d
);
4056 err
= fuse_fs_poll(f
->fs
, path
, fi
, ph
, &revents
);
4057 fuse_finish_interrupt(f
, req
, &d
);
4058 free_path(f
, ino
, path
);
4061 fuse_reply_poll(req
, revents
);
4063 reply_err(req
, err
);
4066 static void fuse_lib_fallocate(fuse_req_t req
, fuse_ino_t ino
, int mode
,
4067 off_t offset
, off_t length
, struct fuse_file_info
*fi
)
4069 struct fuse
*f
= req_fuse_prepare(req
);
4070 struct fuse_intr_data d
;
4074 err
= get_path_nullok(f
, ino
, &path
);
4076 fuse_prepare_interrupt(f
, req
, &d
);
4077 err
= fuse_fs_fallocate(f
->fs
, path
, mode
, offset
, length
, fi
);
4078 fuse_finish_interrupt(f
, req
, &d
);
4079 free_path(f
, ino
, path
);
4081 reply_err(req
, err
);
4084 static int clean_delay(struct fuse
*f
)
4087 * This is calculating the delay between clean runs. To
4088 * reduce the number of cleans we are doing them 10 times
4089 * within the remember window.
4092 int max_sleep
= 3600;
4093 int sleep_time
= f
->conf
.remember
/ 10;
4095 if (sleep_time
> max_sleep
)
4097 if (sleep_time
< min_sleep
)
4102 int fuse_clean_cache(struct fuse
*f
)
4104 struct node_lru
*lnode
;
4105 struct list_head
*curr
, *next
;
4107 struct timespec now
;
4109 pthread_mutex_lock(&f
->lock
);
4113 for (curr
= f
->lru_table
.next
; curr
!= &f
->lru_table
; curr
= next
) {
4117 lnode
= list_entry(curr
, struct node_lru
, lru
);
4118 node
= &lnode
->node
;
4120 age
= diff_timespec(&now
, &lnode
->forget_time
);
4121 if (age
<= f
->conf
.remember
)
4124 assert(node
->nlookup
== 1);
4126 /* Don't forget active directories */
4127 if (node
->refctr
> 1)
4131 unhash_name(f
, node
);
4132 unref_node(f
, node
);
4134 pthread_mutex_unlock(&f
->lock
);
4136 return clean_delay(f
);
4139 static struct fuse_lowlevel_ops fuse_path_ops
= {
4140 .init
= fuse_lib_init
,
4141 .destroy
= fuse_lib_destroy
,
4142 .lookup
= fuse_lib_lookup
,
4143 .forget
= fuse_lib_forget
,
4144 .forget_multi
= fuse_lib_forget_multi
,
4145 .getattr
= fuse_lib_getattr
,
4146 .setattr
= fuse_lib_setattr
,
4147 .access
= fuse_lib_access
,
4148 .readlink
= fuse_lib_readlink
,
4149 .mknod
= fuse_lib_mknod
,
4150 .mkdir
= fuse_lib_mkdir
,
4151 .unlink
= fuse_lib_unlink
,
4152 .rmdir
= fuse_lib_rmdir
,
4153 .symlink
= fuse_lib_symlink
,
4154 .rename
= fuse_lib_rename
,
4155 .link
= fuse_lib_link
,
4156 .create
= fuse_lib_create
,
4157 .open
= fuse_lib_open
,
4158 .read
= fuse_lib_read
,
4159 .write_buf
= fuse_lib_write_buf
,
4160 .flush
= fuse_lib_flush
,
4161 .release
= fuse_lib_release
,
4162 .fsync
= fuse_lib_fsync
,
4163 .opendir
= fuse_lib_opendir
,
4164 .readdir
= fuse_lib_readdir
,
4165 .releasedir
= fuse_lib_releasedir
,
4166 .fsyncdir
= fuse_lib_fsyncdir
,
4167 .statfs
= fuse_lib_statfs
,
4168 .setxattr
= fuse_lib_setxattr
,
4169 .getxattr
= fuse_lib_getxattr
,
4170 .listxattr
= fuse_lib_listxattr
,
4171 .removexattr
= fuse_lib_removexattr
,
4172 .getlk
= fuse_lib_getlk
,
4173 .setlk
= fuse_lib_setlk
,
4174 .flock
= fuse_lib_flock
,
4175 .bmap
= fuse_lib_bmap
,
4176 .ioctl
= fuse_lib_ioctl
,
4177 .poll
= fuse_lib_poll
,
4178 .fallocate
= fuse_lib_fallocate
,
4181 int fuse_notify_poll(struct fuse_pollhandle
*ph
)
4183 return fuse_lowlevel_notify_poll(ph
);
4186 static void free_cmd(struct fuse_cmd
*cmd
)
4192 void fuse_process_cmd(struct fuse
*f
, struct fuse_cmd
*cmd
)
4194 fuse_session_process(f
->se
, cmd
->buf
, cmd
->buflen
, cmd
->ch
);
4198 int fuse_exited(struct fuse
*f
)
4200 return fuse_session_exited(f
->se
);
4203 struct fuse_session
*fuse_get_session(struct fuse
*f
)
4208 static struct fuse_cmd
*fuse_alloc_cmd(size_t bufsize
)
4210 struct fuse_cmd
*cmd
= (struct fuse_cmd
*) malloc(sizeof(*cmd
));
4212 fprintf(stderr
, "fuse: failed to allocate cmd\n");
4215 cmd
->buf
= (char *) malloc(bufsize
);
4216 if (cmd
->buf
== NULL
) {
4217 fprintf(stderr
, "fuse: failed to allocate read buffer\n");
4224 struct fuse_cmd
*fuse_read_cmd(struct fuse
*f
)
4226 struct fuse_chan
*ch
= fuse_session_next_chan(f
->se
, NULL
);
4227 size_t bufsize
= fuse_chan_bufsize(ch
);
4228 struct fuse_cmd
*cmd
= fuse_alloc_cmd(bufsize
);
4230 int res
= fuse_chan_recv(&ch
, cmd
->buf
, bufsize
);
4233 if (res
< 0 && res
!= -EINTR
&& res
!= -EAGAIN
)
4243 static int fuse_session_loop_remember(struct fuse
*f
)
4245 struct fuse_session
*se
= f
->se
;
4247 struct timespec now
;
4249 struct fuse_chan
*ch
= fuse_session_next_chan(se
, NULL
);
4250 size_t bufsize
= fuse_chan_bufsize(ch
);
4251 char *buf
= (char *) malloc(bufsize
);
4252 struct pollfd fds
= {
4253 .fd
= fuse_chan_fd(ch
),
4258 fprintf(stderr
, "fuse: failed to allocate read buffer\n");
4263 next_clean
= now
.tv_sec
;
4264 while (!fuse_session_exited(se
)) {
4265 struct fuse_chan
*tmpch
= ch
;
4266 struct fuse_buf fbuf
= {
4273 if (now
.tv_sec
< next_clean
)
4274 timeout
= next_clean
- now
.tv_sec
;
4278 res
= poll(&fds
, 1, timeout
* 1000);
4280 if (errno
== -EINTR
)
4284 } else if (res
> 0) {
4285 res
= fuse_session_receive_buf(se
, &fbuf
, &tmpch
);
4292 fuse_session_process_buf(se
, &fbuf
, tmpch
);
4294 timeout
= fuse_clean_cache(f
);
4296 next_clean
= now
.tv_sec
+ timeout
;
4301 fuse_session_reset(se
);
4302 return res
< 0 ? -1 : 0;
4305 int fuse_loop(struct fuse
*f
)
4311 return fuse_session_loop_remember(f
);
4313 return fuse_session_loop(f
->se
);
4316 int fuse_invalidate(struct fuse
*f
, const char *path
)
4323 void fuse_exit(struct fuse
*f
)
4325 fuse_session_exit(f
->se
);
4328 struct fuse_context
*fuse_get_context(void)
4330 return &fuse_get_context_internal()->ctx
;
4334 * The size of fuse_context got extended, so need to be careful about
4335 * incompatibility (i.e. a new binary cannot work with an old
4338 struct fuse_context
*fuse_get_context_compat22(void);
4339 struct fuse_context
*fuse_get_context_compat22(void)
4341 return &fuse_get_context_internal()->ctx
;
4343 FUSE_SYMVER(".symver fuse_get_context_compat22,fuse_get_context@FUSE_2.2");
4345 int fuse_getgroups(int size
, gid_t list
[])
4347 fuse_req_t req
= fuse_get_context_internal()->req
;
4348 return fuse_req_getgroups(req
, size
, list
);
4351 int fuse_interrupted(void)
4353 return fuse_req_interrupted(fuse_get_context_internal()->req
);
4356 void fuse_set_getcontext_func(struct fuse_context
*(*func
)(void))
4366 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4368 static const struct fuse_opt fuse_lib_opts
[] = {
4369 FUSE_OPT_KEY("-h", KEY_HELP
),
4370 FUSE_OPT_KEY("--help", KEY_HELP
),
4371 FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP
),
4372 FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP
),
4373 FUSE_LIB_OPT("debug", debug
, 1),
4374 FUSE_LIB_OPT("-d", debug
, 1),
4375 FUSE_LIB_OPT("hard_remove", hard_remove
, 1),
4376 FUSE_LIB_OPT("use_ino", use_ino
, 1),
4377 FUSE_LIB_OPT("readdir_ino", readdir_ino
, 1),
4378 FUSE_LIB_OPT("direct_io", direct_io
, 1),
4379 FUSE_LIB_OPT("kernel_cache", kernel_cache
, 1),
4380 FUSE_LIB_OPT("auto_cache", auto_cache
, 1),
4381 FUSE_LIB_OPT("noauto_cache", auto_cache
, 0),
4382 FUSE_LIB_OPT("umask=", set_mode
, 1),
4383 FUSE_LIB_OPT("umask=%o", umask
, 0),
4384 FUSE_LIB_OPT("uid=", set_uid
, 1),
4385 FUSE_LIB_OPT("uid=%d", uid
, 0),
4386 FUSE_LIB_OPT("gid=", set_gid
, 1),
4387 FUSE_LIB_OPT("gid=%d", gid
, 0),
4388 FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout
, 0),
4389 FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout
, 0),
4390 FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout
, 0),
4391 FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set
, 1),
4392 FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout
, 0),
4393 FUSE_LIB_OPT("noforget", remember
, -1),
4394 FUSE_LIB_OPT("remember=%u", remember
, 0),
4395 FUSE_LIB_OPT("nopath", nopath
, 1),
4396 FUSE_LIB_OPT("intr", intr
, 1),
4397 FUSE_LIB_OPT("intr_signal=%d", intr_signal
, 0),
4398 FUSE_LIB_OPT("modules=%s", modules
, 0),
4402 static void fuse_lib_help(void)
4405 " -o hard_remove immediate removal (don't hide files)\n"
4406 " -o use_ino let filesystem set inode numbers\n"
4407 " -o readdir_ino try to fill in d_ino in readdir\n"
4408 " -o direct_io use direct I/O\n"
4409 " -o kernel_cache cache files in kernel\n"
4410 " -o [no]auto_cache enable caching based on modification times (off)\n"
4411 " -o umask=M set file permissions (octal)\n"
4412 " -o uid=N set file owner\n"
4413 " -o gid=N set file group\n"
4414 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4415 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4416 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4417 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4418 " -o noforget never forget cached inodes\n"
4419 " -o remember=T remember cached inodes for T seconds (0s)\n"
4420 " -o nopath don't supply path if not necessary\n"
4421 " -o intr allow requests to be interrupted\n"
4422 " -o intr_signal=NUM signal to send on interrupt (%i)\n"
4423 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
4424 "\n", FUSE_DEFAULT_INTR_SIGNAL
);
4427 static void fuse_lib_help_modules(void)
4429 struct fuse_module
*m
;
4430 fprintf(stderr
, "\nModule options:\n");
4431 pthread_mutex_lock(&fuse_context_lock
);
4432 for (m
= fuse_modules
; m
; m
= m
->next
) {
4433 struct fuse_fs
*fs
= NULL
;
4434 struct fuse_fs
*newfs
;
4435 struct fuse_args args
= FUSE_ARGS_INIT(0, NULL
);
4436 if (fuse_opt_add_arg(&args
, "") != -1 &&
4437 fuse_opt_add_arg(&args
, "-h") != -1) {
4438 fprintf(stderr
, "\n[%s]\n", m
->name
);
4439 newfs
= m
->factory(&args
, &fs
);
4440 assert(newfs
== NULL
);
4442 fuse_opt_free_args(&args
);
4444 pthread_mutex_unlock(&fuse_context_lock
);
4447 static int fuse_lib_opt_proc(void *data
, const char *arg
, int key
,
4448 struct fuse_args
*outargs
)
4450 (void) arg
; (void) outargs
;
4452 if (key
== KEY_HELP
) {
4453 struct fuse_config
*conf
= (struct fuse_config
*) data
;
4461 int fuse_is_lib_option(const char *opt
)
4463 return fuse_lowlevel_is_lib_option(opt
) ||
4464 fuse_opt_match(fuse_lib_opts
, opt
);
4467 static int fuse_init_intr_signal(int signum
, int *installed
)
4469 struct sigaction old_sa
;
4471 if (sigaction(signum
, NULL
, &old_sa
) == -1) {
4472 perror("fuse: cannot get old signal handler");
4476 if (old_sa
.sa_handler
== SIG_DFL
) {
4477 struct sigaction sa
;
4479 memset(&sa
, 0, sizeof(struct sigaction
));
4480 sa
.sa_handler
= fuse_intr_sighandler
;
4481 sigemptyset(&sa
.sa_mask
);
4483 if (sigaction(signum
, &sa
, NULL
) == -1) {
4484 perror("fuse: cannot set interrupt signal handler");
4492 static void fuse_restore_intr_signal(int signum
)
4494 struct sigaction sa
;
4496 memset(&sa
, 0, sizeof(struct sigaction
));
4497 sa
.sa_handler
= SIG_DFL
;
4498 sigaction(signum
, &sa
, NULL
);
4502 static int fuse_push_module(struct fuse
*f
, const char *module
,
4503 struct fuse_args
*args
)
4505 struct fuse_fs
*fs
[2] = { f
->fs
, NULL
};
4506 struct fuse_fs
*newfs
;
4507 struct fuse_module
*m
= fuse_get_module(module
);
4512 newfs
= m
->factory(args
, fs
);
4519 f
->nullpath_ok
= newfs
->op
.flag_nullpath_ok
&& f
->nullpath_ok
;
4520 f
->conf
.nopath
= newfs
->op
.flag_nopath
&& f
->conf
.nopath
;
4521 f
->utime_omit_ok
= newfs
->op
.flag_utime_omit_ok
&& f
->utime_omit_ok
;
4525 struct fuse_fs
*fuse_fs_new(const struct fuse_operations
*op
, size_t op_size
,
4530 if (sizeof(struct fuse_operations
) < op_size
) {
4531 fprintf(stderr
, "fuse: warning: library too old, some operations may not not work\n");
4532 op_size
= sizeof(struct fuse_operations
);
4535 fs
= (struct fuse_fs
*) calloc(1, sizeof(struct fuse_fs
));
4537 fprintf(stderr
, "fuse: failed to allocate fuse_fs object\n");
4541 fs
->user_data
= user_data
;
4543 memcpy(&fs
->op
, op
, op_size
);
4547 static int node_table_init(struct node_table
*t
)
4549 t
->size
= NODE_TABLE_MIN_SIZE
;
4550 t
->array
= (struct node
**) calloc(1, sizeof(struct node
*) * t
->size
);
4551 if (t
->array
== NULL
) {
4552 fprintf(stderr
, "fuse: memory allocation failed\n");
4561 static void *fuse_prune_nodes(void *fuse
)
4563 struct fuse
*f
= fuse
;
4567 sleep_time
= fuse_clean_cache(f
);
4573 int fuse_start_cleanup_thread(struct fuse
*f
)
4576 return fuse_start_thread(&f
->prune_thread
, fuse_prune_nodes
, f
);
4581 void fuse_stop_cleanup_thread(struct fuse
*f
)
4583 if (lru_enabled(f
)) {
4584 pthread_mutex_lock(&f
->lock
);
4585 pthread_cancel(f
->prune_thread
);
4586 pthread_mutex_unlock(&f
->lock
);
4587 pthread_join(f
->prune_thread
, NULL
);
4591 struct fuse
*fuse_new_common(struct fuse_chan
*ch
, struct fuse_args
*args
,
4592 const struct fuse_operations
*op
,
4593 size_t op_size
, void *user_data
, int compat
)
4598 struct fuse_lowlevel_ops llop
= fuse_path_ops
;
4600 if (fuse_create_context_key() == -1)
4603 f
= (struct fuse
*) calloc(1, sizeof(struct fuse
));
4605 fprintf(stderr
, "fuse: failed to allocate fuse object\n");
4606 goto out_delete_context_key
;
4609 fs
= fuse_fs_new(op
, op_size
, user_data
);
4613 fs
->compat
= compat
;
4615 f
->nullpath_ok
= fs
->op
.flag_nullpath_ok
;
4616 f
->conf
.nopath
= fs
->op
.flag_nopath
;
4617 f
->utime_omit_ok
= fs
->op
.flag_utime_omit_ok
;
4619 /* Oh f**k, this is ugly! */
4625 f
->conf
.entry_timeout
= 1.0;
4626 f
->conf
.attr_timeout
= 1.0;
4627 f
->conf
.negative_timeout
= 0.0;
4628 f
->conf
.intr_signal
= FUSE_DEFAULT_INTR_SIGNAL
;
4630 f
->pagesize
= getpagesize();
4631 init_list_head(&f
->partial_slabs
);
4632 init_list_head(&f
->full_slabs
);
4633 init_list_head(&f
->lru_table
);
4635 if (fuse_opt_parse(args
, &f
->conf
, fuse_lib_opts
,
4636 fuse_lib_opt_proc
) == -1)
4639 if (f
->conf
.modules
) {
4643 for (module
= f
->conf
.modules
; module
; module
= next
) {
4645 for (p
= module
; *p
&& *p
!= ':'; p
++);
4646 next
= *p
? p
+ 1 : NULL
;
4649 fuse_push_module(f
, module
, args
) == -1)
4654 if (!f
->conf
.ac_attr_timeout_set
)
4655 f
->conf
.ac_attr_timeout
= f
->conf
.attr_timeout
;
4657 #if defined(__FreeBSD__) || defined(__NetBSD__)
4659 * In FreeBSD, we always use these settings as inode numbers
4660 * are needed to make getcwd(3) work.
4662 f
->conf
.readdir_ino
= 1;
4665 if (compat
&& compat
<= 25) {
4666 if (fuse_sync_compat_args(args
) == -1)
4670 f
->se
= fuse_lowlevel_new_common(args
, &llop
, sizeof(llop
), f
);
4671 if (f
->se
== NULL
) {
4673 fuse_lib_help_modules();
4677 fuse_session_add_chan(f
->se
, ch
);
4679 if (f
->conf
.debug
) {
4680 fprintf(stderr
, "nullpath_ok: %i\n", f
->nullpath_ok
);
4681 fprintf(stderr
, "nopath: %i\n", f
->conf
.nopath
);
4682 fprintf(stderr
, "utime_omit_ok: %i\n", f
->utime_omit_ok
);
4685 /* Trace topmost layer by default */
4686 f
->fs
->debug
= f
->conf
.debug
;
4689 if (node_table_init(&f
->name_table
) == -1)
4690 goto out_free_session
;
4692 if (node_table_init(&f
->id_table
) == -1)
4693 goto out_free_name_table
;
4695 fuse_mutex_init(&f
->lock
);
4697 root
= alloc_node(f
);
4699 fprintf(stderr
, "fuse: memory allocation failed\n");
4700 goto out_free_id_table
;
4702 if (lru_enabled(f
)) {
4703 struct node_lru
*lnode
= node_lru(root
);
4704 init_list_head(&lnode
->lru
);
4707 strcpy(root
->inline_name
, "/");
4708 root
->name
= root
->inline_name
;
4711 fuse_init_intr_signal(f
->conf
.intr_signal
,
4712 &f
->intr_installed
) == -1)
4715 root
->parent
= NULL
;
4716 root
->nodeid
= FUSE_ROOT_ID
;
4725 free(f
->id_table
.array
);
4726 out_free_name_table
:
4727 free(f
->name_table
.array
);
4729 fuse_session_destroy(f
->se
);
4731 /* Horrible compatibility hack to stop the destructor from being
4732 called on the filesystem without init being called first */
4733 fs
->op
.destroy
= NULL
;
4734 fuse_fs_destroy(f
->fs
);
4735 free(f
->conf
.modules
);
4738 out_delete_context_key
:
4739 fuse_delete_context_key();
4744 struct fuse
*fuse_new(struct fuse_chan
*ch
, struct fuse_args
*args
,
4745 const struct fuse_operations
*op
, size_t op_size
,
4748 return fuse_new_common(ch
, args
, op
, op_size
, user_data
, 0);
4751 void fuse_destroy(struct fuse
*f
)
4755 if (f
->conf
.intr
&& f
->intr_installed
)
4756 fuse_restore_intr_signal(f
->conf
.intr_signal
);
4759 struct fuse_context_i
*c
= fuse_get_context_internal();
4761 memset(c
, 0, sizeof(*c
));
4764 for (i
= 0; i
< f
->id_table
.size
; i
++) {
4767 for (node
= f
->id_table
.array
[i
]; node
!= NULL
;
4768 node
= node
->id_next
) {
4769 if (node
->is_hidden
) {
4771 if (try_get_path(f
, node
->nodeid
, NULL
, &path
, NULL
, false) == 0) {
4772 fuse_fs_unlink(f
->fs
, path
);
4779 for (i
= 0; i
< f
->id_table
.size
; i
++) {
4783 for (node
= f
->id_table
.array
[i
]; node
!= NULL
; node
= next
) {
4784 next
= node
->id_next
;
4789 assert(list_empty(&f
->partial_slabs
));
4790 assert(list_empty(&f
->full_slabs
));
4792 free(f
->id_table
.array
);
4793 free(f
->name_table
.array
);
4794 pthread_mutex_destroy(&f
->lock
);
4795 fuse_session_destroy(f
->se
);
4796 free(f
->conf
.modules
);
4798 fuse_delete_context_key();
4801 static struct fuse
*fuse_new_common_compat25(int fd
, struct fuse_args
*args
,
4802 const struct fuse_operations
*op
,
4803 size_t op_size
, int compat
)
4805 struct fuse
*f
= NULL
;
4806 struct fuse_chan
*ch
= fuse_kern_chan_new(fd
);
4809 f
= fuse_new_common(ch
, args
, op
, op_size
, NULL
, compat
);
4814 /* called with fuse_context_lock held or during initialization (before
4815 main() has been called) */
4816 void fuse_register_module(struct fuse_module
*mod
)
4819 mod
->so
= fuse_current_so
;
4822 mod
->next
= fuse_modules
;
4826 #if !defined(__FreeBSD__) && !defined(__NetBSD__)
4828 static struct fuse
*fuse_new_common_compat(int fd
, const char *opts
,
4829 const struct fuse_operations
*op
,
4830 size_t op_size
, int compat
)
4833 struct fuse_args args
= FUSE_ARGS_INIT(0, NULL
);
4835 if (fuse_opt_add_arg(&args
, "") == -1)
4838 (fuse_opt_add_arg(&args
, "-o") == -1 ||
4839 fuse_opt_add_arg(&args
, opts
) == -1)) {
4840 fuse_opt_free_args(&args
);
4843 f
= fuse_new_common_compat25(fd
, &args
, op
, op_size
, compat
);
4844 fuse_opt_free_args(&args
);
4849 struct fuse
*fuse_new_compat22(int fd
, const char *opts
,
4850 const struct fuse_operations_compat22
*op
,
4853 return fuse_new_common_compat(fd
, opts
, (struct fuse_operations
*) op
,
4857 struct fuse
*fuse_new_compat2(int fd
, const char *opts
,
4858 const struct fuse_operations_compat2
*op
)
4860 return fuse_new_common_compat(fd
, opts
, (struct fuse_operations
*) op
,
4861 sizeof(struct fuse_operations_compat2
),
4865 struct fuse
*fuse_new_compat1(int fd
, int flags
,
4866 const struct fuse_operations_compat1
*op
)
4868 const char *opts
= NULL
;
4869 if (flags
& FUSE_DEBUG_COMPAT1
)
4871 return fuse_new_common_compat(fd
, opts
, (struct fuse_operations
*) op
,
4872 sizeof(struct fuse_operations_compat1
),
4876 FUSE_SYMVER(".symver fuse_exited,__fuse_exited@");
4877 FUSE_SYMVER(".symver fuse_process_cmd,__fuse_process_cmd@");
4878 FUSE_SYMVER(".symver fuse_read_cmd,__fuse_read_cmd@");
4879 FUSE_SYMVER(".symver fuse_set_getcontext_func,__fuse_set_getcontext_func@");
4880 FUSE_SYMVER(".symver fuse_new_compat2,fuse_new@");
4881 FUSE_SYMVER(".symver fuse_new_compat22,fuse_new@FUSE_2.2");
4883 #endif /* __FreeBSD__ || __NetBSD__ */
4885 struct fuse
*fuse_new_compat25(int fd
, struct fuse_args
*args
,
4886 const struct fuse_operations_compat25
*op
,
4889 return fuse_new_common_compat25(fd
, args
, (struct fuse_operations
*) op
,
4893 FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5");