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
11 #include "fuse_lowlevel.h"
13 #include "fuse_misc.h"
27 #include <sys/param.h>
31 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
33 #define FUSE_UNKNOWN_INO 0xffffffff
34 #define OFFSET_MAX 0x7fffffffffffffffLL
41 double negative_timeout
;
43 double ac_attr_timeout
;
44 int ac_attr_timeout_set
;
60 struct fuse_operations op
;
65 struct fuse_session
*se
;
66 struct node
**name_table
;
67 size_t name_table_size
;
68 struct node
**id_table
;
71 unsigned int generation
;
74 pthread_rwlock_t tree_lock
;
75 struct fuse_config conf
;
91 struct node
*name_next
;
94 unsigned int generation
;
105 pthread_mutex_t lock
;
119 struct fuse_context_i
{
120 struct fuse_context ctx
;
124 static pthread_key_t fuse_context_key
;
125 static pthread_mutex_t fuse_context_lock
= PTHREAD_MUTEX_INITIALIZER
;
126 static int fuse_context_ref
;
128 static struct node
*get_node_nocheck(struct fuse
*f
, fuse_ino_t nodeid
)
130 size_t hash
= nodeid
% f
->id_table_size
;
133 for (node
= f
->id_table
[hash
]; node
!= NULL
; node
= node
->id_next
)
134 if (node
->nodeid
== nodeid
)
140 static struct node
*get_node(struct fuse
*f
, fuse_ino_t nodeid
)
142 struct node
*node
= get_node_nocheck(f
, nodeid
);
144 fprintf(stderr
, "fuse internal error: node %llu not found\n",
145 (unsigned long long) nodeid
);
151 static void free_node(struct node
*node
)
157 static void unhash_id(struct fuse
*f
, struct node
*node
)
159 size_t hash
= node
->nodeid
% f
->id_table_size
;
160 struct node
**nodep
= &f
->id_table
[hash
];
162 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->id_next
)
163 if (*nodep
== node
) {
164 *nodep
= node
->id_next
;
169 static void hash_id(struct fuse
*f
, struct node
*node
)
171 size_t hash
= node
->nodeid
% f
->id_table_size
;
172 node
->id_next
= f
->id_table
[hash
];
173 f
->id_table
[hash
] = node
;
176 static unsigned int name_hash(struct fuse
*f
, fuse_ino_t parent
,
179 unsigned int hash
= *name
;
182 for (name
+= 1; *name
!= '\0'; name
++)
183 hash
= (hash
<< 5) - hash
+ *name
;
185 return (hash
+ parent
) % f
->name_table_size
;
188 static void unref_node(struct fuse
*f
, struct node
*node
);
190 static void unhash_name(struct fuse
*f
, struct node
*node
)
193 size_t hash
= name_hash(f
, node
->parent
->nodeid
, node
->name
);
194 struct node
**nodep
= &f
->name_table
[hash
];
196 for (; *nodep
!= NULL
; nodep
= &(*nodep
)->name_next
)
197 if (*nodep
== node
) {
198 *nodep
= node
->name_next
;
199 node
->name_next
= NULL
;
200 unref_node(f
, node
->parent
);
206 fprintf(stderr
, "fuse internal error: unable to unhash node: %llu\n",
207 (unsigned long long) node
->nodeid
);
212 static int hash_name(struct fuse
*f
, struct node
*node
, fuse_ino_t parentid
,
215 size_t hash
= name_hash(f
, parentid
, name
);
216 struct node
*parent
= get_node(f
, parentid
);
217 node
->name
= strdup(name
);
218 if (node
->name
== NULL
)
222 node
->parent
= parent
;
223 node
->name_next
= f
->name_table
[hash
];
224 f
->name_table
[hash
] = node
;
228 static void delete_node(struct fuse
*f
, struct node
*node
)
231 fprintf(stderr
, "delete: %llu\n", (unsigned long long) node
->nodeid
);
238 static void unref_node(struct fuse
*f
, struct node
*node
)
240 assert(node
->refctr
> 0);
243 delete_node(f
, node
);
246 static fuse_ino_t
next_id(struct fuse
*f
)
249 f
->ctr
= (f
->ctr
+ 1) & 0xffffffff;
252 } while (f
->ctr
== 0 || f
->ctr
== FUSE_UNKNOWN_INO
||
253 get_node_nocheck(f
, f
->ctr
) != NULL
);
257 static struct node
*lookup_node(struct fuse
*f
, fuse_ino_t parent
,
260 size_t hash
= name_hash(f
, parent
, name
);
263 for (node
= f
->name_table
[hash
]; node
!= NULL
; node
= node
->name_next
)
264 if (node
->parent
->nodeid
== parent
&& strcmp(node
->name
, name
) == 0)
270 static struct node
*find_node(struct fuse
*f
, fuse_ino_t parent
,
275 pthread_mutex_lock(&f
->lock
);
276 node
= lookup_node(f
, parent
, name
);
278 node
= (struct node
*) calloc(1, sizeof(struct node
));
283 node
->nodeid
= next_id(f
);
284 node
->open_count
= 0;
286 node
->generation
= f
->generation
;
287 if (hash_name(f
, node
, parent
, name
) == -1) {
296 pthread_mutex_unlock(&f
->lock
);
300 static char *add_name(char **buf
, unsigned *bufsize
, char *s
, const char *name
)
302 size_t len
= strlen(name
);
304 if (s
- len
<= *buf
) {
305 unsigned pathlen
= *bufsize
- (s
- *buf
);
306 unsigned newbufsize
= *bufsize
;
309 while (newbufsize
< pathlen
+ len
+ 1) {
310 if (newbufsize
>= 0x80000000)
311 newbufsize
= 0xffffffff;
316 newbuf
= realloc(*buf
, newbufsize
);
321 s
= newbuf
+ newbufsize
- pathlen
;
322 memmove(s
, newbuf
+ *bufsize
- pathlen
, pathlen
);
323 *bufsize
= newbufsize
;
326 strncpy(s
, name
, len
);
333 static char *get_path_name(struct fuse
*f
, fuse_ino_t nodeid
, const char *name
)
335 unsigned bufsize
= 256;
340 buf
= malloc(bufsize
);
344 s
= buf
+ bufsize
- 1;
348 s
= add_name(&buf
, &bufsize
, s
, name
);
353 pthread_mutex_lock(&f
->lock
);
354 for (node
= get_node(f
, nodeid
); node
&& node
->nodeid
!= FUSE_ROOT_ID
;
355 node
= node
->parent
) {
356 if (node
->name
== NULL
) {
361 s
= add_name(&buf
, &bufsize
, s
, node
->name
);
365 pthread_mutex_unlock(&f
->lock
);
367 if (node
== NULL
|| s
== NULL
)
371 memmove(buf
, s
, bufsize
- (s
- buf
));
381 static char *get_path(struct fuse
*f
, fuse_ino_t nodeid
)
383 return get_path_name(f
, nodeid
, NULL
);
386 static void forget_node(struct fuse
*f
, fuse_ino_t nodeid
, uint64_t nlookup
)
389 if (nodeid
== FUSE_ROOT_ID
)
391 pthread_mutex_lock(&f
->lock
);
392 node
= get_node(f
, nodeid
);
393 assert(node
->nlookup
>= nlookup
);
394 node
->nlookup
-= nlookup
;
395 if (!node
->nlookup
) {
396 unhash_name(f
, node
);
399 pthread_mutex_unlock(&f
->lock
);
402 static void remove_node(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
406 pthread_mutex_lock(&f
->lock
);
407 node
= lookup_node(f
, dir
, name
);
409 unhash_name(f
, node
);
410 pthread_mutex_unlock(&f
->lock
);
413 static int rename_node(struct fuse
*f
, fuse_ino_t olddir
, const char *oldname
,
414 fuse_ino_t newdir
, const char *newname
, int hide
)
417 struct node
*newnode
;
420 pthread_mutex_lock(&f
->lock
);
421 node
= lookup_node(f
, olddir
, oldname
);
422 newnode
= lookup_node(f
, newdir
, newname
);
426 if (newnode
!= NULL
) {
428 fprintf(stderr
, "fuse: hidden file got created during hiding\n");
432 unhash_name(f
, newnode
);
435 unhash_name(f
, node
);
436 if (hash_name(f
, node
, newdir
, newname
) == -1) {
445 pthread_mutex_unlock(&f
->lock
);
449 static void set_stat(struct fuse
*f
, fuse_ino_t nodeid
, struct stat
*stbuf
)
451 if (!f
->conf
.use_ino
)
452 stbuf
->st_ino
= nodeid
;
453 if (f
->conf
.set_mode
)
454 stbuf
->st_mode
= (stbuf
->st_mode
& S_IFMT
) | (0777 & ~f
->conf
.umask
);
456 stbuf
->st_uid
= f
->conf
.uid
;
458 stbuf
->st_gid
= f
->conf
.gid
;
461 static struct fuse
*req_fuse(fuse_req_t req
)
463 return (struct fuse
*) fuse_req_userdata(req
);
466 static void fuse_intr_sighandler(int sig
)
472 struct fuse_intr_data
{
478 static void fuse_interrupt(fuse_req_t req
, void *d_
)
480 struct fuse_intr_data
*d
= d_
;
481 struct fuse
*f
= req_fuse(req
);
483 if (d
->id
== pthread_self())
486 pthread_mutex_lock(&f
->lock
);
487 while (!d
->finished
) {
489 struct timespec timeout
;
491 pthread_kill(d
->id
, f
->conf
.intr_signal
);
492 gettimeofday(&now
, NULL
);
493 timeout
.tv_sec
= now
.tv_sec
+ 1;
494 timeout
.tv_nsec
= now
.tv_usec
* 1000;
495 pthread_cond_timedwait(&d
->cond
, &f
->lock
, &timeout
);
497 pthread_mutex_unlock(&f
->lock
);
500 static void fuse_do_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
501 struct fuse_intr_data
*d
)
503 pthread_mutex_lock(&f
->lock
);
505 pthread_cond_broadcast(&d
->cond
);
506 pthread_mutex_unlock(&f
->lock
);
507 fuse_req_interrupt_func(req
, NULL
, NULL
);
508 pthread_cond_destroy(&d
->cond
);
511 static void fuse_do_prepare_interrupt(fuse_req_t req
, struct fuse_intr_data
*d
)
513 d
->id
= pthread_self();
514 pthread_cond_init(&d
->cond
, NULL
);
516 fuse_req_interrupt_func(req
, fuse_interrupt
, d
);
519 static void fuse_finish_interrupt(struct fuse
*f
, fuse_req_t req
,
520 struct fuse_intr_data
*d
)
523 fuse_do_finish_interrupt(f
, req
, d
);
526 static void fuse_prepare_interrupt(struct fuse
*f
, fuse_req_t req
,
527 struct fuse_intr_data
*d
)
530 fuse_do_prepare_interrupt(req
, d
);
533 int fuse_fs_getattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
)
535 fuse_get_context()->private_data
= fs
->user_data
;
537 return fs
->op
.getattr(path
, buf
);
542 int fuse_fs_fgetattr(struct fuse_fs
*fs
, const char *path
, struct stat
*buf
,
543 struct fuse_file_info
*fi
)
545 fuse_get_context()->private_data
= fs
->user_data
;
547 return fs
->op
.fgetattr(path
, buf
, fi
);
548 else if (fs
->op
.getattr
)
549 return fs
->op
.getattr(path
, buf
);
554 int fuse_fs_rename(struct fuse_fs
*fs
, const char *oldpath
,
557 fuse_get_context()->private_data
= fs
->user_data
;
559 return fs
->op
.rename(oldpath
, newpath
);
564 int fuse_fs_unlink(struct fuse_fs
*fs
, const char *path
)
566 fuse_get_context()->private_data
= fs
->user_data
;
568 return fs
->op
.unlink(path
);
573 int fuse_fs_rmdir(struct fuse_fs
*fs
, const char *path
)
575 fuse_get_context()->private_data
= fs
->user_data
;
577 return fs
->op
.rmdir(path
);
582 int fuse_fs_symlink(struct fuse_fs
*fs
, const char *linkname
, const char *path
)
584 fuse_get_context()->private_data
= fs
->user_data
;
586 return fs
->op
.symlink(linkname
, path
);
591 int fuse_fs_link(struct fuse_fs
*fs
, const char *oldpath
, const char *newpath
)
593 fuse_get_context()->private_data
= fs
->user_data
;
595 return fs
->op
.link(oldpath
, newpath
);
600 int fuse_fs_release(struct fuse_fs
*fs
, const char *path
,
601 struct fuse_file_info
*fi
)
603 fuse_get_context()->private_data
= fs
->user_data
;
605 return fs
->op
.release(path
, fi
);
610 int fuse_fs_opendir(struct fuse_fs
*fs
, const char *path
,
611 struct fuse_file_info
*fi
)
613 fuse_get_context()->private_data
= fs
->user_data
;
615 return fs
->op
.opendir(path
, fi
);
620 int fuse_fs_open(struct fuse_fs
*fs
, const char *path
,
621 struct fuse_file_info
*fi
)
623 fuse_get_context()->private_data
= fs
->user_data
;
625 return fs
->op
.open(path
, fi
);
630 int fuse_fs_read(struct fuse_fs
*fs
, const char *path
, char *buf
, size_t size
,
631 off_t off
, struct fuse_file_info
*fi
)
633 fuse_get_context()->private_data
= fs
->user_data
;
635 return fs
->op
.read(path
, buf
, size
, off
, fi
);
640 int fuse_fs_write(struct fuse_fs
*fs
, const char *path
, const char *buf
,
641 size_t size
, off_t off
, struct fuse_file_info
*fi
)
643 fuse_get_context()->private_data
= fs
->user_data
;
645 return fs
->op
.write(path
, buf
, size
, off
, fi
);
650 int fuse_fs_fsync(struct fuse_fs
*fs
, const char *path
, int datasync
,
651 struct fuse_file_info
*fi
)
653 fuse_get_context()->private_data
= fs
->user_data
;
655 return fs
->op
.fsync(path
, datasync
, fi
);
660 int fuse_fs_fsyncdir(struct fuse_fs
*fs
, const char *path
, int datasync
,
661 struct fuse_file_info
*fi
)
663 fuse_get_context()->private_data
= fs
->user_data
;
665 return fs
->op
.fsyncdir(path
, datasync
, fi
);
670 int fuse_fs_flush(struct fuse_fs
*fs
, const char *path
,
671 struct fuse_file_info
*fi
)
673 fuse_get_context()->private_data
= fs
->user_data
;
675 return fs
->op
.flush(path
, fi
);
680 int fuse_fs_statfs(struct fuse_fs
*fs
, const char *path
, struct statvfs
*buf
)
682 fuse_get_context()->private_data
= fs
->user_data
;
684 return fs
->op
.statfs(path
, buf
);
686 buf
->f_namemax
= 255;
692 int fuse_fs_releasedir(struct fuse_fs
*fs
, const char *path
,
693 struct fuse_file_info
*fi
)
695 fuse_get_context()->private_data
= fs
->user_data
;
696 if (fs
->op
.releasedir
)
697 return fs
->op
.releasedir(path
, fi
);
702 int fuse_fs_readdir(struct fuse_fs
*fs
, const char *path
, void *buf
,
703 fuse_fill_dir_t filler
, off_t off
,
704 struct fuse_file_info
*fi
)
706 fuse_get_context()->private_data
= fs
->user_data
;
708 return fs
->op
.readdir(path
, buf
, filler
, off
, fi
);
713 int fuse_fs_create(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
714 struct fuse_file_info
*fi
)
716 fuse_get_context()->private_data
= fs
->user_data
;
718 return fs
->op
.create(path
, mode
, fi
);
723 int fuse_fs_lock(struct fuse_fs
*fs
, const char *path
,
724 struct fuse_file_info
*fi
, int cmd
, struct flock
*lock
)
726 fuse_get_context()->private_data
= fs
->user_data
;
728 return fs
->op
.lock(path
, fi
, cmd
, lock
);
733 int fuse_fs_chown(struct fuse_fs
*fs
, const char *path
, uid_t uid
, gid_t gid
)
735 fuse_get_context()->private_data
= fs
->user_data
;
737 return fs
->op
.chown(path
, uid
, gid
);
742 int fuse_fs_truncate(struct fuse_fs
*fs
, const char *path
, off_t size
)
744 fuse_get_context()->private_data
= fs
->user_data
;
746 return fs
->op
.truncate(path
, size
);
751 int fuse_fs_ftruncate(struct fuse_fs
*fs
, const char *path
, off_t size
,
752 struct fuse_file_info
*fi
)
754 fuse_get_context()->private_data
= fs
->user_data
;
755 if (fs
->op
.ftruncate
)
756 return fs
->op
.ftruncate(path
, size
, fi
);
757 else if (fs
->op
.truncate
)
758 return fs
->op
.truncate(path
, size
);
763 int fuse_fs_utimens(struct fuse_fs
*fs
, const char *path
,
764 const struct timespec tv
[2])
766 fuse_get_context()->private_data
= fs
->user_data
;
768 return fs
->op
.utimens(path
, tv
);
769 else if(fs
->op
.utime
) {
771 buf
.actime
= tv
[0].tv_sec
;
772 buf
.modtime
= tv
[1].tv_sec
;
773 return fs
->op
.utime(path
, &buf
);
778 int fuse_fs_access(struct fuse_fs
*fs
, const char *path
, int mask
)
780 fuse_get_context()->private_data
= fs
->user_data
;
782 return fs
->op
.access(path
, mask
);
787 int fuse_fs_readlink(struct fuse_fs
*fs
, const char *path
, char *buf
,
790 fuse_get_context()->private_data
= fs
->user_data
;
792 return fs
->op
.readlink(path
, buf
, len
);
797 int fuse_fs_mknod(struct fuse_fs
*fs
, const char *path
, mode_t mode
,
800 fuse_get_context()->private_data
= fs
->user_data
;
802 return fs
->op
.mknod(path
, mode
, rdev
);
807 int fuse_fs_mkdir(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
809 fuse_get_context()->private_data
= fs
->user_data
;
811 return fs
->op
.mkdir(path
, mode
);
816 int fuse_fs_setxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
817 const char *value
, size_t size
, int flags
)
819 fuse_get_context()->private_data
= fs
->user_data
;
821 return fs
->op
.setxattr(path
, name
, value
, size
, flags
);
826 int fuse_fs_getxattr(struct fuse_fs
*fs
, const char *path
, const char *name
,
827 char *value
, size_t size
)
829 fuse_get_context()->private_data
= fs
->user_data
;
831 return fs
->op
.getxattr(path
, name
, value
, size
);
836 int fuse_fs_listxattr(struct fuse_fs
*fs
, const char *path
, char *list
,
839 fuse_get_context()->private_data
= fs
->user_data
;
840 if (fs
->op
.listxattr
)
841 return fs
->op
.listxattr(path
, list
, size
);
846 int fuse_fs_bmap(struct fuse_fs
*fs
, const char *path
, size_t blocksize
,
849 fuse_get_context()->private_data
= fs
->user_data
;
851 return fs
->op
.bmap(path
, blocksize
, idx
);
856 int fuse_fs_removexattr(struct fuse_fs
*fs
, const char *path
, const char *name
)
858 fuse_get_context()->private_data
= fs
->user_data
;
859 if (fs
->op
.removexattr
)
860 return fs
->op
.removexattr(path
, name
);
865 static int is_open(struct fuse
*f
, fuse_ino_t dir
, const char *name
)
869 pthread_mutex_lock(&f
->lock
);
870 node
= lookup_node(f
, dir
, name
);
871 if (node
&& node
->open_count
> 0)
873 pthread_mutex_unlock(&f
->lock
);
877 static char *hidden_name(struct fuse
*f
, fuse_ino_t dir
, const char *oldname
,
878 char *newname
, size_t bufsize
)
882 struct node
*newnode
;
888 pthread_mutex_lock(&f
->lock
);
889 node
= lookup_node(f
, dir
, oldname
);
891 pthread_mutex_unlock(&f
->lock
);
896 snprintf(newname
, bufsize
, ".fuse_hidden%08x%08x",
897 (unsigned int) node
->nodeid
, f
->hidectr
);
898 newnode
= lookup_node(f
, dir
, newname
);
900 pthread_mutex_unlock(&f
->lock
);
902 newpath
= get_path_name(f
, dir
, newname
);
906 res
= fuse_fs_getattr(f
->fs
, newpath
, &buf
);
911 } while(res
== 0 && --failctr
);
916 static int hide_node(struct fuse
*f
, const char *oldpath
,
917 fuse_ino_t dir
, const char *oldname
)
923 newpath
= hidden_name(f
, dir
, oldname
, newname
, sizeof(newname
));
925 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
927 err
= rename_node(f
, dir
, oldname
, dir
, newname
, 1);
933 static int lookup_path(struct fuse
*f
, fuse_ino_t nodeid
,
934 const char *name
, const char *path
,
935 struct fuse_entry_param
*e
, struct fuse_file_info
*fi
)
939 memset(e
, 0, sizeof(struct fuse_entry_param
));
941 res
= fuse_fs_fgetattr(f
->fs
, path
, &e
->attr
, fi
);
943 res
= fuse_fs_getattr(f
->fs
, path
, &e
->attr
);
947 node
= find_node(f
, nodeid
, name
);
951 e
->ino
= node
->nodeid
;
952 e
->generation
= node
->generation
;
953 e
->entry_timeout
= f
->conf
.entry_timeout
;
954 e
->attr_timeout
= f
->conf
.attr_timeout
;
955 set_stat(f
, e
->ino
, &e
->attr
);
957 fprintf(stderr
, " NODEID: %lu\n", (unsigned long) e
->ino
);
963 static struct fuse_context_i
*fuse_get_context_internal(void)
965 struct fuse_context_i
*c
;
967 c
= (struct fuse_context_i
*) pthread_getspecific(fuse_context_key
);
969 c
= (struct fuse_context_i
*) malloc(sizeof(struct fuse_context_i
));
971 /* This is hard to deal with properly, so just abort. If
972 memory is so low that the context cannot be allocated,
973 there's not much hope for the filesystem anyway */
974 fprintf(stderr
, "fuse: failed to allocate thread specific data\n");
977 pthread_setspecific(fuse_context_key
, c
);
982 static void fuse_freecontext(void *data
)
987 static int fuse_create_context_key(void)
990 pthread_mutex_lock(&fuse_context_lock
);
991 if (!fuse_context_ref
) {
992 err
= pthread_key_create(&fuse_context_key
, fuse_freecontext
);
994 fprintf(stderr
, "fuse: failed to create thread specific key: %s\n",
996 pthread_mutex_unlock(&fuse_context_lock
);
1001 pthread_mutex_unlock(&fuse_context_lock
);
1005 static void fuse_delete_context_key(void)
1007 pthread_mutex_lock(&fuse_context_lock
);
1009 if (!fuse_context_ref
) {
1010 free(pthread_getspecific(fuse_context_key
));
1011 pthread_key_delete(fuse_context_key
);
1013 pthread_mutex_unlock(&fuse_context_lock
);
1016 static struct fuse
*req_fuse_prepare(fuse_req_t req
)
1018 struct fuse_context_i
*c
= fuse_get_context_internal();
1019 const struct fuse_ctx
*ctx
= fuse_req_ctx(req
);
1021 c
->ctx
.fuse
= req_fuse(req
);
1022 c
->ctx
.uid
= ctx
->uid
;
1023 c
->ctx
.gid
= ctx
->gid
;
1024 c
->ctx
.pid
= ctx
->pid
;
1026 c
->ctx
.umask
= ctx
->umask
;
1031 static void reply_err(fuse_req_t req
, int err
)
1033 /* fuse_reply_err() uses non-negated errno values */
1034 fuse_reply_err(req
, -err
);
1037 static void reply_entry(fuse_req_t req
, const struct fuse_entry_param
*e
,
1041 struct fuse
*f
= req_fuse(req
);
1042 if (fuse_reply_entry(req
, e
) == -ENOENT
)
1043 forget_node(f
, e
->ino
, 1);
1045 reply_err(req
, err
);
1048 void fuse_fs_init(struct fuse_fs
*fs
, struct fuse_conn_info
*conn
)
1050 fuse_get_context()->private_data
= fs
->user_data
;
1052 fs
->user_data
= fs
->op
.init(conn
);
1055 static void fuse_lib_init(void *data
, struct fuse_conn_info
*conn
)
1057 struct fuse
*f
= (struct fuse
*) data
;
1058 struct fuse_context_i
*c
= fuse_get_context_internal();
1060 memset(c
, 0, sizeof(*c
));
1062 fuse_fs_init(f
->fs
, conn
);
1065 void fuse_fs_destroy(struct fuse_fs
*fs
)
1067 fuse_get_context()->private_data
= fs
->user_data
;
1069 fs
->op
.destroy(fs
->user_data
);
1073 static void fuse_lib_destroy(void *data
)
1075 struct fuse
*f
= (struct fuse
*) data
;
1076 struct fuse_context_i
*c
= fuse_get_context_internal();
1078 memset(c
, 0, sizeof(*c
));
1080 fuse_fs_destroy(f
->fs
);
1084 static void fuse_lib_lookup(fuse_req_t req
, fuse_ino_t parent
,
1087 struct fuse
*f
= req_fuse_prepare(req
);
1088 struct fuse_entry_param e
;
1093 pthread_rwlock_rdlock(&f
->tree_lock
);
1094 path
= get_path_name(f
, parent
, name
);
1096 struct fuse_intr_data d
;
1098 fprintf(stderr
, "LOOKUP %s\n", path
);
1099 fuse_prepare_interrupt(f
, req
, &d
);
1100 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
1101 if (err
== -ENOENT
&& f
->conf
.negative_timeout
!= 0.0) {
1103 e
.entry_timeout
= f
->conf
.negative_timeout
;
1106 fuse_finish_interrupt(f
, req
, &d
);
1109 pthread_rwlock_unlock(&f
->tree_lock
);
1110 reply_entry(req
, &e
, err
);
1113 static void fuse_lib_forget(fuse_req_t req
, fuse_ino_t ino
,
1114 unsigned long nlookup
)
1116 struct fuse
*f
= req_fuse(req
);
1118 fprintf(stderr
, "FORGET %llu/%lu\n", (unsigned long long)ino
, nlookup
);
1119 forget_node(f
, ino
, nlookup
);
1120 fuse_reply_none(req
);
1123 static void fuse_lib_getattr(fuse_req_t req
, fuse_ino_t ino
,
1124 struct fuse_file_info
*fi
)
1126 struct fuse
*f
= req_fuse_prepare(req
);
1132 memset(&buf
, 0, sizeof(buf
));
1135 pthread_rwlock_rdlock(&f
->tree_lock
);
1136 path
= get_path(f
, ino
);
1138 struct fuse_intr_data d
;
1139 fuse_prepare_interrupt(f
, req
, &d
);
1140 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
1141 fuse_finish_interrupt(f
, req
, &d
);
1144 pthread_rwlock_unlock(&f
->tree_lock
);
1146 set_stat(f
, ino
, &buf
);
1147 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
1149 reply_err(req
, err
);
1152 int fuse_fs_chmod(struct fuse_fs
*fs
, const char *path
, mode_t mode
)
1154 fuse_get_context()->private_data
= fs
->user_data
;
1156 return fs
->op
.chmod(path
, mode
);
1161 static void fuse_lib_setattr(fuse_req_t req
, fuse_ino_t ino
, struct stat
*attr
,
1162 int valid
, struct fuse_file_info
*fi
)
1164 struct fuse
*f
= req_fuse_prepare(req
);
1170 pthread_rwlock_rdlock(&f
->tree_lock
);
1171 path
= get_path(f
, ino
);
1173 struct fuse_intr_data d
;
1174 fuse_prepare_interrupt(f
, req
, &d
);
1176 if (!err
&& (valid
& FUSE_SET_ATTR_MODE
))
1177 err
= fuse_fs_chmod(f
->fs
, path
, attr
->st_mode
);
1178 if (!err
&& (valid
& (FUSE_SET_ATTR_UID
| FUSE_SET_ATTR_GID
))) {
1180 (valid
& FUSE_SET_ATTR_UID
) ? attr
->st_uid
: (uid_t
) -1;
1182 (valid
& FUSE_SET_ATTR_GID
) ? attr
->st_gid
: (gid_t
) -1;
1183 err
= fuse_fs_chown(f
->fs
, path
, uid
, gid
);
1185 if (!err
&& (valid
& FUSE_SET_ATTR_SIZE
)) {
1187 err
= fuse_fs_ftruncate(f
->fs
, path
, attr
->st_size
, fi
);
1189 err
= fuse_fs_truncate(f
->fs
, path
, attr
->st_size
);
1191 #ifdef HAVE_UTIMENSAT
1192 if (!err
&& f
->utime_omit_ok
&&
1193 (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
))) {
1194 struct timespec tv
[2];
1198 tv
[0].tv_nsec
= UTIME_OMIT
;
1199 tv
[1].tv_nsec
= UTIME_OMIT
;
1201 if (valid
& FUSE_SET_ATTR_ATIME_NOW
)
1202 tv
[0].tv_nsec
= UTIME_NOW
;
1203 else if (valid
& FUSE_SET_ATTR_ATIME
)
1204 tv
[0] = attr
->st_atim
;
1206 if (valid
& FUSE_SET_ATTR_MTIME_NOW
)
1207 tv
[1].tv_nsec
= UTIME_NOW
;
1208 else if (valid
& FUSE_SET_ATTR_MTIME
)
1209 tv
[1] = attr
->st_mtim
;
1211 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
1214 if (!err
&& (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) ==
1215 (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) {
1216 struct timespec tv
[2];
1217 tv
[0].tv_sec
= attr
->st_atime
;
1218 tv
[0].tv_nsec
= ST_ATIM_NSEC(attr
);
1219 tv
[1].tv_sec
= attr
->st_mtime
;
1220 tv
[1].tv_nsec
= ST_MTIM_NSEC(attr
);
1221 err
= fuse_fs_utimens(f
->fs
, path
, tv
);
1224 err
= fuse_fs_getattr(f
->fs
, path
, &buf
);
1225 fuse_finish_interrupt(f
, req
, &d
);
1228 pthread_rwlock_unlock(&f
->tree_lock
);
1230 set_stat(f
, ino
, &buf
);
1231 fuse_reply_attr(req
, &buf
, f
->conf
.attr_timeout
);
1233 reply_err(req
, err
);
1236 static void fuse_lib_access(fuse_req_t req
, fuse_ino_t ino
, int mask
)
1238 struct fuse
*f
= req_fuse_prepare(req
);
1243 pthread_rwlock_rdlock(&f
->tree_lock
);
1244 path
= get_path(f
, ino
);
1246 struct fuse_intr_data d
;
1248 fprintf(stderr
, "ACCESS %s 0%o\n", path
, mask
);
1249 fuse_prepare_interrupt(f
, req
, &d
);
1250 err
= fuse_fs_access(f
->fs
, path
, mask
);
1251 fuse_finish_interrupt(f
, req
, &d
);
1254 pthread_rwlock_unlock(&f
->tree_lock
);
1255 reply_err(req
, err
);
1258 static void fuse_lib_readlink(fuse_req_t req
, fuse_ino_t ino
)
1260 struct fuse
*f
= req_fuse_prepare(req
);
1261 char linkname
[PATH_MAX
+ 1];
1266 pthread_rwlock_rdlock(&f
->tree_lock
);
1267 path
= get_path(f
, ino
);
1269 struct fuse_intr_data d
;
1270 fuse_prepare_interrupt(f
, req
, &d
);
1271 err
= fuse_fs_readlink(f
->fs
, path
, linkname
, sizeof(linkname
));
1272 fuse_finish_interrupt(f
, req
, &d
);
1275 pthread_rwlock_unlock(&f
->tree_lock
);
1277 linkname
[PATH_MAX
] = '\0';
1278 fuse_reply_readlink(req
, linkname
);
1280 reply_err(req
, err
);
1283 static void fuse_lib_mknod(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
1284 mode_t mode
, dev_t rdev
)
1286 struct fuse
*f
= req_fuse_prepare(req
);
1287 struct fuse_entry_param e
;
1292 pthread_rwlock_rdlock(&f
->tree_lock
);
1293 path
= get_path_name(f
, parent
, name
);
1295 struct fuse_intr_data d
;
1297 fprintf(stderr
, "MKNOD %s\n", path
);
1298 fuse_prepare_interrupt(f
, req
, &d
);
1300 if (S_ISREG(mode
)) {
1301 struct fuse_file_info fi
;
1303 memset(&fi
, 0, sizeof(fi
));
1304 fi
.flags
= O_CREAT
| O_EXCL
| O_WRONLY
;
1305 err
= fuse_fs_create(f
->fs
, path
, mode
, &fi
);
1307 err
= lookup_path(f
, parent
, name
, path
, &e
, &fi
);
1308 fuse_fs_release(f
->fs
, path
, &fi
);
1311 if (err
== -ENOSYS
) {
1312 err
= fuse_fs_mknod(f
->fs
, path
, mode
, rdev
);
1314 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
1316 fuse_finish_interrupt(f
, req
, &d
);
1319 pthread_rwlock_unlock(&f
->tree_lock
);
1320 reply_entry(req
, &e
, err
);
1323 static void fuse_lib_mkdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
1326 struct fuse
*f
= req_fuse_prepare(req
);
1327 struct fuse_entry_param e
;
1332 pthread_rwlock_rdlock(&f
->tree_lock
);
1333 path
= get_path_name(f
, parent
, name
);
1335 struct fuse_intr_data d
;
1337 fprintf(stderr
, "MKDIR %s\n", path
);
1338 fuse_prepare_interrupt(f
, req
, &d
);
1339 err
= fuse_fs_mkdir(f
->fs
, path
, mode
);
1341 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
1342 fuse_finish_interrupt(f
, req
, &d
);
1345 pthread_rwlock_unlock(&f
->tree_lock
);
1346 reply_entry(req
, &e
, err
);
1349 static void fuse_lib_unlink(fuse_req_t req
, fuse_ino_t parent
,
1352 struct fuse
*f
= req_fuse_prepare(req
);
1357 pthread_rwlock_wrlock(&f
->tree_lock
);
1358 path
= get_path_name(f
, parent
, name
);
1360 struct fuse_intr_data d
;
1362 fprintf(stderr
, "UNLINK %s\n", path
);
1363 fuse_prepare_interrupt(f
, req
, &d
);
1364 if (!f
->conf
.hard_remove
&& is_open(f
, parent
, name
))
1365 err
= hide_node(f
, path
, parent
, name
);
1367 err
= fuse_fs_unlink(f
->fs
, path
);
1369 remove_node(f
, parent
, name
);
1371 fuse_finish_interrupt(f
, req
, &d
);
1374 pthread_rwlock_unlock(&f
->tree_lock
);
1375 reply_err(req
, err
);
1378 static void fuse_lib_rmdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
1380 struct fuse
*f
= req_fuse_prepare(req
);
1385 pthread_rwlock_wrlock(&f
->tree_lock
);
1386 path
= get_path_name(f
, parent
, name
);
1388 struct fuse_intr_data d
;
1390 fprintf(stderr
, "RMDIR %s\n", path
);
1391 fuse_prepare_interrupt(f
, req
, &d
);
1392 err
= fuse_fs_rmdir(f
->fs
, path
);
1393 fuse_finish_interrupt(f
, req
, &d
);
1395 remove_node(f
, parent
, name
);
1398 pthread_rwlock_unlock(&f
->tree_lock
);
1399 reply_err(req
, err
);
1402 static void fuse_lib_symlink(fuse_req_t req
, const char *linkname
,
1403 fuse_ino_t parent
, const char *name
)
1405 struct fuse
*f
= req_fuse_prepare(req
);
1406 struct fuse_entry_param e
;
1411 pthread_rwlock_rdlock(&f
->tree_lock
);
1412 path
= get_path_name(f
, parent
, name
);
1414 struct fuse_intr_data d
;
1416 fprintf(stderr
, "SYMLINK %s\n", path
);
1417 fuse_prepare_interrupt(f
, req
, &d
);
1418 err
= fuse_fs_symlink(f
->fs
, linkname
, path
);
1420 err
= lookup_path(f
, parent
, name
, path
, &e
, NULL
);
1421 fuse_finish_interrupt(f
, req
, &d
);
1424 pthread_rwlock_unlock(&f
->tree_lock
);
1425 reply_entry(req
, &e
, err
);
1428 static void fuse_lib_rename(fuse_req_t req
, fuse_ino_t olddir
,
1429 const char *oldname
, fuse_ino_t newdir
,
1430 const char *newname
)
1432 struct fuse
*f
= req_fuse_prepare(req
);
1438 pthread_rwlock_wrlock(&f
->tree_lock
);
1439 oldpath
= get_path_name(f
, olddir
, oldname
);
1440 if (oldpath
!= NULL
) {
1441 newpath
= get_path_name(f
, newdir
, newname
);
1442 if (newpath
!= NULL
) {
1443 struct fuse_intr_data d
;
1445 fprintf(stderr
, "RENAME %s -> %s\n", oldpath
, newpath
);
1447 fuse_prepare_interrupt(f
, req
, &d
);
1448 if (!f
->conf
.hard_remove
&& is_open(f
, newdir
, newname
))
1449 err
= hide_node(f
, newpath
, newdir
, newname
);
1451 err
= fuse_fs_rename(f
->fs
, oldpath
, newpath
);
1453 err
= rename_node(f
, olddir
, oldname
, newdir
, newname
, 0);
1455 fuse_finish_interrupt(f
, req
, &d
);
1460 pthread_rwlock_unlock(&f
->tree_lock
);
1461 reply_err(req
, err
);
1464 static void fuse_lib_link(fuse_req_t req
, fuse_ino_t ino
, fuse_ino_t newparent
,
1465 const char *newname
)
1467 struct fuse
*f
= req_fuse_prepare(req
);
1468 struct fuse_entry_param e
;
1474 pthread_rwlock_rdlock(&f
->tree_lock
);
1475 oldpath
= get_path(f
, ino
);
1476 if (oldpath
!= NULL
) {
1477 newpath
= get_path_name(f
, newparent
, newname
);
1478 if (newpath
!= NULL
) {
1479 struct fuse_intr_data d
;
1481 fprintf(stderr
, "LINK %s\n", newpath
);
1482 fuse_prepare_interrupt(f
, req
, &d
);
1483 err
= fuse_fs_link(f
->fs
, oldpath
, newpath
);
1485 err
= lookup_path(f
, newparent
, newname
, newpath
, &e
, NULL
);
1486 fuse_finish_interrupt(f
, req
, &d
);
1491 pthread_rwlock_unlock(&f
->tree_lock
);
1492 reply_entry(req
, &e
, err
);
1495 static void fuse_do_release(struct fuse
*f
, fuse_ino_t ino
, const char *path
,
1496 struct fuse_file_info
*fi
)
1499 int unlink_hidden
= 0;
1501 fuse_fs_release(f
->fs
, path
? path
: "-", fi
);
1503 pthread_mutex_lock(&f
->lock
);
1504 node
= get_node(f
, ino
);
1505 assert(node
->open_count
> 0);
1507 if (node
->is_hidden
&& !node
->open_count
) {
1509 node
->is_hidden
= 0;
1511 pthread_mutex_unlock(&f
->lock
);
1513 if(unlink_hidden
&& path
)
1514 fuse_fs_unlink(f
->fs
, path
);
1517 static void fuse_lib_create(fuse_req_t req
, fuse_ino_t parent
,
1518 const char *name
, mode_t mode
,
1519 struct fuse_file_info
*fi
)
1521 struct fuse
*f
= req_fuse_prepare(req
);
1522 struct fuse_intr_data d
;
1523 struct fuse_entry_param e
;
1528 pthread_rwlock_rdlock(&f
->tree_lock
);
1529 path
= get_path_name(f
, parent
, name
);
1531 fuse_prepare_interrupt(f
, req
, &d
);
1532 err
= fuse_fs_create(f
->fs
, path
, mode
, fi
);
1534 err
= lookup_path(f
, parent
, name
, path
, &e
, fi
);
1536 fuse_fs_release(f
->fs
, path
, fi
);
1537 else if (!S_ISREG(e
.attr
.st_mode
)) {
1539 fuse_fs_release(f
->fs
, path
, fi
);
1540 forget_node(f
, e
.ino
, 1);
1542 if (f
->conf
.direct_io
)
1544 if (f
->conf
.kernel_cache
)
1549 fuse_finish_interrupt(f
, req
, &d
);
1552 pthread_mutex_lock(&f
->lock
);
1553 get_node(f
, e
.ino
)->open_count
++;
1554 pthread_mutex_unlock(&f
->lock
);
1555 if (fuse_reply_create(req
, &e
, fi
) == -ENOENT
) {
1556 /* The open syscall was interrupted, so it must be cancelled */
1557 fuse_prepare_interrupt(f
, req
, &d
);
1558 fuse_do_release(f
, e
.ino
, path
, fi
);
1559 fuse_finish_interrupt(f
, req
, &d
);
1560 forget_node(f
, e
.ino
, 1);
1561 } else if (f
->conf
.debug
) {
1562 fprintf(stderr
, " CREATE[%llu] flags: 0x%x %s\n",
1563 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1566 reply_err(req
, err
);
1571 pthread_rwlock_unlock(&f
->tree_lock
);
1574 static void fuse_lib_open(fuse_req_t req
, fuse_ino_t ino
,
1575 struct fuse_file_info
*fi
)
1577 struct fuse
*f
= req_fuse_prepare(req
);
1578 struct fuse_intr_data d
;
1583 pthread_rwlock_rdlock(&f
->tree_lock
);
1584 path
= get_path(f
, ino
);
1586 fuse_prepare_interrupt(f
, req
, &d
);
1587 err
= fuse_fs_open(f
->fs
, path
, fi
);
1589 if (f
->conf
.direct_io
)
1591 if (f
->conf
.kernel_cache
)
1594 fuse_finish_interrupt(f
, req
, &d
);
1597 pthread_mutex_lock(&f
->lock
);
1598 get_node(f
, ino
)->open_count
++;
1599 pthread_mutex_unlock(&f
->lock
);
1600 if (fuse_reply_open(req
, fi
) == -ENOENT
) {
1601 /* The open syscall was interrupted, so it must be cancelled */
1602 fuse_prepare_interrupt(f
, req
, &d
);
1603 fuse_do_release(f
, ino
, path
, fi
);
1604 fuse_finish_interrupt(f
, req
, &d
);
1605 } else if (f
->conf
.debug
) {
1606 fprintf(stderr
, "OPEN[%llu] flags: 0x%x %s\n",
1607 (unsigned long long) fi
->fh
, fi
->flags
, path
);
1610 reply_err(req
, err
);
1614 pthread_rwlock_unlock(&f
->tree_lock
);
1617 static void fuse_lib_read(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
1618 off_t off
, struct fuse_file_info
*fi
)
1620 struct fuse
*f
= req_fuse_prepare(req
);
1625 buf
= (char *) malloc(size
);
1627 reply_err(req
, -ENOMEM
);
1632 pthread_rwlock_rdlock(&f
->tree_lock
);
1633 path
= get_path(f
, ino
);
1635 struct fuse_intr_data d
;
1637 fprintf(stderr
, "READ[%llu] %lu bytes from %llu\n",
1638 (unsigned long long) fi
->fh
, (unsigned long) size
,
1639 (unsigned long long) off
);
1641 fuse_prepare_interrupt(f
, req
, &d
);
1642 res
= fuse_fs_read(f
->fs
, path
, buf
, size
, off
, fi
);
1643 fuse_finish_interrupt(f
, req
, &d
);
1646 pthread_rwlock_unlock(&f
->tree_lock
);
1650 fprintf(stderr
, " READ[%llu] %u bytes\n",
1651 (unsigned long long)fi
->fh
, res
);
1652 if ((size_t) res
> size
)
1653 fprintf(stderr
, "fuse: read too many bytes");
1654 fuse_reply_buf(req
, buf
, res
);
1656 reply_err(req
, res
);
1661 static void fuse_lib_write(fuse_req_t req
, fuse_ino_t ino
, const char *buf
,
1662 size_t size
, off_t off
, struct fuse_file_info
*fi
)
1664 struct fuse
*f
= req_fuse_prepare(req
);
1669 pthread_rwlock_rdlock(&f
->tree_lock
);
1670 path
= get_path(f
, ino
);
1672 struct fuse_intr_data d
;
1674 fprintf(stderr
, "WRITE%s[%llu] %lu bytes to %llu\n",
1675 fi
->writepage
? "PAGE" : "", (unsigned long long) fi
->fh
,
1676 (unsigned long) size
, (unsigned long long) off
);
1678 fuse_prepare_interrupt(f
, req
, &d
);
1679 res
= fuse_fs_write(f
->fs
, path
, buf
, size
, off
, fi
);
1680 fuse_finish_interrupt(f
, req
, &d
);
1683 pthread_rwlock_unlock(&f
->tree_lock
);
1687 fprintf(stderr
, " WRITE%s[%llu] %u bytes\n",
1688 fi
->writepage
? "PAGE" : "", (unsigned long long) fi
->fh
,
1690 if ((size_t) res
> size
)
1691 fprintf(stderr
, "fuse: wrote too many bytes");
1692 fuse_reply_write(req
, res
);
1694 reply_err(req
, res
);
1697 static void fuse_lib_fsync(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
1698 struct fuse_file_info
*fi
)
1700 struct fuse
*f
= req_fuse_prepare(req
);
1705 pthread_rwlock_rdlock(&f
->tree_lock
);
1706 path
= get_path(f
, ino
);
1708 struct fuse_intr_data d
;
1710 fprintf(stderr
, "FSYNC[%llu]\n", (unsigned long long) fi
->fh
);
1711 fuse_prepare_interrupt(f
, req
, &d
);
1712 err
= fuse_fs_fsync(f
->fs
, path
, datasync
, fi
);
1713 fuse_finish_interrupt(f
, req
, &d
);
1716 pthread_rwlock_unlock(&f
->tree_lock
);
1717 reply_err(req
, err
);
1720 static struct fuse_dh
*get_dirhandle(const struct fuse_file_info
*llfi
,
1721 struct fuse_file_info
*fi
)
1723 struct fuse_dh
*dh
= (struct fuse_dh
*) (uintptr_t) llfi
->fh
;
1724 memset(fi
, 0, sizeof(struct fuse_file_info
));
1726 fi
->fh_old
= dh
->fh
;
1730 static void fuse_lib_opendir(fuse_req_t req
, fuse_ino_t ino
,
1731 struct fuse_file_info
*llfi
)
1733 struct fuse
*f
= req_fuse_prepare(req
);
1734 struct fuse_intr_data d
;
1736 struct fuse_file_info fi
;
1740 dh
= (struct fuse_dh
*) malloc(sizeof(struct fuse_dh
));
1742 reply_err(req
, -ENOMEM
);
1745 memset(dh
, 0, sizeof(struct fuse_dh
));
1747 dh
->contents
= NULL
;
1751 fuse_mutex_init(&dh
->lock
);
1753 llfi
->fh
= (uintptr_t) dh
;
1755 memset(&fi
, 0, sizeof(fi
));
1756 fi
.flags
= llfi
->flags
;
1759 pthread_rwlock_rdlock(&f
->tree_lock
);
1760 path
= get_path(f
, ino
);
1762 fuse_prepare_interrupt(f
, req
, &d
);
1763 err
= fuse_fs_opendir(f
->fs
, path
, &fi
);
1764 fuse_finish_interrupt(f
, req
, &d
);
1768 if (fuse_reply_open(req
, llfi
) == -ENOENT
) {
1769 /* The opendir syscall was interrupted, so it must be cancelled */
1770 fuse_prepare_interrupt(f
, req
, &d
);
1771 fuse_fs_releasedir(f
->fs
, path
, &fi
);
1772 fuse_finish_interrupt(f
, req
, &d
);
1773 pthread_mutex_destroy(&dh
->lock
);
1777 reply_err(req
, err
);
1778 pthread_mutex_destroy(&dh
->lock
);
1782 pthread_rwlock_unlock(&f
->tree_lock
);
1785 static int extend_contents(struct fuse_dh
*dh
, unsigned minsize
)
1787 if (minsize
> dh
->size
) {
1789 unsigned newsize
= dh
->size
;
1792 while (newsize
< minsize
) {
1793 if (newsize
>= 0x80000000)
1794 newsize
= 0xffffffff;
1799 newptr
= (char *) realloc(dh
->contents
, newsize
);
1801 dh
->error
= -ENOMEM
;
1804 dh
->contents
= newptr
;
1810 static int fill_dir(void *dh_
, const char *name
, const struct stat
*statp
,
1813 struct fuse_dh
*dh
= (struct fuse_dh
*) dh_
;
1820 memset(&stbuf
, 0, sizeof(stbuf
));
1821 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
1824 if (!dh
->fuse
->conf
.use_ino
) {
1825 stbuf
.st_ino
= FUSE_UNKNOWN_INO
;
1826 if (dh
->fuse
->conf
.readdir_ino
) {
1828 pthread_mutex_lock(&dh
->fuse
->lock
);
1829 node
= lookup_node(dh
->fuse
, dh
->nodeid
, name
);
1831 stbuf
.st_ino
= (ino_t
) node
->nodeid
;
1832 pthread_mutex_unlock(&dh
->fuse
->lock
);
1837 if (extend_contents(dh
, dh
->needlen
) == -1)
1841 newlen
= dh
->len
+ fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
,
1842 dh
->needlen
- dh
->len
, name
,
1844 if (newlen
> dh
->needlen
)
1847 newlen
= dh
->len
+ fuse_add_direntry(dh
->req
, NULL
, 0, name
, NULL
, 0);
1848 if (extend_contents(dh
, newlen
) == -1)
1851 fuse_add_direntry(dh
->req
, dh
->contents
+ dh
->len
, dh
->size
- dh
->len
,
1852 name
, &stbuf
, newlen
);
1858 static int readdir_fill(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
1859 size_t size
, off_t off
, struct fuse_dh
*dh
,
1860 struct fuse_file_info
*fi
)
1864 pthread_rwlock_rdlock(&f
->tree_lock
);
1865 path
= get_path(f
, ino
);
1867 struct fuse_intr_data d
;
1874 fuse_prepare_interrupt(f
, req
, &d
);
1875 err
= fuse_fs_readdir(f
->fs
, path
, dh
, fill_dir
, off
, fi
);
1876 fuse_finish_interrupt(f
, req
, &d
);
1884 pthread_rwlock_unlock(&f
->tree_lock
);
1888 static void fuse_lib_readdir(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
1889 off_t off
, struct fuse_file_info
*llfi
)
1891 struct fuse
*f
= req_fuse_prepare(req
);
1892 struct fuse_file_info fi
;
1893 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
1895 pthread_mutex_lock(&dh
->lock
);
1896 /* According to SUS, directory contents need to be refreshed on
1902 int err
= readdir_fill(f
, req
, ino
, size
, off
, dh
, &fi
);
1904 reply_err(req
, err
);
1909 if (off
< dh
->len
) {
1910 if (off
+ size
> dh
->len
)
1911 size
= dh
->len
- off
;
1918 fuse_reply_buf(req
, dh
->contents
+ off
, size
);
1920 pthread_mutex_unlock(&dh
->lock
);
1923 static void fuse_lib_releasedir(fuse_req_t req
, fuse_ino_t ino
,
1924 struct fuse_file_info
*llfi
)
1926 struct fuse
*f
= req_fuse_prepare(req
);
1927 struct fuse_intr_data d
;
1928 struct fuse_file_info fi
;
1929 struct fuse_dh
*dh
= get_dirhandle(llfi
, &fi
);
1932 pthread_rwlock_rdlock(&f
->tree_lock
);
1933 path
= get_path(f
, ino
);
1934 fuse_prepare_interrupt(f
, req
, &d
);
1935 fuse_fs_releasedir(f
->fs
, path
? path
: "-", &fi
);
1936 fuse_finish_interrupt(f
, req
, &d
);
1939 pthread_rwlock_unlock(&f
->tree_lock
);
1940 pthread_mutex_lock(&dh
->lock
);
1941 pthread_mutex_unlock(&dh
->lock
);
1942 pthread_mutex_destroy(&dh
->lock
);
1948 static void fuse_lib_fsyncdir(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
1949 struct fuse_file_info
*llfi
)
1951 struct fuse
*f
= req_fuse_prepare(req
);
1952 struct fuse_file_info fi
;
1956 get_dirhandle(llfi
, &fi
);
1959 pthread_rwlock_rdlock(&f
->tree_lock
);
1960 path
= get_path(f
, ino
);
1962 struct fuse_intr_data d
;
1963 fuse_prepare_interrupt(f
, req
, &d
);
1964 err
= fuse_fs_fsyncdir(f
->fs
, path
, datasync
, &fi
);
1965 fuse_finish_interrupt(f
, req
, &d
);
1968 pthread_rwlock_unlock(&f
->tree_lock
);
1969 reply_err(req
, err
);
1972 static void fuse_lib_statfs(fuse_req_t req
, fuse_ino_t ino
)
1974 struct fuse
*f
= req_fuse_prepare(req
);
1979 memset(&buf
, 0, sizeof(buf
));
1980 pthread_rwlock_rdlock(&f
->tree_lock
);
1986 path
= get_path(f
, ino
);
1989 struct fuse_intr_data d
;
1990 fuse_prepare_interrupt(f
, req
, &d
);
1991 err
= fuse_fs_statfs(f
->fs
, path
, &buf
);
1992 fuse_finish_interrupt(f
, req
, &d
);
1995 pthread_rwlock_unlock(&f
->tree_lock
);
1998 fuse_reply_statfs(req
, &buf
);
2000 reply_err(req
, err
);
2003 static void fuse_lib_setxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
2004 const char *value
, size_t size
, int flags
)
2006 struct fuse
*f
= req_fuse_prepare(req
);
2011 pthread_rwlock_rdlock(&f
->tree_lock
);
2012 path
= get_path(f
, ino
);
2014 struct fuse_intr_data d
;
2015 fuse_prepare_interrupt(f
, req
, &d
);
2016 err
= fuse_fs_setxattr(f
->fs
, path
, name
, value
, size
, flags
);
2017 fuse_finish_interrupt(f
, req
, &d
);
2020 pthread_rwlock_unlock(&f
->tree_lock
);
2021 reply_err(req
, err
);
2024 static int common_getxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
2025 const char *name
, char *value
, size_t size
)
2031 pthread_rwlock_rdlock(&f
->tree_lock
);
2032 path
= get_path(f
, ino
);
2034 struct fuse_intr_data d
;
2035 fuse_prepare_interrupt(f
, req
, &d
);
2036 err
= fuse_fs_getxattr(f
->fs
, path
, name
, value
, size
);
2037 fuse_finish_interrupt(f
, req
, &d
);
2040 pthread_rwlock_unlock(&f
->tree_lock
);
2044 static void fuse_lib_getxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
2047 struct fuse
*f
= req_fuse_prepare(req
);
2051 char *value
= (char *) malloc(size
);
2052 if (value
== NULL
) {
2053 reply_err(req
, -ENOMEM
);
2056 res
= common_getxattr(f
, req
, ino
, name
, value
, size
);
2058 fuse_reply_buf(req
, value
, res
);
2060 reply_err(req
, res
);
2063 res
= common_getxattr(f
, req
, ino
, name
, NULL
, 0);
2065 fuse_reply_xattr(req
, res
);
2067 reply_err(req
, res
);
2071 static int common_listxattr(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
2072 char *list
, size_t size
)
2078 pthread_rwlock_rdlock(&f
->tree_lock
);
2079 path
= get_path(f
, ino
);
2081 struct fuse_intr_data d
;
2082 fuse_prepare_interrupt(f
, req
, &d
);
2083 err
= fuse_fs_listxattr(f
->fs
, path
, list
, size
);
2084 fuse_finish_interrupt(f
, req
, &d
);
2087 pthread_rwlock_unlock(&f
->tree_lock
);
2091 static void fuse_lib_listxattr(fuse_req_t req
, fuse_ino_t ino
, size_t size
)
2093 struct fuse
*f
= req_fuse_prepare(req
);
2097 char *list
= (char *) malloc(size
);
2099 reply_err(req
, -ENOMEM
);
2102 res
= common_listxattr(f
, req
, ino
, list
, size
);
2104 fuse_reply_buf(req
, list
, res
);
2106 reply_err(req
, res
);
2109 res
= common_listxattr(f
, req
, ino
, NULL
, 0);
2111 fuse_reply_xattr(req
, res
);
2113 reply_err(req
, res
);
2117 static void fuse_lib_removexattr(fuse_req_t req
, fuse_ino_t ino
,
2120 struct fuse
*f
= req_fuse_prepare(req
);
2125 pthread_rwlock_rdlock(&f
->tree_lock
);
2126 path
= get_path(f
, ino
);
2128 struct fuse_intr_data d
;
2129 fuse_prepare_interrupt(f
, req
, &d
);
2130 err
= fuse_fs_removexattr(f
->fs
, path
, name
);
2131 fuse_finish_interrupt(f
, req
, &d
);
2134 pthread_rwlock_unlock(&f
->tree_lock
);
2135 reply_err(req
, err
);
2138 static struct lock
*locks_conflict(struct node
*node
, const struct lock
*lock
)
2142 for (l
= node
->locks
; l
; l
= l
->next
)
2143 if (l
->owner
!= lock
->owner
&&
2144 lock
->start
<= l
->end
&& l
->start
<= lock
->end
&&
2145 (l
->type
== F_WRLCK
|| lock
->type
== F_WRLCK
))
2151 static void delete_lock(struct lock
**lockp
)
2153 struct lock
*l
= *lockp
;
2158 static void insert_lock(struct lock
**pos
, struct lock
*lock
)
2164 static int locks_insert(struct node
*node
, struct lock
*lock
)
2167 struct lock
*newl1
= NULL
;
2168 struct lock
*newl2
= NULL
;
2170 if (lock
->type
!= F_UNLCK
|| lock
->start
!= 0 || lock
->end
!= OFFSET_MAX
) {
2171 newl1
= malloc(sizeof(struct lock
));
2172 newl2
= malloc(sizeof(struct lock
));
2174 if (!newl1
|| !newl2
) {
2181 for (lp
= &node
->locks
; *lp
;) {
2182 struct lock
*l
= *lp
;
2183 if (l
->owner
!= lock
->owner
)
2186 if (lock
->type
== l
->type
) {
2187 if (l
->end
< lock
->start
- 1)
2189 if (lock
->end
< l
->start
- 1)
2191 if (l
->start
<= lock
->start
&& lock
->end
<= l
->end
)
2193 if (l
->start
< lock
->start
)
2194 lock
->start
= l
->start
;
2195 if (lock
->end
< l
->end
)
2199 if (l
->end
< lock
->start
)
2201 if (lock
->end
< l
->start
)
2203 if (lock
->start
<= l
->start
&& l
->end
<= lock
->end
)
2205 if (l
->end
<= lock
->end
) {
2206 l
->end
= lock
->start
- 1;
2209 if (lock
->start
<= l
->start
) {
2210 l
->start
= lock
->end
+ 1;
2214 newl2
->start
= lock
->end
+ 1;
2215 l
->end
= lock
->start
- 1;
2216 insert_lock(&l
->next
, newl2
);
2226 if (lock
->type
!= F_UNLCK
) {
2228 insert_lock(lp
, newl1
);
2237 static void flock_to_lock(struct flock
*flock
, struct lock
*lock
)
2239 memset(lock
, 0, sizeof(struct lock
));
2240 lock
->type
= flock
->l_type
;
2241 lock
->start
= flock
->l_start
;
2242 lock
->end
= flock
->l_len
? flock
->l_start
+ flock
->l_len
- 1 : OFFSET_MAX
;
2243 lock
->pid
= flock
->l_pid
;
2246 static void lock_to_flock(struct lock
*lock
, struct flock
*flock
)
2248 flock
->l_type
= lock
->type
;
2249 flock
->l_start
= lock
->start
;
2250 flock
->l_len
= (lock
->end
== OFFSET_MAX
) ? 0 : lock
->end
- lock
->start
+ 1;
2251 flock
->l_pid
= lock
->pid
;
2254 static int fuse_flush_common(struct fuse
*f
, fuse_req_t req
, fuse_ino_t ino
,
2255 const char *path
, struct fuse_file_info
*fi
)
2257 struct fuse_intr_data d
;
2263 fuse_prepare_interrupt(f
, req
, &d
);
2264 memset(&lock
, 0, sizeof(lock
));
2265 lock
.l_type
= F_UNLCK
;
2266 lock
.l_whence
= SEEK_SET
;
2267 err
= fuse_fs_flush(f
->fs
, path
, fi
);
2268 errlock
= fuse_fs_lock(f
->fs
, path
, fi
, F_SETLK
, &lock
);
2269 fuse_finish_interrupt(f
, req
, &d
);
2271 if (errlock
!= -ENOSYS
) {
2272 flock_to_lock(&lock
, &l
);
2273 l
.owner
= fi
->lock_owner
;
2274 pthread_mutex_lock(&f
->lock
);
2275 locks_insert(get_node(f
, ino
), &l
);
2276 pthread_mutex_unlock(&f
->lock
);
2278 /* if op.lock() is defined FLUSH is needed regardless of op.flush() */
2285 static void fuse_lib_release(fuse_req_t req
, fuse_ino_t ino
,
2286 struct fuse_file_info
*fi
)
2288 struct fuse
*f
= req_fuse_prepare(req
);
2289 struct fuse_intr_data d
;
2293 pthread_rwlock_rdlock(&f
->tree_lock
);
2294 path
= get_path(f
, ino
);
2296 fprintf(stderr
, "RELEASE%s[%llu] flags: 0x%x\n",
2297 fi
->flush
? "+FLUSH" : "",
2298 (unsigned long long) fi
->fh
, fi
->flags
);
2301 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
2306 fuse_prepare_interrupt(f
, req
, &d
);
2307 fuse_do_release(f
, ino
, path
, fi
);
2308 fuse_finish_interrupt(f
, req
, &d
);
2310 pthread_rwlock_unlock(&f
->tree_lock
);
2312 reply_err(req
, err
);
2315 static void fuse_lib_flush(fuse_req_t req
, fuse_ino_t ino
,
2316 struct fuse_file_info
*fi
)
2318 struct fuse
*f
= req_fuse_prepare(req
);
2322 pthread_rwlock_rdlock(&f
->tree_lock
);
2323 path
= get_path(f
, ino
);
2324 if (path
&& f
->conf
.debug
)
2325 fprintf(stderr
, "FLUSH[%llu]\n", (unsigned long long) fi
->fh
);
2326 err
= fuse_flush_common(f
, req
, ino
, path
, fi
);
2328 pthread_rwlock_unlock(&f
->tree_lock
);
2329 reply_err(req
, err
);
2332 static int fuse_lock_common(fuse_req_t req
, fuse_ino_t ino
,
2333 struct fuse_file_info
*fi
, struct flock
*lock
,
2336 struct fuse
*f
= req_fuse_prepare(req
);
2341 pthread_rwlock_rdlock(&f
->tree_lock
);
2342 path
= get_path(f
, ino
);
2344 struct fuse_intr_data d
;
2345 fuse_prepare_interrupt(f
, req
, &d
);
2346 err
= fuse_fs_lock(f
->fs
, path
, fi
, cmd
, lock
);
2347 fuse_finish_interrupt(f
, req
, &d
);
2350 pthread_rwlock_unlock(&f
->tree_lock
);
2354 static void fuse_lib_getlk(fuse_req_t req
, fuse_ino_t ino
,
2355 struct fuse_file_info
*fi
, struct flock
*lock
)
2359 struct lock
*conflict
;
2360 struct fuse
*f
= req_fuse(req
);
2362 flock_to_lock(lock
, &l
);
2363 l
.owner
= fi
->lock_owner
;
2364 pthread_mutex_lock(&f
->lock
);
2365 conflict
= locks_conflict(get_node(f
, ino
), &l
);
2367 lock_to_flock(conflict
, lock
);
2368 pthread_mutex_unlock(&f
->lock
);
2370 err
= fuse_lock_common(req
, ino
, fi
, lock
, F_GETLK
);
2375 fuse_reply_lock(req
, lock
);
2377 reply_err(req
, err
);
2380 static void fuse_lib_setlk(fuse_req_t req
, fuse_ino_t ino
,
2381 struct fuse_file_info
*fi
, struct flock
*lock
,
2384 int err
= fuse_lock_common(req
, ino
, fi
, lock
, should_sleep
? F_SETLKW
: F_SETLK
);
2386 struct fuse
*f
= req_fuse(req
);
2388 flock_to_lock(lock
, &l
);
2389 l
.owner
= fi
->lock_owner
;
2390 pthread_mutex_lock(&f
->lock
);
2391 locks_insert(get_node(f
, ino
), &l
);
2392 pthread_mutex_unlock(&f
->lock
);
2394 reply_err(req
, err
);
2397 static void fuse_lib_bmap(fuse_req_t req
, fuse_ino_t ino
, size_t blocksize
,
2400 struct fuse
*f
= req_fuse_prepare(req
);
2401 struct fuse_intr_data d
;
2406 pthread_rwlock_rdlock(&f
->tree_lock
);
2407 path
= get_path(f
, ino
);
2409 fuse_prepare_interrupt(f
, req
, &d
);
2410 err
= fuse_fs_bmap(f
->fs
, path
, blocksize
, &idx
);
2411 fuse_finish_interrupt(f
, req
, &d
);
2414 pthread_rwlock_unlock(&f
->tree_lock
);
2416 fuse_reply_bmap(req
, idx
);
2418 reply_err(req
, err
);
2421 static struct fuse_lowlevel_ops fuse_path_ops
= {
2422 .init
= fuse_lib_init
,
2423 .destroy
= fuse_lib_destroy
,
2424 .lookup
= fuse_lib_lookup
,
2425 .forget
= fuse_lib_forget
,
2426 .getattr
= fuse_lib_getattr
,
2427 .setattr
= fuse_lib_setattr
,
2428 .access
= fuse_lib_access
,
2429 .readlink
= fuse_lib_readlink
,
2430 .mknod
= fuse_lib_mknod
,
2431 .mkdir
= fuse_lib_mkdir
,
2432 .unlink
= fuse_lib_unlink
,
2433 .rmdir
= fuse_lib_rmdir
,
2434 .symlink
= fuse_lib_symlink
,
2435 .rename
= fuse_lib_rename
,
2436 .link
= fuse_lib_link
,
2437 .create
= fuse_lib_create
,
2438 .open
= fuse_lib_open
,
2439 .read
= fuse_lib_read
,
2440 .write
= fuse_lib_write
,
2441 .flush
= fuse_lib_flush
,
2442 .release
= fuse_lib_release
,
2443 .fsync
= fuse_lib_fsync
,
2444 .opendir
= fuse_lib_opendir
,
2445 .readdir
= fuse_lib_readdir
,
2446 .releasedir
= fuse_lib_releasedir
,
2447 .fsyncdir
= fuse_lib_fsyncdir
,
2448 .statfs
= fuse_lib_statfs
,
2449 .setxattr
= fuse_lib_setxattr
,
2450 .getxattr
= fuse_lib_getxattr
,
2451 .listxattr
= fuse_lib_listxattr
,
2452 .removexattr
= fuse_lib_removexattr
,
2453 .getlk
= fuse_lib_getlk
,
2454 .setlk
= fuse_lib_setlk
,
2455 .bmap
= fuse_lib_bmap
,
2458 struct fuse_session
*fuse_get_session(struct fuse
*f
)
2463 int fuse_loop(struct fuse
*f
)
2466 return fuse_session_loop(f
->se
);
2471 void fuse_exit(struct fuse
*f
)
2473 fuse_session_exit(f
->se
);
2476 struct fuse_context
*fuse_get_context(void)
2478 return &fuse_get_context_internal()->ctx
;
2481 int fuse_interrupted(void)
2483 return fuse_req_interrupted(fuse_get_context_internal()->req
);
2490 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
2492 static const struct fuse_opt fuse_lib_opts
[] = {
2493 FUSE_OPT_KEY("-h", KEY_HELP
),
2494 FUSE_OPT_KEY("--help", KEY_HELP
),
2495 FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP
),
2496 FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP
),
2497 FUSE_LIB_OPT("debug", debug
, 1),
2498 FUSE_LIB_OPT("-d", debug
, 1),
2499 FUSE_LIB_OPT("hard_remove", hard_remove
, 1),
2500 FUSE_LIB_OPT("use_ino", use_ino
, 1),
2501 FUSE_LIB_OPT("readdir_ino", readdir_ino
, 1),
2502 FUSE_LIB_OPT("direct_io", direct_io
, 1),
2503 FUSE_LIB_OPT("kernel_cache", kernel_cache
, 1),
2504 FUSE_LIB_OPT("umask=", set_mode
, 1),
2505 FUSE_LIB_OPT("umask=%o", umask
, 0),
2506 FUSE_LIB_OPT("uid=", set_uid
, 1),
2507 FUSE_LIB_OPT("uid=%d", uid
, 0),
2508 FUSE_LIB_OPT("gid=", set_gid
, 1),
2509 FUSE_LIB_OPT("gid=%d", gid
, 0),
2510 FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout
, 0),
2511 FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout
, 0),
2512 FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout
, 0),
2513 FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set
, 1),
2514 FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout
, 0),
2515 FUSE_LIB_OPT("intr", intr
, 1),
2516 FUSE_LIB_OPT("intr_signal=%d", intr_signal
, 0),
2520 static void fuse_lib_help(void)
2523 " -o hard_remove immediate removal (don't hide files)\n"
2524 " -o use_ino let filesystem set inode numbers\n"
2525 " -o readdir_ino try to fill in d_ino in readdir\n"
2526 " -o direct_io use direct I/O\n"
2527 " -o kernel_cache cache files in kernel\n"
2528 " -o umask=M set file permissions (octal)\n"
2529 " -o uid=N set file owner\n"
2530 " -o gid=N set file group\n"
2531 " -o entry_timeout=T cache timeout for names (1.0s)\n"
2532 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
2533 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
2534 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
2535 " -o intr allow requests to be interrupted\n"
2536 " -o intr_signal=NUM signal to send on interrupt (%i)\n"
2537 "\n", FUSE_DEFAULT_INTR_SIGNAL
);
2540 static int fuse_lib_opt_proc(void *data
, const char *arg
, int key
,
2541 struct fuse_args
*outargs
)
2543 (void) arg
; (void) outargs
;
2545 if (key
== KEY_HELP
) {
2546 struct fuse_config
*conf
= (struct fuse_config
*) data
;
2554 static int fuse_init_intr_signal(int signum
, int *installed
)
2556 struct sigaction old_sa
;
2558 if (sigaction(signum
, NULL
, &old_sa
) == -1) {
2559 perror("fuse: cannot get old signal handler");
2563 if (old_sa
.sa_handler
== SIG_DFL
) {
2564 struct sigaction sa
;
2566 memset(&sa
, 0, sizeof(struct sigaction
));
2567 sa
.sa_handler
= fuse_intr_sighandler
;
2568 sigemptyset(&sa
.sa_mask
);
2570 if (sigaction(signum
, &sa
, NULL
) == -1) {
2571 perror("fuse: cannot set interrupt signal handler");
2579 static void fuse_restore_intr_signal(int signum
)
2581 struct sigaction sa
;
2583 memset(&sa
, 0, sizeof(struct sigaction
));
2584 sa
.sa_handler
= SIG_DFL
;
2585 sigaction(signum
, &sa
, NULL
);
2588 struct fuse_fs
*fuse_fs_new(const struct fuse_operations
*op
, size_t op_size
,
2593 if (sizeof(struct fuse_operations
) < op_size
) {
2594 fprintf(stderr
, "fuse: warning: library too old, some operations may not not work\n");
2595 op_size
= sizeof(struct fuse_operations
);
2598 fs
= (struct fuse_fs
*) calloc(1, sizeof(struct fuse_fs
));
2600 fprintf(stderr
, "fuse: failed to allocate fuse_fs object\n");
2604 fs
->user_data
= user_data
;
2606 memcpy(&fs
->op
, op
, op_size
);
2610 struct fuse
*fuse_new(struct fuse_chan
*ch
, struct fuse_args
*args
,
2611 const struct fuse_operations
*op
, size_t op_size
,
2617 struct fuse_lowlevel_ops llop
= fuse_path_ops
;
2619 if (fuse_create_context_key() == -1)
2622 f
= (struct fuse
*) calloc(1, sizeof(struct fuse
));
2624 fprintf(stderr
, "fuse: failed to allocate fuse object\n");
2625 goto out_delete_context_key
;
2628 fs
= fuse_fs_new(op
, op_size
, user_data
);
2633 f
->utime_omit_ok
= fs
->op
.flag_utime_omit_ok
;
2635 /* Oh f**k, this is ugly! */
2641 f
->conf
.entry_timeout
= 1.0;
2642 f
->conf
.attr_timeout
= 1.0;
2643 f
->conf
.negative_timeout
= 0.0;
2644 f
->conf
.intr_signal
= FUSE_DEFAULT_INTR_SIGNAL
;
2646 if (fuse_opt_parse(args
, &f
->conf
, fuse_lib_opts
, fuse_lib_opt_proc
) == -1)
2649 if (!f
->conf
.ac_attr_timeout_set
)
2650 f
->conf
.ac_attr_timeout
= f
->conf
.attr_timeout
;
2654 * In FreeBSD, we always use these settings as inode numbers are needed to
2655 * make getcwd(3) work.
2657 f
->conf
.readdir_ino
= 1;
2660 f
->se
= fuse_lowlevel_new(args
, &llop
, sizeof(llop
), f
);
2661 if (f
->se
== NULL
) {
2665 fuse_session_add_chan(f
->se
, ch
);
2668 fprintf(stderr
, "utime_omit_ok: %i\n", f
->utime_omit_ok
);
2671 /* FIXME: Dynamic hash table */
2672 f
->name_table_size
= 14057;
2673 f
->name_table
= (struct node
**)
2674 calloc(1, sizeof(struct node
*) * f
->name_table_size
);
2675 if (f
->name_table
== NULL
) {
2676 fprintf(stderr
, "fuse: memory allocation failed\n");
2677 goto out_free_session
;
2680 f
->id_table_size
= 14057;
2681 f
->id_table
= (struct node
**)
2682 calloc(1, sizeof(struct node
*) * f
->id_table_size
);
2683 if (f
->id_table
== NULL
) {
2684 fprintf(stderr
, "fuse: memory allocation failed\n");
2685 goto out_free_name_table
;
2688 fuse_mutex_init(&f
->lock
);
2689 pthread_rwlock_init(&f
->tree_lock
, NULL
);
2691 root
= (struct node
*) calloc(1, sizeof(struct node
));
2693 fprintf(stderr
, "fuse: memory allocation failed\n");
2694 goto out_free_id_table
;
2697 root
->name
= strdup("/");
2698 if (root
->name
== NULL
) {
2699 fprintf(stderr
, "fuse: memory allocation failed\n");
2704 fuse_init_intr_signal(f
->conf
.intr_signal
, &f
->intr_installed
) == -1)
2705 goto out_free_root_name
;
2707 root
->parent
= NULL
;
2708 root
->nodeid
= FUSE_ROOT_ID
;
2709 root
->generation
= 0;
2722 out_free_name_table
:
2723 free(f
->name_table
);
2725 fuse_session_destroy(f
->se
);
2727 /* Horrible compatibility hack to stop the destructor from being
2728 called on the filesystem without init being called first */
2729 fs
->op
.destroy
= NULL
;
2730 fuse_fs_destroy(f
->fs
);
2733 out_delete_context_key
:
2734 fuse_delete_context_key();
2739 void fuse_destroy(struct fuse
*f
)
2743 if (f
->conf
.intr
&& f
->intr_installed
)
2744 fuse_restore_intr_signal(f
->conf
.intr_signal
);
2747 struct fuse_context_i
*c
= fuse_get_context_internal();
2749 memset(c
, 0, sizeof(*c
));
2752 for (i
= 0; i
< f
->id_table_size
; i
++) {
2755 for (node
= f
->id_table
[i
]; node
!= NULL
; node
= node
->id_next
) {
2756 if (node
->is_hidden
) {
2757 char *path
= get_path(f
, node
->nodeid
);
2759 fuse_fs_unlink(f
->fs
, path
);
2766 for (i
= 0; i
< f
->id_table_size
; i
++) {
2770 for (node
= f
->id_table
[i
]; node
!= NULL
; node
= next
) {
2771 next
= node
->id_next
;
2776 free(f
->name_table
);
2777 pthread_mutex_destroy(&f
->lock
);
2778 pthread_rwlock_destroy(&f
->tree_lock
);
2779 fuse_session_destroy(f
->se
);
2781 fuse_delete_context_key();